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