File indexing completed on 2025-12-16 10:04:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
0011 #define BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
0012
0013 #include <list>
0014 #include <queue>
0015 #include <vector>
0016
0017 #include "boost/polygon/voronoi_geometry_type.hpp"
0018
0019 namespace boost {
0020 namespace polygon {
0021 namespace detail {
0022
0023 template <typename T>
0024 class point_2d {
0025 public:
0026 typedef T coordinate_type;
0027
0028 point_2d() {}
0029
0030 point_2d(coordinate_type x, coordinate_type y) :
0031 x_(x),
0032 y_(y) {}
0033
0034 bool operator==(const point_2d& that) const {
0035 return (this->x_ == that.x()) && (this->y_ == that.y());
0036 }
0037
0038 bool operator!=(const point_2d& that) const {
0039 return (this->x_ != that.x()) || (this->y_ != that.y());
0040 }
0041
0042 coordinate_type x() const {
0043 return x_;
0044 }
0045
0046 coordinate_type y() const {
0047 return y_;
0048 }
0049
0050 point_2d& x(coordinate_type x) {
0051 x_ = x;
0052 return *this;
0053 }
0054
0055 point_2d& y(coordinate_type y) {
0056 y_ = y;
0057 return *this;
0058 }
0059
0060 private:
0061 coordinate_type x_;
0062 coordinate_type y_;
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 template <typename T>
0087 class site_event {
0088 public:
0089 typedef T coordinate_type;
0090 typedef point_2d<T> point_type;
0091
0092 site_event() :
0093 point0_(0, 0),
0094 point1_(0, 0),
0095 sorted_index_(0),
0096 flags_(0) {}
0097
0098 site_event(coordinate_type x, coordinate_type y) :
0099 point0_(x, y),
0100 point1_(x, y),
0101 sorted_index_(0),
0102 flags_(0) {}
0103
0104 explicit site_event(const point_type& point) :
0105 point0_(point),
0106 point1_(point),
0107 sorted_index_(0),
0108 flags_(0) {}
0109
0110 site_event(coordinate_type x1, coordinate_type y1,
0111 coordinate_type x2, coordinate_type y2):
0112 point0_(x1, y1),
0113 point1_(x2, y2),
0114 sorted_index_(0),
0115 flags_(0) {}
0116
0117 site_event(const point_type& point1, const point_type& point2) :
0118 point0_(point1),
0119 point1_(point2),
0120 sorted_index_(0),
0121 flags_(0) {}
0122
0123 bool operator==(const site_event& that) const {
0124 return (this->point0_ == that.point0_) &&
0125 (this->point1_ == that.point1_);
0126 }
0127
0128 bool operator!=(const site_event& that) const {
0129 return (this->point0_ != that.point0_) ||
0130 (this->point1_ != that.point1_);
0131 }
0132
0133 coordinate_type x() const {
0134 return point0_.x();
0135 }
0136
0137 coordinate_type y() const {
0138 return point0_.y();
0139 }
0140
0141 coordinate_type x0() const {
0142 return point0_.x();
0143 }
0144
0145 coordinate_type y0() const {
0146 return point0_.y();
0147 }
0148
0149 coordinate_type x1() const {
0150 return point1_.x();
0151 }
0152
0153 coordinate_type y1() const {
0154 return point1_.y();
0155 }
0156
0157 const point_type& point0() const {
0158 return point0_;
0159 }
0160
0161 const point_type& point1() const {
0162 return point1_;
0163 }
0164
0165 std::size_t sorted_index() const {
0166 return sorted_index_;
0167 }
0168
0169 site_event& sorted_index(std::size_t index) {
0170 sorted_index_ = index;
0171 return *this;
0172 }
0173
0174 std::size_t initial_index() const {
0175 return initial_index_;
0176 }
0177
0178 site_event& initial_index(std::size_t index) {
0179 initial_index_ = index;
0180 return *this;
0181 }
0182
0183 bool is_inverse() const {
0184 return (flags_ & IS_INVERSE) ? true : false;
0185 }
0186
0187 site_event& inverse() {
0188 std::swap(point0_, point1_);
0189 flags_ ^= IS_INVERSE;
0190 return *this;
0191 }
0192
0193 SourceCategory source_category() const {
0194 return static_cast<SourceCategory>(flags_ & SOURCE_CATEGORY_BITMASK);
0195 }
0196
0197 site_event& source_category(SourceCategory source_category) {
0198 flags_ |= source_category;
0199 return *this;
0200 }
0201
0202 bool is_point() const {
0203 return (point0_.x() == point1_.x()) && (point0_.y() == point1_.y());
0204 }
0205
0206 bool is_segment() const {
0207 return (point0_.x() != point1_.x()) || (point0_.y() != point1_.y());
0208 }
0209
0210 private:
0211 enum Bits {
0212 IS_INVERSE = 0x20
0213 };
0214
0215 point_type point0_;
0216 point_type point1_;
0217 std::size_t sorted_index_;
0218 std::size_t initial_index_;
0219 std::size_t flags_;
0220 };
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 template <typename T>
0235 class circle_event {
0236 public:
0237 typedef T coordinate_type;
0238
0239 circle_event() : is_active_(true) {}
0240
0241 circle_event(coordinate_type c_x,
0242 coordinate_type c_y,
0243 coordinate_type lower_x) :
0244 center_x_(c_x),
0245 center_y_(c_y),
0246 lower_x_(lower_x),
0247 is_active_(true) {}
0248
0249 coordinate_type x() const {
0250 return center_x_;
0251 }
0252
0253 circle_event& x(coordinate_type center_x) {
0254 center_x_ = center_x;
0255 return *this;
0256 }
0257
0258 coordinate_type y() const {
0259 return center_y_;
0260 }
0261
0262 circle_event& y(coordinate_type center_y) {
0263 center_y_ = center_y;
0264 return *this;
0265 }
0266
0267 coordinate_type lower_x() const {
0268 return lower_x_;
0269 }
0270
0271 circle_event& lower_x(coordinate_type lower_x) {
0272 lower_x_ = lower_x;
0273 return *this;
0274 }
0275
0276 coordinate_type lower_y() const {
0277 return center_y_;
0278 }
0279
0280 bool is_active() const {
0281 return is_active_;
0282 }
0283
0284 circle_event& deactivate() {
0285 is_active_ = false;
0286 return *this;
0287 }
0288
0289 private:
0290 coordinate_type center_x_;
0291 coordinate_type center_y_;
0292 coordinate_type lower_x_;
0293 bool is_active_;
0294 };
0295
0296
0297
0298
0299
0300
0301
0302
0303 template <typename T, typename Predicate>
0304 class ordered_queue {
0305 public:
0306 ordered_queue() {}
0307
0308 bool empty() const {
0309 return c_.empty();
0310 }
0311
0312 const T &top() const {
0313 return *c_.top();
0314 }
0315
0316 void pop() {
0317 list_iterator_type it = c_.top();
0318 c_.pop();
0319 c_list_.erase(it);
0320 }
0321
0322 T &push(const T &e) {
0323 c_list_.push_front(e);
0324 c_.push(c_list_.begin());
0325 return c_list_.front();
0326 }
0327
0328 void clear() {
0329 while (!c_.empty())
0330 c_.pop();
0331 c_list_.clear();
0332 }
0333
0334 private:
0335 typedef typename std::list<T>::iterator list_iterator_type;
0336
0337 struct comparison {
0338 bool operator() (const list_iterator_type &it1,
0339 const list_iterator_type &it2) const {
0340 return cmp_(*it1, *it2);
0341 }
0342 Predicate cmp_;
0343 };
0344
0345 std::priority_queue< list_iterator_type,
0346 std::vector<list_iterator_type>,
0347 comparison > c_;
0348 std::list<T> c_list_;
0349
0350
0351 ordered_queue(const ordered_queue&);
0352 void operator=(const ordered_queue&);
0353 };
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 template <typename Site>
0365 class beach_line_node_key {
0366 public:
0367 typedef Site site_type;
0368
0369
0370
0371 explicit beach_line_node_key(const site_type &new_site) :
0372 left_site_(new_site),
0373 right_site_(new_site) {}
0374
0375
0376
0377 beach_line_node_key(const site_type &left_site,
0378 const site_type &right_site) :
0379 left_site_(left_site),
0380 right_site_(right_site) {}
0381
0382 const site_type &left_site() const {
0383 return left_site_;
0384 }
0385
0386 site_type &left_site() {
0387 return left_site_;
0388 }
0389
0390 beach_line_node_key& left_site(const site_type &site) {
0391 left_site_ = site;
0392 return *this;
0393 }
0394
0395 const site_type &right_site() const {
0396 return right_site_;
0397 }
0398
0399 site_type &right_site() {
0400 return right_site_;
0401 }
0402
0403 beach_line_node_key& right_site(const site_type &site) {
0404 right_site_ = site;
0405 return *this;
0406 }
0407
0408 private:
0409 site_type left_site_;
0410 site_type right_site_;
0411 };
0412
0413
0414
0415
0416
0417 template <typename Edge, typename Circle>
0418 class beach_line_node_data {
0419 public:
0420 explicit beach_line_node_data(Edge* new_edge) :
0421 circle_event_(NULL),
0422 edge_(new_edge) {}
0423
0424 Circle* circle_event() const {
0425 return circle_event_;
0426 }
0427
0428 beach_line_node_data& circle_event(Circle* circle_event) {
0429 circle_event_ = circle_event;
0430 return *this;
0431 }
0432
0433 Edge* edge() const {
0434 return edge_;
0435 }
0436
0437 beach_line_node_data& edge(Edge* new_edge) {
0438 edge_ = new_edge;
0439 return *this;
0440 }
0441
0442 private:
0443 Circle* circle_event_;
0444 Edge* edge_;
0445 };
0446 }
0447 }
0448 }
0449
0450 #endif