static void relaxPoints(FillContext& context, Size iterations) { auto chunkSize = context.chunkSize; auto cx = context.chunkX; auto cy = context.chunkY; auto& points = context.points; for(int i = 0; i < iterations; ++i) { Diagram diagram; construct_voronoi(points.begin(), points.end(), &diagram); for(const DiagramCell& it : diagram.cells()) { auto edge = it.incident_edge(); CoordinateType x = 0; CoordinateType y = 0; int count = 0; do { edge = edge->next(); auto edgePoints = getEdgePoints(*edge, points); x += edgePoints.first.x() - cx * chunkSize; y += edgePoints.first.y() - cy * chunkSize; ++count; } while (edge != it.incident_edge()); points[it.source_index()].x(x / count + cx * chunkSize); points[it.source_index()].y(y / count + cy * chunkSize); } } }
void VoronoiDiagram::updateEdges(const Diagram& diagram) { //LOG << "Boost voronoi has " << diagram.cells().size() << " cells\n"; for (auto& cell : diagram.cells()) { assert(cell.contains_point()); // Cell should be created by point seed const voronoi_diagram<Real>::edge_type* edge = cell.incident_edge(); assert(edge->is_linear()); // For points all edges should be linear assert(edge != nullptr); cells.emplace_back(seeds.at(cell.source_index()), diagramLiftOnZ); auto& lastCell = cells.at(cells.size() - 1); do { if (edge->is_primary()) { auto voronoiEdge = ToVoronoiEdge(*edge); try { voronoiEdge = getRayBoundedToArena(voronoiEdge); lastCell.addEdge(move(voronoiEdge)); } catch(EdgeNotInArea& e) { // Do not add this edge } } edge = edge->next(); } while (edge != cell.incident_edge()); } }