1 // Copyright (c) 2000 Max-Planck-Institute Saarbruecken (Germany). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h $ 7 // $Id: Rotation_tree_2.h 4bb0406 2021-02-04T18:12:12+01:00 Sébastien Loriot 8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // 11 // Author(s) : Susan Hert <hert@mpi-sb.mpg.de> 12 13 /* 14 A rotation tree for computing the vertex visibility graph of a set of 15 non-intersecting segments in the plane (e.g. edges of a polygon). 16 17 Let $V$ be the set of segment endpoints and 18 let $p_{\infinity}$ ($p_{-\infinity}$) be a point with $y$ coordinate 19 $\infinity$ ($-\infinity$) and $x$ coordinate larger than all points 20 in $V$. The tree $G$ is a tree with node set 21 $V \cup \{p_{\infinity}, p_{-\infinity}\}$. Every node (except the one 22 corresponding to $p_{\infinity}$) has exactly one outgoing edge to the 23 point $q$ with the following property: $q$ is the first point encountered 24 when looking from $p$ in direction $d$ and rotating counterclockwise. 25 */ 26 27 #ifndef CGAL_ROTATION_TREE_H 28 #define CGAL_ROTATION_TREE_H 29 30 #include <CGAL/disable_warnings.h> 31 32 #include <CGAL/license/Partition_2.h> 33 34 35 #include <CGAL/vector.h> 36 #include <CGAL/Partition_2/Rotation_tree_node_2.h> 37 38 namespace CGAL { 39 40 template <class Traits_> 41 class Rotation_tree_2 : public internal::vector< Rotation_tree_node_2<Traits_> > 42 { 43 public: 44 typedef Traits_ Traits; 45 typedef Rotation_tree_node_2<Traits> Node; 46 typedef typename internal::vector<Node>::iterator Self_iterator; 47 typedef typename Traits::Point_2 Point_2; 48 49 using internal::vector< Rotation_tree_node_2<Traits_> >::push_back; 50 using internal::vector< Rotation_tree_node_2<Traits_> >::back; 51 52 class Greater { 53 typename Traits::Less_xy_2 less; 54 typedef typename Traits::Point_2 Point; 55 public: Greater(typename Traits::Less_xy_2 less)56 Greater(typename Traits::Less_xy_2 less) : less(less) {} 57 58 template <typename Point_like> operator()59 bool operator()(const Point_like& p1, const Point_like& p2) { 60 return less(Point(p2), Point(p1)); 61 } 62 }; 63 64 struct Equal { operatorEqual65 bool operator()(const Point_2& p, const Point_2& q) const 66 { 67 return p == q; 68 } 69 }; 70 71 // constructor 72 template<class ForwardIterator> Rotation_tree_2(ForwardIterator first,ForwardIterator beyond,const Traits & traits)73 Rotation_tree_2(ForwardIterator first, ForwardIterator beyond, const Traits& traits) 74 { 75 for (ForwardIterator it = first; it != beyond; it++) 76 push_back(*it); 77 78 Greater greater (traits.less_xy_2_object()); 79 Equal equal; 80 std::sort(this->begin(), this->end(), greater); 81 std::unique(this->begin(), this->end(),equal); 82 83 // front() is the point with the largest x coordinate 84 85 // Add two auxiliary points that have a special role and whose coordinates are not used 86 // push the point p_minus_infinity; the coordinates should never be used 87 push_back(back()); 88 89 // push the point p_infinity; the coordinates should never be used 90 push_back(back()); 91 92 _p_inf = this->end(); // record the iterators to these extreme points 93 _p_inf--; 94 _p_minus_inf = _p_inf; 95 _p_minus_inf--; 96 97 Self_iterator child; 98 // make p_minus_inf a child of p_inf 99 set_rightmost_child(_p_minus_inf, _p_inf); 100 child = this->begin(); // now points to p_0 101 while (child != _p_minus_inf) // make all points children of p_minus_inf 102 { 103 set_rightmost_child(child, _p_minus_inf); 104 child++; 105 } 106 } 107 108 109 // the point that comes first in the right-to-left ordering is first 110 // in the ordering, after the auxilliary points p_minus_inf and p_inf rightmost_point_ref()111 Self_iterator rightmost_point_ref() 112 { 113 return this->begin(); 114 } 115 right_sibling(Self_iterator p)116 Self_iterator right_sibling(Self_iterator p) 117 { 118 if (!(*p).has_right_sibling()) return this->end(); 119 return (*p).right_sibling(); 120 } 121 left_sibling(Self_iterator p)122 Self_iterator left_sibling(Self_iterator p) 123 { 124 if (!(*p).has_left_sibling()) return this->end(); 125 return (*p).left_sibling(); 126 } 127 rightmost_child(Self_iterator p)128 Self_iterator rightmost_child(Self_iterator p) 129 { 130 if (!(*p).has_children()) return this->end(); 131 return (*p).rightmost_child(); 132 } 133 parent(Self_iterator p)134 Self_iterator parent(Self_iterator p) 135 { 136 if (!(*p).has_parent()) return this->end(); 137 return (*p).parent(); 138 } 139 parent_is_p_infinity(Self_iterator p)140 bool parent_is_p_infinity(Self_iterator p) 141 { 142 return parent(p) == _p_inf; 143 } 144 parent_is_p_minus_infinity(Self_iterator p)145 bool parent_is_p_minus_infinity(Self_iterator p) 146 { 147 return parent(p) == _p_minus_inf; 148 } 149 150 // makes *p the parent of *q set_parent(Self_iterator p,Self_iterator q)151 void set_parent (Self_iterator p, Self_iterator q) 152 { 153 CGAL_assertion(q != this->end()); 154 if (p == this->end()) 155 (*q).clear_parent(); 156 else 157 (*q).set_parent(p); 158 } 159 160 // makes *p the rightmost child of *q 161 void set_rightmost_child(Self_iterator p, Self_iterator q); 162 163 // makes *p the left sibling of *q 164 void set_left_sibling(Self_iterator p, Self_iterator q); 165 166 // makes *p the right sibling of *q 167 void set_right_sibling(Self_iterator p, Self_iterator q); 168 169 // NOTE: this function does not actually remove the node p from the 170 // list; it only reorganizes the pointers so this node is not 171 // in the tree structure anymore 172 void erase(Self_iterator p); 173 174 private: 175 Self_iterator _p_inf; 176 Self_iterator _p_minus_inf; 177 }; 178 179 } 180 181 #include <CGAL/Partition_2/Rotation_tree_2_impl.h> 182 183 #include <CGAL/enable_warnings.h> 184 185 #endif // CGAL_ROTATION_TREE_H 186 187 // For the Emacs editor: 188 // Local Variables: 189 // c-basic-offset: 3 190 // End: 191