1 /*
2  * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
3  * http://code.google.com/p/poly2tri/
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright notice,
13  *   this list of conditions and the following disclaimer in the documentation
14  *   and/or other materials provided with the distribution.
15  * * Neither the name of Poly2Tri nor the names of its contributors may be
16  *   used to endorse or promote products derived from this software without specific
17  *   prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 // Include guard
33 #ifndef SHAPES_H
34 #define SHAPES_H
35 
36 #include <vector>
37 #include <cstddef>
38 #include <assert.h>
39 #include <cmath>
40 
41 namespace p2t {
42 
43 struct Edge;
44 
45 struct Point {
46 
47   double x, y;
48 
49   /// Default constructor does nothing (for performance).
PointPoint50   Point()
51   {
52     x = 0.0;
53     y = 0.0;
54   }
55 
56   /// The edges this point constitutes an upper ending point
57   std::vector<Edge*> edge_list;
58 
59   /// Construct using coordinates.
PointPoint60   Point(double x, double y) : x(x), y(y) {}
61 
62   /// Set this point to all zeros.
set_zeroPoint63   void set_zero()
64   {
65     x = 0.0;
66     y = 0.0;
67   }
68 
69   /// Set this point to some specified coordinates.
setPoint70   void set(double x_, double y_)
71   {
72     x = x_;
73     y = y_;
74   }
75 
76   /// Negate this point.
77   Point operator -() const
78   {
79     Point v;
80     v.set(-x, -y);
81     return v;
82   }
83 
84   /// Add a point to this point.
85   void operator +=(const Point& v)
86   {
87     x += v.x;
88     y += v.y;
89   }
90 
91   /// Subtract a point from this point.
92   void operator -=(const Point& v)
93   {
94     x -= v.x;
95     y -= v.y;
96   }
97 
98   /// Multiply this point by a scalar.
99   void operator *=(double a)
100   {
101     x *= a;
102     y *= a;
103   }
104 
105   /// Get the length of this point (the norm).
LengthPoint106   double Length() const
107   {
108     return std::sqrt(x * x + y * y);
109   }
110 
111   /// Convert this point into a unit point. Returns the Length.
NormalizePoint112   double Normalize()
113   {
114     double len = Length();
115     x /= len;
116     y /= len;
117     return len;
118   }
119 
120 };
121 
122 // Represents a simple polygon's edge
123 struct Edge {
124 
125   Point* p, *q;
126 
127   /// Constructor
EdgeEdge128   Edge(Point& p1, Point& p2) : p(&p1), q(&p2)
129   {
130     if (p1.y > p2.y) {
131       q = &p1;
132       p = &p2;
133     } else if (p1.y == p2.y) {
134       if (p1.x > p2.x) {
135         q = &p1;
136         p = &p2;
137       } else if (p1.x == p2.x) {
138         // Repeat points
139         assert(false);
140       }
141     }
142 
143     q->edge_list.push_back(this);
144   }
145 };
146 
147 // Triangle-based data structures are know to have better performance than quad-edge structures
148 // See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
149 //      "Triangulations in CGAL"
150 class Triangle {
151 public:
152 
153 /// Constructor
154 Triangle(Point& a, Point& b, Point& c);
155 
156 /// Flags to determine if an edge is a Constrained edge
157 bool constrained_edge[3];
158 /// Flags to determine if an edge is a Delauney edge
159 bool delaunay_edge[3];
160 
161 Point* GetPoint(const int& index);
162 Point* PointCW(Point& point);
163 Point* PointCCW(Point& point);
164 Point* OppositePoint(Triangle& t, Point& p);
165 
166 Triangle* GetNeighbor(const int& index);
167 void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
168 void MarkNeighbor(Triangle& t);
169 
170 void MarkConstrainedEdge(const int index);
171 void MarkConstrainedEdge(Edge& edge);
172 void MarkConstrainedEdge(Point* p, Point* q);
173 
174 int Index(const Point* p);
175 int EdgeIndex(const Point* p1, const Point* p2);
176 
177 Triangle* NeighborCW(Point& point);
178 Triangle* NeighborCCW(Point& point);
179 bool GetConstrainedEdgeCCW(Point& p);
180 bool GetConstrainedEdgeCW(Point& p);
181 void SetConstrainedEdgeCCW(Point& p, bool ce);
182 void SetConstrainedEdgeCW(Point& p, bool ce);
183 bool GetDelunayEdgeCCW(Point& p);
184 bool GetDelunayEdgeCW(Point& p);
185 void SetDelunayEdgeCCW(Point& p, bool e);
186 void SetDelunayEdgeCW(Point& p, bool e);
187 
188 bool Contains(Point* p);
189 bool Contains(const Edge& e);
190 bool Contains(Point* p, Point* q);
191 void Legalize(Point& point);
192 void Legalize(Point& opoint, Point& npoint);
193 /**
194  * Clears all references to all other triangles and points
195  */
196 void Clear();
197 void ClearNeighbor(Triangle *triangle );
198 void ClearNeighbors();
199 void ClearDelunayEdges();
200 
201 inline bool IsInterior();
202 inline void IsInterior(bool b);
203 
204 Triangle& NeighborAcross(Point& opoint);
205 
206 void DebugPrint();
207 
208 private:
209 
210 /// Triangle points
211 Point* points_[3];
212 /// Neighbor list
213 Triangle* neighbors_[3];
214 
215 /// Has this triangle been marked as an interior triangle?
216 bool interior_;
217 };
218 
cmp(const Point * a,const Point * b)219 inline bool cmp(const Point* a, const Point* b)
220 {
221   if (a->y < b->y) {
222     return true;
223   } else if (a->y == b->y) {
224     // Make sure q is point with greater x value
225     if (a->x < b->x) {
226       return true;
227     }
228   }
229   return false;
230 }
231 
232 /// Add two points_ component-wise.
233 inline Point operator +(const Point& a, const Point& b)
234 {
235   return Point(a.x + b.x, a.y + b.y);
236 }
237 
238 /// Subtract two points_ component-wise.
239 inline Point operator -(const Point& a, const Point& b)
240 {
241   return Point(a.x - b.x, a.y - b.y);
242 }
243 
244 /// Multiply point by scalar
245 inline Point operator *(double s, const Point& a)
246 {
247   return Point(s * a.x, s * a.y);
248 }
249 
250 inline bool operator ==(const Point& a, const Point& b)
251 {
252   return a.x == b.x && a.y == b.y;
253 }
254 
255 inline bool operator !=(const Point& a, const Point& b)
256 {
257   return !(a.x == b.x) && !(a.y == b.y);
258 }
259 
260 /// Peform the dot product on two vectors.
Dot(const Point & a,const Point & b)261 inline double Dot(const Point& a, const Point& b)
262 {
263   return a.x * b.x + a.y * b.y;
264 }
265 
266 /// Perform the cross product on two vectors. In 2D this produces a scalar.
Cross(const Point & a,const Point & b)267 inline double Cross(const Point& a, const Point& b)
268 {
269   return a.x * b.y - a.y * b.x;
270 }
271 
272 /// Perform the cross product on a point and a scalar. In 2D this produces
273 /// a point.
Cross(const Point & a,double s)274 inline Point Cross(const Point& a, double s)
275 {
276   return Point(s * a.y, -s * a.x);
277 }
278 
279 /// Perform the cross product on a scalar and a point. In 2D this produces
280 /// a point.
Cross(const double s,const Point & a)281 inline Point Cross(const double s, const Point& a)
282 {
283   return Point(-s * a.y, s * a.x);
284 }
285 
GetPoint(const int & index)286 inline Point* Triangle::GetPoint(const int& index)
287 {
288   return points_[index];
289 }
290 
GetNeighbor(const int & index)291 inline Triangle* Triangle::GetNeighbor(const int& index)
292 {
293   return neighbors_[index];
294 }
295 
Contains(Point * p)296 inline bool Triangle::Contains(Point* p)
297 {
298   return p == points_[0] || p == points_[1] || p == points_[2];
299 }
300 
Contains(const Edge & e)301 inline bool Triangle::Contains(const Edge& e)
302 {
303   return Contains(e.p) && Contains(e.q);
304 }
305 
Contains(Point * p,Point * q)306 inline bool Triangle::Contains(Point* p, Point* q)
307 {
308   return Contains(p) && Contains(q);
309 }
310 
IsInterior()311 inline bool Triangle::IsInterior()
312 {
313   return interior_;
314 }
315 
IsInterior(bool b)316 inline void Triangle::IsInterior(bool b)
317 {
318   interior_ = b;
319 }
320 
321 }
322 
323 #endif
324 
325 
326