/src/assimp/contrib/poly2tri/poly2tri/common/shapes.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors |
3 | | * https://github.com/jhasse/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 | | #pragma once |
33 | | |
34 | | #include "dll_symbol.h" |
35 | | |
36 | | #include <cmath> |
37 | | #include <cstddef> |
38 | | #include <stdexcept> |
39 | | #include <vector> |
40 | | |
41 | | #if defined(_WIN32) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) |
42 | | # pragma warning( disable: 4251) |
43 | | #endif |
44 | | namespace p2t { |
45 | | |
46 | | struct Edge; |
47 | | |
48 | | struct P2T_DLL_SYMBOL Point { |
49 | | |
50 | | double x, y; |
51 | | |
52 | | /// Default constructor does nothing (for performance). |
53 | | Point() |
54 | 0 | { |
55 | 0 | x = 0.0; |
56 | 0 | y = 0.0; |
57 | 0 | } |
58 | | |
59 | | /// The edges this point constitutes an upper ending point |
60 | | std::vector<Edge*> edge_list; |
61 | | |
62 | | /// Construct using coordinates. |
63 | | Point(double x, double y); |
64 | | |
65 | | /// Set this point to all zeros. |
66 | | void set_zero() |
67 | 0 | { |
68 | 0 | x = 0.0; |
69 | 0 | y = 0.0; |
70 | 0 | } |
71 | | |
72 | | /// Set this point to some specified coordinates. |
73 | | void set(double x_, double y_) |
74 | 0 | { |
75 | 0 | x = x_; |
76 | 0 | y = y_; |
77 | 0 | } |
78 | | |
79 | | /// Negate this point. |
80 | | Point operator -() const |
81 | 0 | { |
82 | 0 | Point v; |
83 | 0 | v.set(-x, -y); |
84 | 0 | return v; |
85 | 0 | } |
86 | | |
87 | | /// Add a point to this point. |
88 | | void operator +=(const Point& v) |
89 | 0 | { |
90 | 0 | x += v.x; |
91 | 0 | y += v.y; |
92 | 0 | } |
93 | | |
94 | | /// Subtract a point from this point. |
95 | | void operator -=(const Point& v) |
96 | 0 | { |
97 | 0 | x -= v.x; |
98 | 0 | y -= v.y; |
99 | 0 | } |
100 | | |
101 | | /// Multiply this point by a scalar. |
102 | | void operator *=(double a) |
103 | 0 | { |
104 | 0 | x *= a; |
105 | 0 | y *= a; |
106 | 0 | } |
107 | | |
108 | | /// Get the length of this point (the norm). |
109 | | double Length() const |
110 | 0 | { |
111 | 0 | return sqrt(x * x + y * y); |
112 | 0 | } |
113 | | |
114 | | /// Convert this point into a unit point. Returns the Length. |
115 | | double Normalize() |
116 | 0 | { |
117 | 0 | const double len = Length(); |
118 | 0 | x /= len; |
119 | 0 | y /= len; |
120 | 0 | return len; |
121 | 0 | } |
122 | | |
123 | | }; |
124 | | |
125 | | P2T_DLL_SYMBOL std::ostream& operator<<(std::ostream&, const Point&); |
126 | | |
127 | | // Represents a simple polygon's edge |
128 | | struct P2T_DLL_SYMBOL Edge { |
129 | | |
130 | | Point* p, *q; |
131 | | |
132 | | /// Constructor |
133 | 0 | Edge(Point& p1, Point& p2) : p(&p1), q(&p2) |
134 | 0 | { |
135 | 0 | if (p1.y > p2.y) { |
136 | 0 | q = &p1; |
137 | 0 | p = &p2; |
138 | 0 | } else if (p1.y == p2.y) { |
139 | 0 | if (p1.x > p2.x) { |
140 | 0 | q = &p1; |
141 | 0 | p = &p2; |
142 | 0 | } else if (p1.x == p2.x) { |
143 | | // Repeat points |
144 | 0 | throw std::runtime_error("Edge::Edge: p1 == p2"); |
145 | 0 | } |
146 | 0 | } |
147 | | |
148 | 0 | q->edge_list.push_back(this); |
149 | 0 | } |
150 | | }; |
151 | | |
152 | | // Triangle-based data structures are know to have better performance than quad-edge structures |
153 | | // See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator" |
154 | | // "Triangulations in CGAL" |
155 | | class P2T_DLL_SYMBOL Triangle { |
156 | | public: |
157 | | |
158 | | /// Constructor |
159 | | Triangle(Point& a, Point& b, Point& c); |
160 | | |
161 | | /// Flags to determine if an edge is a Constrained edge |
162 | | bool constrained_edge[3]; |
163 | | /// Flags to determine if an edge is a Delauney edge |
164 | | bool delaunay_edge[3]; |
165 | | |
166 | | Point* GetPoint(int index); |
167 | | Point* PointCW(const Point& point); |
168 | | Point* PointCCW(const Point& point); |
169 | | Point* OppositePoint(Triangle& t, const Point& p); |
170 | | |
171 | | Triangle* GetNeighbor(int index); |
172 | | void MarkNeighbor(Point* p1, Point* p2, Triangle* t); |
173 | | void MarkNeighbor(Triangle& t); |
174 | | |
175 | | void MarkConstrainedEdge(int index); |
176 | | void MarkConstrainedEdge(Edge& edge); |
177 | | void MarkConstrainedEdge(Point* p, Point* q); |
178 | | |
179 | | int Index(const Point* p); |
180 | | int EdgeIndex(const Point* p1, const Point* p2); |
181 | | |
182 | | Triangle* NeighborAcross(const Point& point); |
183 | | Triangle* NeighborCW(const Point& point); |
184 | | Triangle* NeighborCCW(const Point& point); |
185 | | bool GetConstrainedEdgeCCW(const Point& p); |
186 | | bool GetConstrainedEdgeCW(const Point& p); |
187 | | void SetConstrainedEdgeCCW(const Point& p, bool ce); |
188 | | void SetConstrainedEdgeCW(const Point& p, bool ce); |
189 | | bool GetDelunayEdgeCCW(const Point& p); |
190 | | bool GetDelunayEdgeCW(const Point& p); |
191 | | void SetDelunayEdgeCCW(const Point& p, bool e); |
192 | | void SetDelunayEdgeCW(const Point& p, bool e); |
193 | | |
194 | | bool Contains(const Point* p); |
195 | | bool Contains(const Edge& e); |
196 | | bool Contains(const Point* p, const Point* q); |
197 | | void Legalize(Point& point); |
198 | | void Legalize(Point& opoint, Point& npoint); |
199 | | /** |
200 | | * Clears all references to all other triangles and points |
201 | | */ |
202 | | void Clear(); |
203 | | void ClearNeighbor(const Triangle *triangle); |
204 | | void ClearNeighbors(); |
205 | | void ClearDelunayEdges(); |
206 | | |
207 | | inline bool IsInterior(); |
208 | | inline void IsInterior(bool b); |
209 | | |
210 | | void DebugPrint(); |
211 | | |
212 | | bool CircumcicleContains(const Point&) const; |
213 | | |
214 | | private: |
215 | | |
216 | | bool IsCounterClockwise() const; |
217 | | |
218 | | /// Triangle points |
219 | | Point* points_[3]; |
220 | | /// Neighbor list |
221 | | Triangle* neighbors_[3]; |
222 | | |
223 | | /// Has this triangle been marked as an interior triangle? |
224 | | bool interior_; |
225 | | }; |
226 | | |
227 | | inline bool cmp(const Point* a, const Point* b) |
228 | 0 | { |
229 | 0 | if (a->y < b->y) { |
230 | 0 | return true; |
231 | 0 | } else if (a->y == b->y) { |
232 | | // Make sure q is point with greater x value |
233 | 0 | if (a->x < b->x) { |
234 | 0 | return true; |
235 | 0 | } |
236 | 0 | } |
237 | 0 | return false; |
238 | 0 | } |
239 | | |
240 | | /// Add two points_ component-wise. |
241 | | inline Point operator +(const Point& a, const Point& b) |
242 | 0 | { |
243 | 0 | return Point(a.x + b.x, a.y + b.y); |
244 | 0 | } |
245 | | |
246 | | /// Subtract two points_ component-wise. |
247 | | inline Point operator -(const Point& a, const Point& b) |
248 | 0 | { |
249 | 0 | return Point(a.x - b.x, a.y - b.y); |
250 | 0 | } |
251 | | |
252 | | /// Multiply point by scalar |
253 | | inline Point operator *(double s, const Point& a) |
254 | 0 | { |
255 | 0 | return Point(s * a.x, s * a.y); |
256 | 0 | } |
257 | | |
258 | | inline bool operator ==(const Point& a, const Point& b) |
259 | 0 | { |
260 | 0 | return a.x == b.x && a.y == b.y; |
261 | 0 | } |
262 | | |
263 | | inline bool operator !=(const Point& a, const Point& b) |
264 | 0 | { |
265 | 0 | return !(a.x == b.x) || !(a.y == b.y); |
266 | 0 | } |
267 | | |
268 | | /// Peform the dot product on two vectors. |
269 | | inline double Dot(const Point& a, const Point& b) |
270 | 0 | { |
271 | 0 | return a.x * b.x + a.y * b.y; |
272 | 0 | } |
273 | | |
274 | | /// Perform the cross product on two vectors. In 2D this produces a scalar. |
275 | | inline double Cross(const Point& a, const Point& b) |
276 | 0 | { |
277 | 0 | return a.x * b.y - a.y * b.x; |
278 | 0 | } |
279 | | |
280 | | /// Perform the cross product on a point and a scalar. In 2D this produces |
281 | | /// a point. |
282 | | inline Point Cross(const Point& a, double s) |
283 | 0 | { |
284 | 0 | return Point(s * a.y, -s * a.x); |
285 | 0 | } |
286 | | |
287 | | /// Perform the cross product on a scalar and a point. In 2D this produces |
288 | | /// a point. |
289 | | inline Point Cross(double s, const Point& a) |
290 | 0 | { |
291 | 0 | return Point(-s * a.y, s * a.x); |
292 | 0 | } |
293 | | |
294 | | inline Point* Triangle::GetPoint(int index) |
295 | 0 | { |
296 | 0 | return points_[index]; |
297 | 0 | } |
298 | | |
299 | | inline Triangle* Triangle::GetNeighbor(int index) |
300 | 0 | { |
301 | 0 | return neighbors_[index]; |
302 | 0 | } |
303 | | |
304 | | inline bool Triangle::Contains(const Point* p) |
305 | 0 | { |
306 | 0 | return p == points_[0] || p == points_[1] || p == points_[2]; |
307 | 0 | } |
308 | | |
309 | | inline bool Triangle::Contains(const Edge& e) |
310 | 0 | { |
311 | 0 | return Contains(e.p) && Contains(e.q); |
312 | 0 | } |
313 | | |
314 | | inline bool Triangle::Contains(const Point* p, const Point* q) |
315 | 0 | { |
316 | 0 | return Contains(p) && Contains(q); |
317 | 0 | } |
318 | | |
319 | | inline bool Triangle::IsInterior() |
320 | 0 | { |
321 | 0 | return interior_; |
322 | 0 | } |
323 | | |
324 | | inline void Triangle::IsInterior(bool b) |
325 | 0 | { |
326 | 0 | interior_ = b; |
327 | 0 | } |
328 | | |
329 | | /// Is this set a valid delaunay triangulation? |
330 | | P2T_DLL_SYMBOL bool IsDelaunay(const std::vector<p2t::Triangle*>&); |
331 | | |
332 | | } |