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 #include "shapes.h"
32 #include <iostream>
33
34 namespace p2t {
35
Triangle(Point & a,Point & b,Point & c)36 Triangle::Triangle(Point& a, Point& b, Point& c)
37 {
38 points_[0] = &a; points_[1] = &b; points_[2] = &c;
39 neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL;
40 constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false;
41 delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
42 interior_ = false;
43 }
44
45 // Update neighbor pointers
MarkNeighbor(Point * p1,Point * p2,Triangle * t)46 void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t)
47 {
48 if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2]))
49 neighbors_[0] = t;
50 else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0]))
51 neighbors_[1] = t;
52 else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0]))
53 neighbors_[2] = t;
54 else
55 assert(0);
56 }
57
58 // Exhaustive search to update neighbor pointers
MarkNeighbor(Triangle & t)59 void Triangle::MarkNeighbor(Triangle& t)
60 {
61 if (t.Contains(points_[1], points_[2])) {
62 neighbors_[0] = &t;
63 t.MarkNeighbor(points_[1], points_[2], this);
64 } else if (t.Contains(points_[0], points_[2])) {
65 neighbors_[1] = &t;
66 t.MarkNeighbor(points_[0], points_[2], this);
67 } else if (t.Contains(points_[0], points_[1])) {
68 neighbors_[2] = &t;
69 t.MarkNeighbor(points_[0], points_[1], this);
70 }
71 }
72
73 /**
74 * Clears all references to all other triangles and points
75 */
Clear()76 void Triangle::Clear()
77 {
78 Triangle *t;
79 for (int i=0; i<3; i++)
80 {
81 t = neighbors_[i];
82 if (t != NULL)
83 {
84 t->ClearNeighbor( this );
85 }
86 }
87 ClearNeighbors();
88 points_[0]=points_[1]=points_[2] = NULL;
89 }
90
ClearNeighbor(Triangle * triangle)91 void Triangle::ClearNeighbor(Triangle *triangle )
92 {
93 if (neighbors_[0] == triangle)
94 {
95 neighbors_[0] = NULL;
96 }
97 else if (neighbors_[1] == triangle)
98 {
99 neighbors_[1] = NULL;
100 }
101 else
102 {
103 neighbors_[2] = NULL;
104 }
105 }
106
ClearNeighbors()107 void Triangle::ClearNeighbors()
108 {
109 neighbors_[0] = NULL;
110 neighbors_[1] = NULL;
111 neighbors_[2] = NULL;
112 }
113
ClearDelunayEdges()114 void Triangle::ClearDelunayEdges()
115 {
116 delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
117 }
118
OppositePoint(Triangle & t,Point & p)119 Point* Triangle::OppositePoint(Triangle& t, Point& p)
120 {
121 Point *cw = t.PointCW(p);
122 return PointCW(*cw);
123 }
124
125 // Legalized triangle by rotating clockwise around point(0)
Legalize(Point & point)126 void Triangle::Legalize(Point& point)
127 {
128 points_[1] = points_[0];
129 points_[0] = points_[2];
130 points_[2] = &point;
131 }
132
133 // Legalize triagnle by rotating clockwise around oPoint
Legalize(Point & opoint,Point & npoint)134 void Triangle::Legalize(Point& opoint, Point& npoint)
135 {
136 if (&opoint == points_[0]) {
137 points_[1] = points_[0];
138 points_[0] = points_[2];
139 points_[2] = &npoint;
140 } else if (&opoint == points_[1]) {
141 points_[2] = points_[1];
142 points_[1] = points_[0];
143 points_[0] = &npoint;
144 } else if (&opoint == points_[2]) {
145 points_[0] = points_[2];
146 points_[2] = points_[1];
147 points_[1] = &npoint;
148 } else {
149 assert(0);
150 }
151 }
152
Index(const Point * p)153 int Triangle::Index(const Point* p)
154 {
155 if (p == points_[0]) {
156 return 0;
157 } else if (p == points_[1]) {
158 return 1;
159 } else if (p == points_[2]) {
160 return 2;
161 }
162 assert(0);
163 }
164
EdgeIndex(const Point * p1,const Point * p2)165 int Triangle::EdgeIndex(const Point* p1, const Point* p2)
166 {
167 if (points_[0] == p1) {
168 if (points_[1] == p2) {
169 return 2;
170 } else if (points_[2] == p2) {
171 return 1;
172 }
173 } else if (points_[1] == p1) {
174 if (points_[2] == p2) {
175 return 0;
176 } else if (points_[0] == p2) {
177 return 2;
178 }
179 } else if (points_[2] == p1) {
180 if (points_[0] == p2) {
181 return 1;
182 } else if (points_[1] == p2) {
183 return 0;
184 }
185 }
186 return -1;
187 }
188
MarkConstrainedEdge(const int index)189 void Triangle::MarkConstrainedEdge(const int index)
190 {
191 constrained_edge[index] = true;
192 }
193
MarkConstrainedEdge(Edge & edge)194 void Triangle::MarkConstrainedEdge(Edge& edge)
195 {
196 MarkConstrainedEdge(edge.p, edge.q);
197 }
198
199 // Mark edge as constrained
MarkConstrainedEdge(Point * p,Point * q)200 void Triangle::MarkConstrainedEdge(Point* p, Point* q)
201 {
202 if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) {
203 constrained_edge[2] = true;
204 } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) {
205 constrained_edge[1] = true;
206 } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) {
207 constrained_edge[0] = true;
208 }
209 }
210
211 // The point counter-clockwise to given point
PointCW(Point & point)212 Point* Triangle::PointCW(Point& point)
213 {
214 if (&point == points_[0]) {
215 return points_[2];
216 } else if (&point == points_[1]) {
217 return points_[0];
218 } else if (&point == points_[2]) {
219 return points_[1];
220 }
221 assert(0);
222 }
223
224 // The point counter-clockwise to given point
PointCCW(Point & point)225 Point* Triangle::PointCCW(Point& point)
226 {
227 if (&point == points_[0]) {
228 return points_[1];
229 } else if (&point == points_[1]) {
230 return points_[2];
231 } else if (&point == points_[2]) {
232 return points_[0];
233 }
234 assert(0);
235 }
236
237 // The neighbor clockwise to given point
NeighborCW(Point & point)238 Triangle* Triangle::NeighborCW(Point& point)
239 {
240 if (&point == points_[0]) {
241 return neighbors_[1];
242 } else if (&point == points_[1]) {
243 return neighbors_[2];
244 }
245 return neighbors_[0];
246 }
247
248 // The neighbor counter-clockwise to given point
NeighborCCW(Point & point)249 Triangle* Triangle::NeighborCCW(Point& point)
250 {
251 if (&point == points_[0]) {
252 return neighbors_[2];
253 } else if (&point == points_[1]) {
254 return neighbors_[0];
255 }
256 return neighbors_[1];
257 }
258
GetConstrainedEdgeCCW(Point & p)259 bool Triangle::GetConstrainedEdgeCCW(Point& p)
260 {
261 if (&p == points_[0]) {
262 return constrained_edge[2];
263 } else if (&p == points_[1]) {
264 return constrained_edge[0];
265 }
266 return constrained_edge[1];
267 }
268
GetConstrainedEdgeCW(Point & p)269 bool Triangle::GetConstrainedEdgeCW(Point& p)
270 {
271 if (&p == points_[0]) {
272 return constrained_edge[1];
273 } else if (&p == points_[1]) {
274 return constrained_edge[2];
275 }
276 return constrained_edge[0];
277 }
278
SetConstrainedEdgeCCW(Point & p,bool ce)279 void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
280 {
281 if (&p == points_[0]) {
282 constrained_edge[2] = ce;
283 } else if (&p == points_[1]) {
284 constrained_edge[0] = ce;
285 } else {
286 constrained_edge[1] = ce;
287 }
288 }
289
SetConstrainedEdgeCW(Point & p,bool ce)290 void Triangle::SetConstrainedEdgeCW(Point& p, bool ce)
291 {
292 if (&p == points_[0]) {
293 constrained_edge[1] = ce;
294 } else if (&p == points_[1]) {
295 constrained_edge[2] = ce;
296 } else {
297 constrained_edge[0] = ce;
298 }
299 }
300
GetDelunayEdgeCCW(Point & p)301 bool Triangle::GetDelunayEdgeCCW(Point& p)
302 {
303 if (&p == points_[0]) {
304 return delaunay_edge[2];
305 } else if (&p == points_[1]) {
306 return delaunay_edge[0];
307 }
308 return delaunay_edge[1];
309 }
310
GetDelunayEdgeCW(Point & p)311 bool Triangle::GetDelunayEdgeCW(Point& p)
312 {
313 if (&p == points_[0]) {
314 return delaunay_edge[1];
315 } else if (&p == points_[1]) {
316 return delaunay_edge[2];
317 }
318 return delaunay_edge[0];
319 }
320
SetDelunayEdgeCCW(Point & p,bool e)321 void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
322 {
323 if (&p == points_[0]) {
324 delaunay_edge[2] = e;
325 } else if (&p == points_[1]) {
326 delaunay_edge[0] = e;
327 } else {
328 delaunay_edge[1] = e;
329 }
330 }
331
SetDelunayEdgeCW(Point & p,bool e)332 void Triangle::SetDelunayEdgeCW(Point& p, bool e)
333 {
334 if (&p == points_[0]) {
335 delaunay_edge[1] = e;
336 } else if (&p == points_[1]) {
337 delaunay_edge[2] = e;
338 } else {
339 delaunay_edge[0] = e;
340 }
341 }
342
343 // The neighbor across to given point
NeighborAcross(Point & opoint)344 Triangle& Triangle::NeighborAcross(Point& opoint)
345 {
346 if (&opoint == points_[0]) {
347 return *neighbors_[0];
348 } else if (&opoint == points_[1]) {
349 return *neighbors_[1];
350 }
351 return *neighbors_[2];
352 }
353
DebugPrint()354 void Triangle::DebugPrint()
355 {
356 using namespace std;
357 cout << points_[0]->x << "," << points_[0]->y << " ";
358 cout << points_[1]->x << "," << points_[1]->y << " ";
359 cout << points_[2]->x << "," << points_[2]->y << endl;
360 }
361
362 }
363
364