// Boost.Polygon library voronoi_basic_tutorial.cpp file // Copyright Andrii Sydorchuk 2010-2012. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include using namespace boost::polygon; #include "voronoi_visual_utils.hpp" struct Point { int a; int b; Point (int x, int y) : a(x), b(y) {} }; struct Segment { Point p0; Point p1; Segment (int x1, int y1, int x2, int y2) : p0(x1, y1), p1(x2, y2) {} }; namespace boost { namespace polygon { template <> struct geometry_concept { typedef point_concept type; }; template <> struct point_traits { typedef int coordinate_type; static inline coordinate_type get(const Point& point, orientation_2d orient) { return (orient == HORIZONTAL) ? point.a : point.b; } }; template <> struct geometry_concept { typedef segment_concept type; }; template <> struct segment_traits { typedef int coordinate_type; typedef Point point_type; static inline point_type get(const Segment& segment, direction_1d dir) { return dir.to_int() ? segment.p1 : segment.p0; } }; } // polygon } // boost // Traversing Voronoi edges using edge iterator. int iterate_primary_edges1(const voronoi_diagram& vd) { int result = 0; for (voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) { if (it->is_primary()) ++result; } return result; } // Traversing Voronoi edges using cell iterator. int iterate_primary_edges2(const voronoi_diagram &vd) { int result = 0; for (voronoi_diagram::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it) { const voronoi_diagram::cell_type& cell = *it; const voronoi_diagram::edge_type* edge = cell.incident_edge(); // This is convenient way to iterate edges around Voronoi cell. do { if (edge->is_primary()) ++result; edge = edge->next(); } while (edge != cell.incident_edge()); } return result; } // Traversing Voronoi edges using vertex iterator. // As opposite to the above two functions this one will not iterate through edges // without finite endpoints and will iterate only once through edges with single // finite endpoint. int iterate_primary_edges3(const voronoi_diagram &vd) { int result = 0; for (voronoi_diagram::const_vertex_iterator it = vd.vertices().begin(); it != vd.vertices().end(); ++it) { const voronoi_diagram::vertex_type& vertex = *it; const voronoi_diagram::edge_type* edge = vertex.incident_edge(); // This is convenient way to iterate edges around Voronoi vertex. do { if (edge->is_primary()) ++result; edge = edge->rot_next(); } while (edge != vertex.incident_edge()); } return result; } int main() { // Preparing Input Geometries. std::vector points; points.push_back(Point(0, 0)); points.push_back(Point(1, 6)); std::vector segments; segments.push_back(Segment(-4, 5, 5, -1)); segments.push_back(Segment(3, -11, 13, -1)); // Construction of the Voronoi Diagram. voronoi_diagram vd; construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &vd); // Traversing Voronoi Graph. { printf("Traversing Voronoi graph.\n"); printf("Number of visited primary edges using edge iterator: %d\n", iterate_primary_edges1(vd)); printf("Number of visited primary edges using cell iterator: %d\n", iterate_primary_edges2(vd)); printf("Number of visited primary edges using vertex iterator: %d\n", iterate_primary_edges3(vd)); printf("\n"); } // Using color member of the Voronoi primitives to store the average number of edges // around each cell (including secondary edges). { printf("Number of edges (including secondary edges) around the Voronoi cells:\n"); for (voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) { std::size_t cnt = it->cell()->color(); it->cell()->color(cnt + 1); } for (voronoi_diagram::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it) { printf("%d ", it->color()); } printf("\n"); printf("\n"); } return 0; }