|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80400 - in trunk: boost/polygon boost/polygon/detail libs/polygon/example libs/polygon/test
From: sydorchuk.andriy_at_[hidden]
Date: 2012-09-04 17:26:12
Author: asydorchuk
Date: 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
New Revision: 80400
URL: http://svn.boost.org/trac/boost/changeset/80400
Log:
Polygon: adding voronoi_events to the public part of the library.
Added:
trunk/boost/polygon/voronoi_events.hpp (contents, props changed)
trunk/libs/polygon/test/voronoi_events_test.cpp (contents, props changed)
Text files modified:
trunk/boost/polygon/detail/voronoi_structures.hpp | 314 ----------------------------------------
trunk/boost/polygon/voronoi_builder.hpp | 22 +-
trunk/boost/polygon/voronoi_diagram.hpp | 33 ++--
trunk/libs/polygon/example/voronoi_visualizer.cpp | 4
trunk/libs/polygon/test/Jamfile.v2 | 1
trunk/libs/polygon/test/voronoi_predicates_test.cpp | 3
trunk/libs/polygon/test/voronoi_structures_test.cpp | 83 ----------
7 files changed, 32 insertions(+), 428 deletions(-)
Modified: trunk/boost/polygon/detail/voronoi_structures.hpp
==============================================================================
--- trunk/boost/polygon/detail/voronoi_structures.hpp (original)
+++ trunk/boost/polygon/detail/voronoi_structures.hpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -17,320 +17,6 @@
namespace boost {
namespace polygon {
namespace detail {
-
-// Cartesian 2D point data structure.
-template <typename T>
-class point_2d {
-public:
- typedef T coordinate_type;
-
- point_2d() {}
-
- point_2d(coordinate_type x, coordinate_type y) :
- x_(x),
- y_(y) {}
-
- bool operator==(const point_2d& that) const {
- return (this->x_ == that.x()) && (this->y_ == that.y());
- }
-
- bool operator!=(const point_2d& that) const {
- return (this->x_ != that.x()) || (this->y_ != that.y());
- }
-
- coordinate_type x() const {
- return x_;
- }
-
- coordinate_type y() const {
- return y_;
- }
-
- point_2d& x(coordinate_type x) {
- x_ = x;
- return *this;
- }
-
- point_2d& y(coordinate_type y) {
- y_ = y;
- return *this;
- }
-
-private:
- coordinate_type x_;
- coordinate_type y_;
-};
-
-// Represents topology type of the voronoi site.
-enum GeometryCategory {
- GEOMETRY_CATEGORY_POINT = 0x0,
- GEOMETRY_CATEGORY_SEGMENT = 0x1
-};
-
-// Represents category of the input source that forms Voronoi cell.
-enum SourceCategory {
- // Point subtypes.
- SOURCE_CATEGORY_SINGLE_POINT = 0x0,
- SOURCE_CATEGORY_SEGMENT_START_POINT = 0x1,
- SOURCE_CATEGORY_SEGMENT_END_POINT = 0x2,
-
- // Segment subtypes.
- SOURCE_CATEGORY_INITIAL_SEGMENT = 0x8,
- SOURCE_CATEGORY_REVERSE_SEGMENT = 0x9,
-
- SOURCE_CATEGORY_GEOMETRY_SHIFT = 0x3,
- SOURCE_CATEGORY_BITMASK = 0x1F
-};
-
-bool belongs(
- const SourceCategory& source_category,
- const GeometryCategory& geometry_category) {
- return (static_cast<std::size_t>(source_category) >> SOURCE_CATEGORY_GEOMETRY_SHIFT) ==
- static_cast<std::size_t>(geometry_category);
-}
-
-// Site event type.
-// Occurs when the sweepline sweeps over one of the initial sites:
-// 1) point site
-// 2) start-point of the segment site
-// 3) endpoint of the segment site
-// Implicit segment direction is defined: the start-point of
-// the segment compares less than its endpoint.
-// Each input segment is divided onto two site events:
-// 1) One going from the start-point to the endpoint
-// (is_inverse() = false)
-// 2) Another going from the endpoint to the start-point
-// (is_inverse() = true)
-// In beach line data structure segment sites of the first
-// type precede sites of the second type for the same segment.
-// Members:
-// point0_ - point site or segment's start-point
-// point1_ - segment's endpoint if site is a segment
-// sorted_index_ - the last bit encodes information if the site is inverse;
-// the other bits encode site event index among the sorted site events
-// initial_index_ - site index among the initial input set
-// Note: for all sites is_inverse_ flag is equal to false by default.
-template <typename T>
-class site_event {
-public:
- typedef T coordinate_type;
- typedef point_2d<T> point_type;
-
- site_event() :
- point0_(0, 0),
- point1_(0, 0),
- sorted_index_(0),
- flags_(0) {}
-
- site_event(coordinate_type x, coordinate_type y) :
- point0_(x, y),
- point1_(x, y),
- sorted_index_(0),
- flags_(0) {}
-
- site_event(const point_type& point) :
- point0_(point),
- point1_(point),
- sorted_index_(0),
- flags_(0) {}
-
- site_event(coordinate_type x1, coordinate_type y1,
- coordinate_type x2, coordinate_type y2):
- point0_(x1, y1),
- point1_(x2, y2),
- sorted_index_(0),
- flags_(0) {}
-
- site_event(const point_type& point1, const point_type& point2) :
- point0_(point1),
- point1_(point2),
- sorted_index_(0),
- flags_(0) {}
-
- bool operator==(const site_event& that) const {
- return (this->point0_ == that.point0_) &&
- (this->point1_ == that.point1_);
- }
-
- bool operator!=(const site_event& that) const {
- return (this->point0_ != that.point0_) ||
- (this->point1_ != that.point1_);
- }
-
- coordinate_type x(bool oriented = false) const {
- return x0(oriented);
- }
-
- coordinate_type y(bool oriented = false) const {
- return y0(oriented);
- }
-
- coordinate_type x0(bool oriented = false) const {
- if (!oriented)
- return point0_.x();
- return is_inverse() ? point1_.x() : point0_.x();
- }
-
- coordinate_type y0(bool oriented = false) const {
- if (!oriented)
- return point0_.y();
- return is_inverse() ? point1_.y() : point0_.y();
- }
-
- coordinate_type x1(bool oriented = false) const {
- if (!oriented)
- return point1_.x();
- return is_inverse() ? point0_.x() : point1_.x();
- }
-
- coordinate_type y1(bool oriented = false) const {
- if (!oriented)
- return point1_.y();
- return is_inverse() ? point0_.y() : point1_.y();
- }
-
- const point_type& point0(bool oriented = false) const {
- if (!oriented)
- return point0_;
- return is_inverse() ? point1_ : point0_;
- }
-
- const point_type& point1(bool oriented = false) const {
- if (!oriented)
- return point1_;
- return is_inverse() ? point0_ : point1_;
- }
-
- std::size_t sorted_index() const {
- return sorted_index_;
- }
-
- site_event& sorted_index(std::size_t index) {
- sorted_index_ = index;
- return *this;
- }
-
- std::size_t initial_index() const {
- return initial_index_;
- }
-
- site_event& initial_index(std::size_t index) {
- initial_index_ = index;
- return *this;
- }
-
- bool is_inverse() const {
- return flags_ & IS_INVERSE;
- }
-
- site_event& inverse() {
- flags_ ^= IS_INVERSE;
- return *this;
- }
-
- SourceCategory source_category() const {
- return static_cast<SourceCategory>(flags_ & SOURCE_CATEGORY_BITMASK);
- }
-
- site_event& source_category(SourceCategory source_category) {
- flags_ |= source_category;
- return *this;
- }
-
- bool is_point() const {
- return (point0_.x() == point1_.x()) && (point0_.y() == point1_.y());
- }
-
- bool is_segment() const {
- return (point0_.x() != point1_.x()) || (point0_.y() != point1_.y());
- }
-
-private:
- enum Bits {
- IS_INVERSE = 0x20 // 32
- };
-
- point_type point0_;
- point_type point1_;
- std::size_t sorted_index_;
- std::size_t initial_index_;
- std::size_t flags_;
-};
-
-// Circle event type.
-// Occurs when the sweepline sweeps over the rightmost point of the Voronoi
-// circle (with the center at the intersection point of the bisectors).
-// Circle event is made of the two consecutive nodes in the beach line data
-// structure. In case another node was inserted during algorithm execution
-// between the given two nodes circle event becomes inactive.
-// Variables:
-// center_x_ - center x-coordinate;
-// center_y_ - center y-coordinate;
-// lower_x_ - leftmost x-coordinate;
-// is_active_ - states whether circle event is still active.
-// NOTE: lower_y coordinate is always equal to center_y.
-template <typename T>
-class circle_event {
-public:
- typedef T coordinate_type;
-
- circle_event() : is_active_(true) {}
-
- circle_event(coordinate_type c_x,
- coordinate_type c_y,
- coordinate_type lower_x) :
- center_x_(c_x),
- center_y_(c_y),
- lower_x_(lower_x),
- is_active_(true) {}
-
- coordinate_type x() const {
- return center_x_;
- }
-
- circle_event& x(coordinate_type center_x) {
- center_x_ = center_x;
- return *this;
- }
-
- coordinate_type y() const {
- return center_y_;
- }
-
- circle_event& y(coordinate_type center_y) {
- center_y_ = center_y;
- return *this;
- }
-
- coordinate_type lower_x() const {
- return lower_x_;
- }
-
- circle_event& lower_x(coordinate_type lower_x) {
- lower_x_ = lower_x;
- return *this;
- }
-
- coordinate_type lower_y() const {
- return center_y_;
- }
-
- bool is_active() const {
- return is_active_;
- }
-
- circle_event& deactivate() {
- is_active_ = false;
- return *this;
- }
-
-private:
- coordinate_type center_x_;
- coordinate_type center_y_;
- coordinate_type lower_x_;
- bool is_active_;
-};
-
// Event queue data structure, holds circle events.
// During algorithm run, some of the circle events disappear (become
// inactive). Priority queue data structure doesn't support
Modified: trunk/boost/polygon/voronoi_builder.hpp
==============================================================================
--- trunk/boost/polygon/voronoi_builder.hpp (original)
+++ trunk/boost/polygon/voronoi_builder.hpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -18,6 +18,8 @@
#include "detail/voronoi_predicates.hpp"
#include "detail/voronoi_structures.hpp"
+#include "voronoi_events.hpp"
+
namespace boost {
namespace polygon {
// GENERAL INFO:
@@ -51,7 +53,7 @@
std::size_t insert_point(const int_type& x, const int_type& y) {
site_events_.push_back(site_event_type(x, y));
site_events_.back().initial_index(index_);
- site_events_.back().source_category(detail::SOURCE_CATEGORY_SINGLE_POINT);
+ site_events_.back().source_category(SOURCE_CATEGORY_SINGLE_POINT);
return index_++;
}
@@ -66,25 +68,21 @@
point_type p1(x1, y1);
site_events_.push_back(site_event_type(p1));
site_events_.back().initial_index(index_);
- site_events_.back().source_category(
- detail::SOURCE_CATEGORY_SEGMENT_START_POINT);
+ site_events_.back().source_category(SOURCE_CATEGORY_SEGMENT_START_POINT);
// Set up end point site.
point_type p2(x2, y2);
site_events_.push_back(site_event_type(p2));
site_events_.back().initial_index(index_);
- site_events_.back().source_category(
- detail::SOURCE_CATEGORY_SEGMENT_END_POINT);
+ site_events_.back().source_category(SOURCE_CATEGORY_SEGMENT_END_POINT);
// Set up segment site.
if (point_comparison_(p1, p2)) {
site_events_.push_back(site_event_type(p1, p2));
- site_events_.back().source_category(
- detail::SOURCE_CATEGORY_INITIAL_SEGMENT);
+ site_events_.back().source_category(SOURCE_CATEGORY_INITIAL_SEGMENT);
} else {
site_events_.push_back(site_event_type(p2, p1));
- site_events_.back().source_category(
- detail::SOURCE_CATEGORY_REVERSE_SEGMENT);
+ site_events_.back().source_category(SOURCE_CATEGORY_REVERSE_SEGMENT);
}
site_events_.back().initial_index(index_);
return index_++;
@@ -131,11 +129,11 @@
}
private:
- typedef detail::point_2d<int_type> point_type;
- typedef detail::site_event<int_type> site_event_type;
+ typedef point_2d<int_type> point_type;
+ typedef site_event<int_type> site_event_type;
typedef typename std::vector<site_event_type>::const_iterator
site_event_iterator_type;
- typedef detail::circle_event<fpt_type> circle_event_type;
+ typedef circle_event<fpt_type> circle_event_type;
typedef typename VP::template point_comparison_predicate<point_type>
point_comparison_predicate;
typedef typename VP::
Modified: trunk/boost/polygon/voronoi_diagram.hpp
==============================================================================
--- trunk/boost/polygon/voronoi_diagram.hpp (original)
+++ trunk/boost/polygon/voronoi_diagram.hpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -13,7 +13,7 @@
#include <vector>
#include "detail/voronoi_ctypes.hpp"
-#include "detail/voronoi_structures.hpp"
+#include "voronoi_events.hpp"
namespace boost {
namespace polygon {
@@ -35,7 +35,7 @@
typedef std::size_t color_type;
typedef voronoi_edge<coordinate_type> voronoi_edge_type;
typedef std::size_t source_index_type;
- typedef detail::SourceCategory source_category_type;
+ typedef SourceCategory source_category_type;
voronoi_cell(const source_index_type& source_index,
const source_category_type& source_category,
@@ -47,13 +47,13 @@
// Returns true if the cell contains point site, false else.
bool contains_point() const {
source_category_type source_category = this->source_category();
- return detail::belongs(source_category, detail::GEOMETRY_CATEGORY_POINT);
+ return belongs(source_category, GEOMETRY_CATEGORY_POINT);
}
// Returns true if the cell contains segment site, false else.
bool contains_segment() const {
source_category_type source_category = this->source_category();
- return detail::belongs(source_category, detail::GEOMETRY_CATEGORY_SEGMENT);
+ return belongs(source_category, GEOMETRY_CATEGORY_SEGMENT);
}
source_index_type source_index() const {
@@ -61,8 +61,7 @@
}
source_category_type source_category() const {
- return static_cast<source_category_type>(
- color_ & detail::SOURCE_CATEGORY_BITMASK);
+ return static_cast<source_category_type>(color_ & SOURCE_CATEGORY_BITMASK);
}
// Degenerate cells don't have any incident edges.
@@ -222,25 +221,25 @@
// Returns true if the edge is linear (segment, ray, line).
// Returns false if the edge is curved (parabolic arc).
bool is_linear() const {
- return color_ & BIT_IS_LINEAR;
+ return (color_ & BIT_IS_LINEAR) ? true : false;
}
// Returns true if the edge is curved (parabolic arc).
// Returns false if the edge is linear (segment, ray, line).
bool is_curved() const {
- return !(color_ & BIT_IS_LINEAR);
+ return (color_ & BIT_IS_LINEAR) ? false : true;
}
// Returns false if edge goes through the endpoint of the segment.
// Returns true else.
bool is_primary() const {
- return color_ & BIT_IS_PRIMARY;
+ return (color_ & BIT_IS_PRIMARY) ? true : false;
}
// Returns true if edge goes through the endpoint of the segment.
// Returns false else.
bool is_secondary() const {
- return !(color_ & BIT_IS_PRIMARY);
+ return (color_ & BIT_IS_PRIMARY) ? false : true;
}
color_type color() const { return color_ >> BITS_SHIFT; }
@@ -351,8 +350,8 @@
edges_.reserve((num_sites << 2) + (num_sites << 1));
}
-template <typename SEvent>
- void _process_single_site(const SEvent& site) {
+ template <typename CT>
+ void _process_single_site(const site_event<CT>& site) {
cells_.push_back(cell_type(
site.initial_index(), site.source_category(), NULL));
}
@@ -360,9 +359,9 @@
// Insert a new half-edge into the output data structure.
// Takes as input left and right sites that form a new bisector.
// Returns a pair of pointers to a new half-edges.
- template <typename SEvent>
+ template <typename CT>
std::pair<void*, void*> _insert_new_edge(
- const SEvent& site1, const SEvent& site2) {
+ const site_event<CT>& site1, const site_event<CT>& site2) {
// Get sites' indexes.
int site_index1 = site1.sorted_index();
int site_index2 = site2.sorted_index();
@@ -407,10 +406,10 @@
// that corresponds to the intersection point of the two old half-edges,
// pointers to those half-edges. Half-edges' direction goes out of the
// new Voronoi vertex point. Returns a pair of pointers to a new half-edges.
- template <typename SEvent, typename CEvent>
+ template <typename CT1, typename CT2>
std::pair<void*, void*> _insert_new_edge(
- const SEvent& site1, const SEvent& site3, const CEvent& circle,
- void* data12, void* data23) {
+ const site_event<CT1>& site1, const site_event<CT1>& site3,
+ const circle_event<CT2>& circle, void* data12, void* data23) {
edge_type* edge12 = static_cast<edge_type*>(data12);
edge_type* edge23 = static_cast<edge_type*>(data23);
Added: trunk/boost/polygon/voronoi_events.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/voronoi_events.hpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -0,0 +1,332 @@
+// Boost.Polygon library voronoi_events.hpp header 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.
+
+#ifndef BOOST_POLYGON_VORONOI_EVENTS
+#define BOOST_POLYGON_VORONOI_EVENTS
+
+namespace boost {
+namespace polygon {
+// Warning: only the below two enums and routine should be used by users.
+// Represents topology type of the voronoi site.
+enum GeometryCategory {
+ GEOMETRY_CATEGORY_POINT = 0x0,
+ GEOMETRY_CATEGORY_SEGMENT = 0x1
+};
+
+// Represents category of the input source that forms Voronoi cell.
+enum SourceCategory {
+ // Point subtypes.
+ SOURCE_CATEGORY_SINGLE_POINT = 0x0,
+ SOURCE_CATEGORY_SEGMENT_START_POINT = 0x1,
+ SOURCE_CATEGORY_SEGMENT_END_POINT = 0x2,
+
+ // Segment subtypes.
+ SOURCE_CATEGORY_INITIAL_SEGMENT = 0x8,
+ SOURCE_CATEGORY_REVERSE_SEGMENT = 0x9,
+
+ SOURCE_CATEGORY_GEOMETRY_SHIFT = 0x3,
+ SOURCE_CATEGORY_BITMASK = 0x1F
+};
+
+bool belongs(
+ const SourceCategory& source_category,
+ const GeometryCategory& geometry_category) {
+ return (static_cast<std::size_t>(source_category) >>
+ SOURCE_CATEGORY_GEOMETRY_SHIFT) ==
+ static_cast<std::size_t>(geometry_category);
+}
+
+// Cartesian 2D point data structure.
+template <typename T>
+class point_2d {
+public:
+ typedef T coordinate_type;
+
+ point_2d() {}
+
+ point_2d(coordinate_type x, coordinate_type y) :
+ x_(x),
+ y_(y) {}
+
+ bool operator==(const point_2d& that) const {
+ return (this->x_ == that.x()) && (this->y_ == that.y());
+ }
+
+ bool operator!=(const point_2d& that) const {
+ return (this->x_ != that.x()) || (this->y_ != that.y());
+ }
+
+ coordinate_type x() const {
+ return x_;
+ }
+
+ coordinate_type y() const {
+ return y_;
+ }
+
+ point_2d& x(coordinate_type x) {
+ x_ = x;
+ return *this;
+ }
+
+ point_2d& y(coordinate_type y) {
+ y_ = y;
+ return *this;
+ }
+
+private:
+ coordinate_type x_;
+ coordinate_type y_;
+};
+
+// Site event type.
+// Occurs when the sweepline sweeps over one of the initial sites:
+// 1) point site
+// 2) start-point of the segment site
+// 3) endpoint of the segment site
+// Implicit segment direction is defined: the start-point of
+// the segment compares less than its endpoint.
+// Each input segment is divided onto two site events:
+// 1) One going from the start-point to the endpoint
+// (is_inverse() = false)
+// 2) Another going from the endpoint to the start-point
+// (is_inverse() = true)
+// In beach line data structure segment sites of the first
+// type precede sites of the second type for the same segment.
+// Members:
+// point0_ - point site or segment's start-point
+// point1_ - segment's endpoint if site is a segment
+// sorted_index_ - the last bit encodes information if the site is inverse;
+// the other bits encode site event index among the sorted site events
+// initial_index_ - site index among the initial input set
+// Note: for all sites is_inverse_ flag is equal to false by default.
+template <typename T>
+class site_event {
+public:
+ typedef T coordinate_type;
+ typedef point_2d<T> point_type;
+
+ site_event() :
+ point0_(0, 0),
+ point1_(0, 0),
+ sorted_index_(0),
+ flags_(0) {}
+
+ site_event(coordinate_type x, coordinate_type y) :
+ point0_(x, y),
+ point1_(x, y),
+ sorted_index_(0),
+ flags_(0) {}
+
+ site_event(const point_type& point) :
+ point0_(point),
+ point1_(point),
+ sorted_index_(0),
+ flags_(0) {}
+
+ site_event(coordinate_type x1, coordinate_type y1,
+ coordinate_type x2, coordinate_type y2):
+ point0_(x1, y1),
+ point1_(x2, y2),
+ sorted_index_(0),
+ flags_(0) {}
+
+ site_event(const point_type& point1, const point_type& point2) :
+ point0_(point1),
+ point1_(point2),
+ sorted_index_(0),
+ flags_(0) {}
+
+ bool operator==(const site_event& that) const {
+ return (this->point0_ == that.point0_) &&
+ (this->point1_ == that.point1_);
+ }
+
+ bool operator!=(const site_event& that) const {
+ return (this->point0_ != that.point0_) ||
+ (this->point1_ != that.point1_);
+ }
+
+ coordinate_type x(bool oriented = false) const {
+ return x0(oriented);
+ }
+
+ coordinate_type y(bool oriented = false) const {
+ return y0(oriented);
+ }
+
+ coordinate_type x0(bool oriented = false) const {
+ if (!oriented)
+ return point0_.x();
+ return is_inverse() ? point1_.x() : point0_.x();
+ }
+
+ coordinate_type y0(bool oriented = false) const {
+ if (!oriented)
+ return point0_.y();
+ return is_inverse() ? point1_.y() : point0_.y();
+ }
+
+ coordinate_type x1(bool oriented = false) const {
+ if (!oriented)
+ return point1_.x();
+ return is_inverse() ? point0_.x() : point1_.x();
+ }
+
+ coordinate_type y1(bool oriented = false) const {
+ if (!oriented)
+ return point1_.y();
+ return is_inverse() ? point0_.y() : point1_.y();
+ }
+
+ const point_type& point0(bool oriented = false) const {
+ if (!oriented)
+ return point0_;
+ return is_inverse() ? point1_ : point0_;
+ }
+
+ const point_type& point1(bool oriented = false) const {
+ if (!oriented)
+ return point1_;
+ return is_inverse() ? point0_ : point1_;
+ }
+
+ std::size_t sorted_index() const {
+ return sorted_index_;
+ }
+
+ site_event& sorted_index(std::size_t index) {
+ sorted_index_ = index;
+ return *this;
+ }
+
+ std::size_t initial_index() const {
+ return initial_index_;
+ }
+
+ site_event& initial_index(std::size_t index) {
+ initial_index_ = index;
+ return *this;
+ }
+
+ bool is_inverse() const {
+ return (flags_ & IS_INVERSE) ? true : false;
+ }
+
+ site_event& inverse() {
+ flags_ ^= IS_INVERSE;
+ return *this;
+ }
+
+ SourceCategory source_category() const {
+ return static_cast<SourceCategory>(flags_ & SOURCE_CATEGORY_BITMASK);
+ }
+
+ site_event& source_category(SourceCategory source_category) {
+ flags_ |= source_category;
+ return *this;
+ }
+
+ bool is_point() const {
+ return (point0_.x() == point1_.x()) && (point0_.y() == point1_.y());
+ }
+
+ bool is_segment() const {
+ return (point0_.x() != point1_.x()) || (point0_.y() != point1_.y());
+ }
+
+private:
+ enum Bits {
+ IS_INVERSE = 0x20 // 32
+ };
+
+ point_type point0_;
+ point_type point1_;
+ std::size_t sorted_index_;
+ std::size_t initial_index_;
+ std::size_t flags_;
+};
+
+// Circle event type.
+// Occurs when the sweepline sweeps over the rightmost point of the Voronoi
+// circle (with the center at the intersection point of the bisectors).
+// Circle event is made of the two consecutive nodes in the beach line data
+// structure. In case another node was inserted during algorithm execution
+// between the given two nodes circle event becomes inactive.
+// Variables:
+// center_x_ - center x-coordinate;
+// center_y_ - center y-coordinate;
+// lower_x_ - leftmost x-coordinate;
+// is_active_ - states whether circle event is still active.
+// NOTE: lower_y coordinate is always equal to center_y.
+template <typename T>
+class circle_event {
+public:
+ typedef T coordinate_type;
+
+ circle_event() : is_active_(true) {}
+
+ circle_event(coordinate_type c_x,
+ coordinate_type c_y,
+ coordinate_type lower_x) :
+ center_x_(c_x),
+ center_y_(c_y),
+ lower_x_(lower_x),
+ is_active_(true) {}
+
+ coordinate_type x() const {
+ return center_x_;
+ }
+
+ circle_event& x(coordinate_type center_x) {
+ center_x_ = center_x;
+ return *this;
+ }
+
+ coordinate_type y() const {
+ return center_y_;
+ }
+
+ circle_event& y(coordinate_type center_y) {
+ center_y_ = center_y;
+ return *this;
+ }
+
+ coordinate_type lower_x() const {
+ return lower_x_;
+ }
+
+ circle_event& lower_x(coordinate_type lower_x) {
+ lower_x_ = lower_x;
+ return *this;
+ }
+
+ coordinate_type lower_y() const {
+ return center_y_;
+ }
+
+ bool is_active() const {
+ return is_active_;
+ }
+
+ circle_event& deactivate() {
+ is_active_ = false;
+ return *this;
+ }
+
+private:
+ coordinate_type center_x_;
+ coordinate_type center_y_;
+ coordinate_type lower_x_;
+ bool is_active_;
+};
+} // polygon
+} // boost
+
+#endif // BOOST_POLYGON_VORONOI_EVENTS
Modified: trunk/libs/polygon/example/voronoi_visualizer.cpp
==============================================================================
--- trunk/libs/polygon/example/voronoi_visualizer.cpp (original)
+++ trunk/libs/polygon/example/voronoi_visualizer.cpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -349,11 +349,11 @@
point_type retrieve_point(const cell_type& cell) {
source_index_type index = cell.source_index();
source_category_type category = cell.source_category();
- if (category == detail::SOURCE_CATEGORY_SINGLE_POINT) {
+ if (category == SOURCE_CATEGORY_SINGLE_POINT) {
return point_data_[index];
}
index -= point_data_.size();
- if (category == detail::SOURCE_CATEGORY_SEGMENT_START_POINT) {
+ if (category == SOURCE_CATEGORY_SEGMENT_START_POINT) {
return low(segment_data_[index]);
} else {
return high(segment_data_[index]);
Modified: trunk/libs/polygon/test/Jamfile.v2
==============================================================================
--- trunk/libs/polygon/test/Jamfile.v2 (original)
+++ trunk/libs/polygon/test/Jamfile.v2 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -26,6 +26,7 @@
:
[ run voronoi_builder_test.cpp ]
[ run voronoi_ctypes_test.cpp ]
+ [ run voronoi_events_test.cpp ]
[ run voronoi_predicates_test.cpp ]
[ run voronoi_robust_fpt_test.cpp ]
[ run voronoi_structures_test.cpp ]
Added: trunk/libs/polygon/test/voronoi_events_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_events_test.cpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -0,0 +1,98 @@
+// Boost.Polygon library voronoi_events_test.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.
+
+#define BOOST_TEST_MODULE voronoi_events_test
+
+#include <boost/test/test_case_template.hpp>
+#include <boost/polygon/voronoi_events.hpp>
+using namespace boost::polygon;
+
+typedef point_2d<int> point_type;
+typedef site_event<int> site_type;
+typedef circle_event<int> circle_type;
+
+BOOST_AUTO_TEST_CASE(point_2d_test1) {
+ point_type p(1, 2);
+ BOOST_CHECK_EQUAL(p.x(), 1);
+ BOOST_CHECK_EQUAL(p.y(), 2);
+ p.x(3);
+ BOOST_CHECK_EQUAL(p.x(), 3);
+ p.y(4);
+ BOOST_CHECK_EQUAL(p.y(), 4);
+}
+
+BOOST_AUTO_TEST_CASE(source_category_test1) {
+ BOOST_CHECK(belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_CHECK(belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_CHECK(belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_CHECK(!belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_POINT));
+ BOOST_CHECK(!belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_POINT));
+
+ BOOST_CHECK(!belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_CHECK(!belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_CHECK(!belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_CHECK(belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_CHECK(belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
+}
+
+BOOST_AUTO_TEST_CASE(site_event_test1) {
+ site_type s(1, 2);
+ s.sorted_index(1);
+ s.initial_index(2);
+ s.source_category(SOURCE_CATEGORY_SEGMENT_START_POINT);
+ BOOST_CHECK(s.x0() == 1 && s.x1() == 1);
+ BOOST_CHECK(s.y0() == 2 && s.y1() == 2);
+ BOOST_CHECK(s.is_point());
+ BOOST_CHECK(!s.is_segment());
+ BOOST_CHECK(!s.is_inverse());
+ BOOST_CHECK(s.sorted_index() == 1);
+ BOOST_CHECK(s.initial_index() == 2);
+ BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_SEGMENT_START_POINT);
+}
+
+BOOST_AUTO_TEST_CASE(site_event_test2) {
+ site_type s(1, 2, 3, 4);
+ s.sorted_index(1);
+ s.initial_index(2);
+ s.source_category(SOURCE_CATEGORY_INITIAL_SEGMENT);
+ BOOST_CHECK(s.x0(true) == 1 && s.x0() == 1);
+ BOOST_CHECK(s.y0(true) == 2 && s.y0() == 2);
+ BOOST_CHECK(s.x1(true) == 3 && s.x1() == 3);
+ BOOST_CHECK(s.y1(true) == 4 && s.y1() == 4);
+ BOOST_CHECK(!s.is_point());
+ BOOST_CHECK(s.is_segment());
+ BOOST_CHECK(!s.is_inverse());
+ BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_INITIAL_SEGMENT);
+
+ s.inverse();
+ BOOST_CHECK(s.x1(true) == 1 && s.x0() == 1);
+ BOOST_CHECK(s.y1(true) == 2 && s.y0() == 2);
+ BOOST_CHECK(s.x0(true) == 3 && s.x1() == 3);
+ BOOST_CHECK(s.y0(true) == 4 && s.y1() == 4);
+ BOOST_CHECK(s.is_inverse());
+ BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_INITIAL_SEGMENT);
+}
+
+BOOST_AUTO_TEST_CASE(circle_event_test) {
+ circle_type c(0, 1, 2);
+ BOOST_CHECK_EQUAL(c.x(), 0);
+ BOOST_CHECK_EQUAL(c.y(), 1);
+ BOOST_CHECK_EQUAL(c.lower_x(), 2);
+ BOOST_CHECK_EQUAL(c.lower_y(), 1);
+ BOOST_CHECK(c.is_active());
+ c.x(3);
+ c.y(4);
+ c.lower_x(5);
+ BOOST_CHECK_EQUAL(c.x(), 3);
+ BOOST_CHECK_EQUAL(c.y(), 4);
+ BOOST_CHECK_EQUAL(c.lower_x(), 5);
+ BOOST_CHECK_EQUAL(c.lower_y(), 4);
+ c.deactivate();
+ BOOST_CHECK(!c.is_active());
+}
Modified: trunk/libs/polygon/test/voronoi_predicates_test.cpp
==============================================================================
--- trunk/libs/polygon/test/voronoi_predicates_test.cpp (original)
+++ trunk/libs/polygon/test/voronoi_predicates_test.cpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -17,6 +17,9 @@
#include <boost/polygon/detail/voronoi_structures.hpp>
using namespace boost::polygon::detail;
+#include <boost/polygon/voronoi_events.hpp>
+using namespace boost::polygon;
+
ulp_comparison<double> ulp_cmp;
typedef voronoi_predicates< voronoi_ctype_traits<int> > VP;
Modified: trunk/libs/polygon/test/voronoi_structures_test.cpp
==============================================================================
--- trunk/libs/polygon/test/voronoi_structures_test.cpp (original)
+++ trunk/libs/polygon/test/voronoi_structures_test.cpp 2012-09-04 17:26:11 EDT (Tue, 04 Sep 2012)
@@ -13,93 +13,10 @@
#include <boost/polygon/detail/voronoi_structures.hpp>
using namespace boost::polygon::detail;
-typedef point_2d<int> point_type;
-typedef site_event<int> site_type;
-typedef circle_event<int> circle_type;
typedef ordered_queue<int, std::greater<int> > ordered_queue_type;
typedef beach_line_node_key<int> node_key_type;
typedef beach_line_node_data<int, int> node_data_type;
-BOOST_AUTO_TEST_CASE(point_2d_test1) {
- point_type p(1, 2);
- BOOST_CHECK_EQUAL(p.x(), 1);
- BOOST_CHECK_EQUAL(p.y(), 2);
- p.x(3);
- BOOST_CHECK_EQUAL(p.x(), 3);
- p.y(4);
- BOOST_CHECK_EQUAL(p.y(), 4);
-}
-
-BOOST_AUTO_TEST_CASE(source_category_test1) {
- BOOST_CHECK(belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_POINT));
- BOOST_CHECK(belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_POINT));
- BOOST_CHECK(belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_POINT));
- BOOST_CHECK(!belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_POINT));
- BOOST_CHECK(!belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_POINT));
-
- BOOST_CHECK(!belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_SEGMENT));
- BOOST_CHECK(!belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_SEGMENT));
- BOOST_CHECK(!belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_SEGMENT));
- BOOST_CHECK(belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
- BOOST_CHECK(belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
-}
-
-BOOST_AUTO_TEST_CASE(site_event_test1) {
- site_type s(1, 2);
- s.sorted_index(1);
- s.initial_index(2);
- s.source_category(SOURCE_CATEGORY_SEGMENT_START_POINT);
- BOOST_CHECK(s.x0() == 1 && s.x1() == 1);
- BOOST_CHECK(s.y0() == 2 && s.y1() == 2);
- BOOST_CHECK(s.is_point());
- BOOST_CHECK(!s.is_segment());
- BOOST_CHECK(!s.is_inverse());
- BOOST_CHECK(s.sorted_index() == 1);
- BOOST_CHECK(s.initial_index() == 2);
- BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_SEGMENT_START_POINT);
-}
-
-BOOST_AUTO_TEST_CASE(site_event_test2) {
- site_type s(1, 2, 3, 4);
- s.sorted_index(1);
- s.initial_index(2);
- s.source_category(SOURCE_CATEGORY_INITIAL_SEGMENT);
- BOOST_CHECK(s.x0(true) == 1 && s.x0() == 1);
- BOOST_CHECK(s.y0(true) == 2 && s.y0() == 2);
- BOOST_CHECK(s.x1(true) == 3 && s.x1() == 3);
- BOOST_CHECK(s.y1(true) == 4 && s.y1() == 4);
- BOOST_CHECK(!s.is_point());
- BOOST_CHECK(s.is_segment());
- BOOST_CHECK(!s.is_inverse());
- BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_INITIAL_SEGMENT);
-
- s.inverse();
- BOOST_CHECK(s.x1(true) == 1 && s.x0() == 1);
- BOOST_CHECK(s.y1(true) == 2 && s.y0() == 2);
- BOOST_CHECK(s.x0(true) == 3 && s.x1() == 3);
- BOOST_CHECK(s.y0(true) == 4 && s.y1() == 4);
- BOOST_CHECK(s.is_inverse());
- BOOST_CHECK(s.source_category() == SOURCE_CATEGORY_INITIAL_SEGMENT);
-}
-
-BOOST_AUTO_TEST_CASE(circle_event_test) {
- circle_type c(0, 1, 2);
- BOOST_CHECK_EQUAL(c.x(), 0);
- BOOST_CHECK_EQUAL(c.y(), 1);
- BOOST_CHECK_EQUAL(c.lower_x(), 2);
- BOOST_CHECK_EQUAL(c.lower_y(), 1);
- BOOST_CHECK(c.is_active());
- c.x(3);
- c.y(4);
- c.lower_x(5);
- BOOST_CHECK_EQUAL(c.x(), 3);
- BOOST_CHECK_EQUAL(c.y(), 4);
- BOOST_CHECK_EQUAL(c.lower_x(), 5);
- BOOST_CHECK_EQUAL(c.lower_y(), 4);
- c.deactivate();
- BOOST_CHECK(!c.is_active());
-}
-
BOOST_AUTO_TEST_CASE(ordered_queue_test) {
ordered_queue_type q;
BOOST_CHECK(q.empty());
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk