2
0
mirror of https://github.com/boostorg/polygon.git synced 2026-01-28 07:22:29 +00:00

Polygon: refactoring & redesigning voronoi diagram structure; code clean up.

[SVN r80360]
This commit is contained in:
Andrii Sydorchuk
2012-09-02 10:21:27 +00:00
parent 96d3867a35
commit 4d3a2c4801
7 changed files with 204 additions and 313 deletions

View File

@@ -11,9 +11,10 @@
#include <vector>
#include <boost/polygon/voronoi.hpp>
#include <boost/polygon/voronoi_utils.hpp>
using namespace boost::polygon;
#include "voronoi_visual_utils.hpp"
struct Point {
int a;
int b;
@@ -57,7 +58,7 @@ struct segment_traits<Segment> {
} // boost
// Traversing Voronoi edges using edge iterator.
int iterate_primary_edges1(const voronoi_diagram<double> &vd) {
int iterate_primary_edges1(const voronoi_diagram<double>& vd) {
int result = 0;
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin();
it != vd.edges().end(); ++it) {
@@ -72,8 +73,8 @@ int iterate_primary_edges2(const voronoi_diagram<double> &vd) {
int result = 0;
for (voronoi_diagram<double>::const_cell_iterator it = vd.cells().begin();
it != vd.cells().end(); ++it) {
const voronoi_diagram<double>::cell_type &cell = *it;
const voronoi_diagram<double>::edge_type *edge = cell.incident_edge();
const voronoi_diagram<double>::cell_type& cell = *it;
const voronoi_diagram<double>::edge_type* edge = cell.incident_edge();
// This is convenient way to iterate edges around Voronoi cell.
do {
if (edge->is_primary())
@@ -92,8 +93,8 @@ int iterate_primary_edges3(const voronoi_diagram<double> &vd) {
int result = 0;
for (voronoi_diagram<double>::const_vertex_iterator it = vd.vertices().begin();
it != vd.vertices().end(); ++it) {
const voronoi_diagram<double>::vertex_type &vertex = *it;
const voronoi_diagram<double>::edge_type *edge = vertex.incident_edge();
const voronoi_diagram<double>::vertex_type& vertex = *it;
const voronoi_diagram<double>::edge_type* edge = vertex.incident_edge();
// This is convenient way to iterate edges around Voronoi vertex.
do {
if (edge->is_primary())
@@ -104,35 +105,6 @@ int iterate_primary_edges3(const voronoi_diagram<double> &vd) {
return result;
}
// Prototype of a function that renders segments.
void draw_segment(double x1, double y1, double x2, double y2) {
printf("Rendering segment: ");
printf("%7.3f %7.3f %7.3f %7.3f\n", x1, y1, x2, y2);
}
void render_diagram(const voronoi_diagram<double> &vd,
const voronoi_utils<double>::brect_type &bbox) {
const std::size_t VISITED = 1;
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin();
it != vd.edges().end(); ++it) {
// We use color to mark visited edges.
it->color(VISITED);
// Don't render the same edge twice.
if (it->twin()->color()) continue;
voronoi_utils<double>::point_set_type polyline;
if (it->is_linear())
voronoi_utils<double>::clip(*it, bbox, polyline);
else
// Parabolic edges are always finite.
voronoi_utils<double>::discretize(*it, 1E-1, polyline);
// Note: discretized edges may also lie outside of the bbox.
// So user might do additional clipping before rendering each such edge.
for (std::size_t i = 1; i < polyline.size(); ++i)
draw_segment(polyline[i-1].x(), polyline[i-1].y(),
polyline[i].x(), polyline[i].y());
}
}
int main() {
// Preparing Input Geometries.
std::vector<Point> points;
@@ -155,46 +127,21 @@ int main() {
printf("\n");
}
// Using color member of the Voronoi primitives..
// 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<double>::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<double>::const_cell_iterator it = vd.cells().begin();
it != vd.cells().end(); ++it) {
const voronoi_diagram<double>::cell_type &cell = *it;
const voronoi_diagram<double>::edge_type *edge = cell.incident_edge();
std::size_t count = 0;
do {
++count;
edge = edge->next();
} while (edge != cell.incident_edge());
cell.color(count);
printf("%d ", it->color());
}
// Count the average number of edges.
double total = 0;
for (voronoi_diagram<double>::const_cell_iterator it = vd.cells().begin();
it != vd.cells().end(); ++it) {
total += it->color();
}
total /= vd.cells().size();
printf("The average number of edges per Voronoi cell is equal to: %3.1f\n", total);
printf("\n");
printf("\n");
}
// Rendering Voronoi diagram.
{
// Construct clipping bounding rectangle.
bounding_rectangle<double> bbox;
for (std::vector<Point>::iterator it = points.begin(); it != points.end(); ++it)
bbox.update(it->a, it->b);
for (std::vector<Segment>::iterator it = segments.begin(); it != segments.end(); ++it) {
bbox.update(it->p0.a, it->p0.b);
bbox.update(it->p1.a, it->p1.b);
}
// Add 10% offset to the bounding rectangle.
bbox = voronoi_utils<double>::scale(bbox, 1.1);
// Render Voronoi diagram.
render_diagram(vd, bbox);
}
return 0;
}