voronoi_structures.hpp 11 KB

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