annotate DEPENDENCIES/generic/include/boost/polygon/detail/voronoi_structures.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Boost.Polygon library detail/voronoi_structures.hpp header file
Chris@16 2
Chris@16 3 // Copyright Andrii Sydorchuk 2010-2012.
Chris@16 4 // Distributed under the Boost Software License, Version 1.0.
Chris@16 5 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 // See http://www.boost.org for updates, documentation, and revision history.
Chris@16 9
Chris@16 10 #ifndef BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
Chris@16 11 #define BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
Chris@16 12
Chris@16 13 #include <list>
Chris@16 14 #include <queue>
Chris@16 15 #include <vector>
Chris@16 16
Chris@16 17 #include "boost/polygon/voronoi_geometry_type.hpp"
Chris@16 18
Chris@16 19 namespace boost {
Chris@16 20 namespace polygon {
Chris@16 21 namespace detail {
Chris@16 22 // Cartesian 2D point data structure.
Chris@16 23 template <typename T>
Chris@16 24 class point_2d {
Chris@16 25 public:
Chris@16 26 typedef T coordinate_type;
Chris@16 27
Chris@16 28 point_2d() {}
Chris@16 29
Chris@16 30 point_2d(coordinate_type x, coordinate_type y) :
Chris@16 31 x_(x),
Chris@16 32 y_(y) {}
Chris@16 33
Chris@16 34 bool operator==(const point_2d& that) const {
Chris@16 35 return (this->x_ == that.x()) && (this->y_ == that.y());
Chris@16 36 }
Chris@16 37
Chris@16 38 bool operator!=(const point_2d& that) const {
Chris@16 39 return (this->x_ != that.x()) || (this->y_ != that.y());
Chris@16 40 }
Chris@16 41
Chris@16 42 coordinate_type x() const {
Chris@16 43 return x_;
Chris@16 44 }
Chris@16 45
Chris@16 46 coordinate_type y() const {
Chris@16 47 return y_;
Chris@16 48 }
Chris@16 49
Chris@16 50 point_2d& x(coordinate_type x) {
Chris@16 51 x_ = x;
Chris@16 52 return *this;
Chris@16 53 }
Chris@16 54
Chris@16 55 point_2d& y(coordinate_type y) {
Chris@16 56 y_ = y;
Chris@16 57 return *this;
Chris@16 58 }
Chris@16 59
Chris@16 60 private:
Chris@16 61 coordinate_type x_;
Chris@16 62 coordinate_type y_;
Chris@16 63 };
Chris@16 64
Chris@16 65 // Site event type.
Chris@16 66 // Occurs when the sweepline sweeps over one of the initial sites:
Chris@16 67 // 1) point site
Chris@16 68 // 2) start-point of the segment site
Chris@16 69 // 3) endpoint of the segment site
Chris@16 70 // Implicit segment direction is defined: the start-point of
Chris@16 71 // the segment compares less than its endpoint.
Chris@16 72 // Each input segment is divided onto two site events:
Chris@16 73 // 1) One going from the start-point to the endpoint
Chris@16 74 // (is_inverse() = false)
Chris@16 75 // 2) Another going from the endpoint to the start-point
Chris@16 76 // (is_inverse() = true)
Chris@16 77 // In beach line data structure segment sites of the first
Chris@16 78 // type precede sites of the second type for the same segment.
Chris@16 79 // Members:
Chris@16 80 // point0_ - point site or segment's start-point
Chris@16 81 // point1_ - segment's endpoint if site is a segment
Chris@16 82 // sorted_index_ - the last bit encodes information if the site is inverse;
Chris@16 83 // the other bits encode site event index among the sorted site events
Chris@16 84 // initial_index_ - site index among the initial input set
Chris@16 85 // Note: for all sites is_inverse_ flag is equal to false by default.
Chris@16 86 template <typename T>
Chris@16 87 class site_event {
Chris@16 88 public:
Chris@16 89 typedef T coordinate_type;
Chris@16 90 typedef point_2d<T> point_type;
Chris@16 91
Chris@16 92 site_event() :
Chris@16 93 point0_(0, 0),
Chris@16 94 point1_(0, 0),
Chris@16 95 sorted_index_(0),
Chris@16 96 flags_(0) {}
Chris@16 97
Chris@16 98 site_event(coordinate_type x, coordinate_type y) :
Chris@16 99 point0_(x, y),
Chris@16 100 point1_(x, y),
Chris@16 101 sorted_index_(0),
Chris@16 102 flags_(0) {}
Chris@16 103
Chris@16 104 explicit site_event(const point_type& point) :
Chris@16 105 point0_(point),
Chris@16 106 point1_(point),
Chris@16 107 sorted_index_(0),
Chris@16 108 flags_(0) {}
Chris@16 109
Chris@16 110 site_event(coordinate_type x1, coordinate_type y1,
Chris@16 111 coordinate_type x2, coordinate_type y2):
Chris@16 112 point0_(x1, y1),
Chris@16 113 point1_(x2, y2),
Chris@16 114 sorted_index_(0),
Chris@16 115 flags_(0) {}
Chris@16 116
Chris@16 117 site_event(const point_type& point1, const point_type& point2) :
Chris@16 118 point0_(point1),
Chris@16 119 point1_(point2),
Chris@16 120 sorted_index_(0),
Chris@16 121 flags_(0) {}
Chris@16 122
Chris@16 123 bool operator==(const site_event& that) const {
Chris@16 124 return (this->point0_ == that.point0_) &&
Chris@16 125 (this->point1_ == that.point1_);
Chris@16 126 }
Chris@16 127
Chris@16 128 bool operator!=(const site_event& that) const {
Chris@16 129 return (this->point0_ != that.point0_) ||
Chris@16 130 (this->point1_ != that.point1_);
Chris@16 131 }
Chris@16 132
Chris@16 133 coordinate_type x() const {
Chris@16 134 return point0_.x();
Chris@16 135 }
Chris@16 136
Chris@16 137 coordinate_type y() const {
Chris@16 138 return point0_.y();
Chris@16 139 }
Chris@16 140
Chris@16 141 coordinate_type x0() const {
Chris@16 142 return point0_.x();
Chris@16 143 }
Chris@16 144
Chris@16 145 coordinate_type y0() const {
Chris@16 146 return point0_.y();
Chris@16 147 }
Chris@16 148
Chris@16 149 coordinate_type x1() const {
Chris@16 150 return point1_.x();
Chris@16 151 }
Chris@16 152
Chris@16 153 coordinate_type y1() const {
Chris@16 154 return point1_.y();
Chris@16 155 }
Chris@16 156
Chris@16 157 const point_type& point0() const {
Chris@16 158 return point0_;
Chris@16 159 }
Chris@16 160
Chris@16 161 const point_type& point1() const {
Chris@16 162 return point1_;
Chris@16 163 }
Chris@16 164
Chris@16 165 std::size_t sorted_index() const {
Chris@16 166 return sorted_index_;
Chris@16 167 }
Chris@16 168
Chris@16 169 site_event& sorted_index(std::size_t index) {
Chris@16 170 sorted_index_ = index;
Chris@16 171 return *this;
Chris@16 172 }
Chris@16 173
Chris@16 174 std::size_t initial_index() const {
Chris@16 175 return initial_index_;
Chris@16 176 }
Chris@16 177
Chris@16 178 site_event& initial_index(std::size_t index) {
Chris@16 179 initial_index_ = index;
Chris@16 180 return *this;
Chris@16 181 }
Chris@16 182
Chris@16 183 bool is_inverse() const {
Chris@16 184 return (flags_ & IS_INVERSE) ? true : false;
Chris@16 185 }
Chris@16 186
Chris@16 187 site_event& inverse() {
Chris@16 188 std::swap(point0_, point1_);
Chris@16 189 flags_ ^= IS_INVERSE;
Chris@16 190 return *this;
Chris@16 191 }
Chris@16 192
Chris@16 193 SourceCategory source_category() const {
Chris@16 194 return static_cast<SourceCategory>(flags_ & SOURCE_CATEGORY_BITMASK);
Chris@16 195 }
Chris@16 196
Chris@16 197 site_event& source_category(SourceCategory source_category) {
Chris@16 198 flags_ |= source_category;
Chris@16 199 return *this;
Chris@16 200 }
Chris@16 201
Chris@16 202 bool is_point() const {
Chris@16 203 return (point0_.x() == point1_.x()) && (point0_.y() == point1_.y());
Chris@16 204 }
Chris@16 205
Chris@16 206 bool is_segment() const {
Chris@16 207 return (point0_.x() != point1_.x()) || (point0_.y() != point1_.y());
Chris@16 208 }
Chris@16 209
Chris@16 210 private:
Chris@16 211 enum Bits {
Chris@16 212 IS_INVERSE = 0x20 // 32
Chris@16 213 };
Chris@16 214
Chris@16 215 point_type point0_;
Chris@16 216 point_type point1_;
Chris@16 217 std::size_t sorted_index_;
Chris@16 218 std::size_t initial_index_;
Chris@16 219 std::size_t flags_;
Chris@16 220 };
Chris@16 221
Chris@16 222 // Circle event type.
Chris@16 223 // Occurs when the sweepline sweeps over the rightmost point of the Voronoi
Chris@16 224 // circle (with the center at the intersection point of the bisectors).
Chris@16 225 // Circle event is made of the two consecutive nodes in the beach line data
Chris@16 226 // structure. In case another node was inserted during algorithm execution
Chris@16 227 // between the given two nodes circle event becomes inactive.
Chris@16 228 // Variables:
Chris@16 229 // center_x_ - center x-coordinate;
Chris@16 230 // center_y_ - center y-coordinate;
Chris@16 231 // lower_x_ - leftmost x-coordinate;
Chris@16 232 // is_active_ - states whether circle event is still active.
Chris@16 233 // NOTE: lower_y coordinate is always equal to center_y.
Chris@16 234 template <typename T>
Chris@16 235 class circle_event {
Chris@16 236 public:
Chris@16 237 typedef T coordinate_type;
Chris@16 238
Chris@16 239 circle_event() : is_active_(true) {}
Chris@16 240
Chris@16 241 circle_event(coordinate_type c_x,
Chris@16 242 coordinate_type c_y,
Chris@16 243 coordinate_type lower_x) :
Chris@16 244 center_x_(c_x),
Chris@16 245 center_y_(c_y),
Chris@16 246 lower_x_(lower_x),
Chris@16 247 is_active_(true) {}
Chris@16 248
Chris@16 249 coordinate_type x() const {
Chris@16 250 return center_x_;
Chris@16 251 }
Chris@16 252
Chris@16 253 circle_event& x(coordinate_type center_x) {
Chris@16 254 center_x_ = center_x;
Chris@16 255 return *this;
Chris@16 256 }
Chris@16 257
Chris@16 258 coordinate_type y() const {
Chris@16 259 return center_y_;
Chris@16 260 }
Chris@16 261
Chris@16 262 circle_event& y(coordinate_type center_y) {
Chris@16 263 center_y_ = center_y;
Chris@16 264 return *this;
Chris@16 265 }
Chris@16 266
Chris@16 267 coordinate_type lower_x() const {
Chris@16 268 return lower_x_;
Chris@16 269 }
Chris@16 270
Chris@16 271 circle_event& lower_x(coordinate_type lower_x) {
Chris@16 272 lower_x_ = lower_x;
Chris@16 273 return *this;
Chris@16 274 }
Chris@16 275
Chris@16 276 coordinate_type lower_y() const {
Chris@16 277 return center_y_;
Chris@16 278 }
Chris@16 279
Chris@16 280 bool is_active() const {
Chris@16 281 return is_active_;
Chris@16 282 }
Chris@16 283
Chris@16 284 circle_event& deactivate() {
Chris@16 285 is_active_ = false;
Chris@16 286 return *this;
Chris@16 287 }
Chris@16 288
Chris@16 289 private:
Chris@16 290 coordinate_type center_x_;
Chris@16 291 coordinate_type center_y_;
Chris@16 292 coordinate_type lower_x_;
Chris@16 293 bool is_active_;
Chris@16 294 };
Chris@16 295
Chris@16 296 // Event queue data structure, holds circle events.
Chris@16 297 // During algorithm run, some of the circle events disappear (become
Chris@16 298 // inactive). Priority queue data structure doesn't support
Chris@16 299 // iterators (there is no direct ability to modify its elements).
Chris@16 300 // Instead list is used to store all the circle events and priority queue
Chris@16 301 // of the iterators to the list elements is used to keep the correct circle
Chris@16 302 // events ordering.
Chris@16 303 template <typename T, typename Predicate>
Chris@16 304 class ordered_queue {
Chris@16 305 public:
Chris@16 306 ordered_queue() {}
Chris@16 307
Chris@16 308 bool empty() const {
Chris@16 309 return c_.empty();
Chris@16 310 }
Chris@16 311
Chris@16 312 const T &top() const {
Chris@16 313 return *c_.top();
Chris@16 314 }
Chris@16 315
Chris@16 316 void pop() {
Chris@16 317 list_iterator_type it = c_.top();
Chris@16 318 c_.pop();
Chris@16 319 c_list_.erase(it);
Chris@16 320 }
Chris@16 321
Chris@16 322 T &push(const T &e) {
Chris@16 323 c_list_.push_front(e);
Chris@16 324 c_.push(c_list_.begin());
Chris@16 325 return c_list_.front();
Chris@16 326 }
Chris@16 327
Chris@16 328 void clear() {
Chris@16 329 while (!c_.empty())
Chris@16 330 c_.pop();
Chris@16 331 c_list_.clear();
Chris@16 332 }
Chris@16 333
Chris@16 334 private:
Chris@16 335 typedef typename std::list<T>::iterator list_iterator_type;
Chris@16 336
Chris@16 337 struct comparison {
Chris@16 338 bool operator() (const list_iterator_type &it1,
Chris@16 339 const list_iterator_type &it2) const {
Chris@16 340 return cmp_(*it1, *it2);
Chris@16 341 }
Chris@16 342 Predicate cmp_;
Chris@16 343 };
Chris@16 344
Chris@16 345 std::priority_queue< list_iterator_type,
Chris@16 346 std::vector<list_iterator_type>,
Chris@16 347 comparison > c_;
Chris@16 348 std::list<T> c_list_;
Chris@16 349
Chris@16 350 // Disallow copy constructor and operator=
Chris@16 351 ordered_queue(const ordered_queue&);
Chris@16 352 void operator=(const ordered_queue&);
Chris@16 353 };
Chris@16 354
Chris@16 355 // Represents a bisector node made by two arcs that correspond to the left
Chris@16 356 // and right sites. Arc is defined as a curve with points equidistant from
Chris@16 357 // the site and from the sweepline. If the site is a point then arc is
Chris@16 358 // a parabola, otherwise it's a line segment. A segment site event will
Chris@16 359 // produce different bisectors based on its direction.
Chris@16 360 // In general case two sites will create two opposite bisectors. That's
Chris@16 361 // why the order of the sites is important to define the unique bisector.
Chris@16 362 // The one site is considered to be newer than the other one if it was
Chris@16 363 // processed by the algorithm later (has greater index).
Chris@16 364 template <typename Site>
Chris@16 365 class beach_line_node_key {
Chris@16 366 public:
Chris@16 367 typedef Site site_type;
Chris@16 368
Chris@16 369 // Constructs degenerate bisector, used to search an arc that is above
Chris@16 370 // the given site. The input to the constructor is the new site point.
Chris@16 371 explicit beach_line_node_key(const site_type &new_site) :
Chris@16 372 left_site_(new_site),
Chris@16 373 right_site_(new_site) {}
Chris@16 374
Chris@16 375 // Constructs a new bisector. The input to the constructor is the two
Chris@16 376 // sites that create the bisector. The order of sites is important.
Chris@16 377 beach_line_node_key(const site_type &left_site,
Chris@16 378 const site_type &right_site) :
Chris@16 379 left_site_(left_site),
Chris@16 380 right_site_(right_site) {}
Chris@16 381
Chris@16 382 const site_type &left_site() const {
Chris@16 383 return left_site_;
Chris@16 384 }
Chris@16 385
Chris@16 386 site_type &left_site() {
Chris@16 387 return left_site_;
Chris@16 388 }
Chris@16 389
Chris@16 390 beach_line_node_key& left_site(const site_type &site) {
Chris@16 391 left_site_ = site;
Chris@16 392 return *this;
Chris@16 393 }
Chris@16 394
Chris@16 395 const site_type &right_site() const {
Chris@16 396 return right_site_;
Chris@16 397 }
Chris@16 398
Chris@16 399 site_type &right_site() {
Chris@16 400 return right_site_;
Chris@16 401 }
Chris@16 402
Chris@16 403 beach_line_node_key& right_site(const site_type &site) {
Chris@16 404 right_site_ = site;
Chris@16 405 return *this;
Chris@16 406 }
Chris@16 407
Chris@16 408 private:
Chris@16 409 site_type left_site_;
Chris@16 410 site_type right_site_;
Chris@16 411 };
Chris@16 412
Chris@16 413 // Represents edge data structure from the Voronoi output, that is
Chris@16 414 // associated as a value with beach line bisector in the beach
Chris@16 415 // line. Contains pointer to the circle event in the circle event
Chris@16 416 // queue if the edge corresponds to the right bisector of the circle event.
Chris@16 417 template <typename Edge, typename Circle>
Chris@16 418 class beach_line_node_data {
Chris@16 419 public:
Chris@16 420 explicit beach_line_node_data(Edge* new_edge) :
Chris@16 421 circle_event_(NULL),
Chris@16 422 edge_(new_edge) {}
Chris@16 423
Chris@16 424 Circle* circle_event() const {
Chris@16 425 return circle_event_;
Chris@16 426 }
Chris@16 427
Chris@16 428 beach_line_node_data& circle_event(Circle* circle_event) {
Chris@16 429 circle_event_ = circle_event;
Chris@16 430 return *this;
Chris@16 431 }
Chris@16 432
Chris@16 433 Edge* edge() const {
Chris@16 434 return edge_;
Chris@16 435 }
Chris@16 436
Chris@16 437 beach_line_node_data& edge(Edge* new_edge) {
Chris@16 438 edge_ = new_edge;
Chris@16 439 return *this;
Chris@16 440 }
Chris@16 441
Chris@16 442 private:
Chris@16 443 Circle* circle_event_;
Chris@16 444 Edge* edge_;
Chris@16 445 };
Chris@16 446 } // detail
Chris@16 447 } // polygon
Chris@16 448 } // boost
Chris@16 449
Chris@16 450 #endif // BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES