CDT  1.4.5
C++ library for constrained Delaunay triangulation
Loading...
Searching...
No Matches
CDTUtils.h
Go to the documentation of this file.
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
9
10#ifndef CDT_obwOaxOTdAWcLNTlNnaq
11#define CDT_obwOaxOTdAWcLNTlNnaq
12
13#ifdef CDT_DONT_USE_BOOST_RTREE
14// CDT_DONT_USE_BOOST_RTREE was replaced with CDT_USE_BOOST
15typedef char CDT_DONT_USE_BOOST_RTREE__was__replaced__with__CDT_USE_BOOST[-1];
16#endif
17
18// #define CDT_USE_STRONG_TYPING // strong type checks on indices
19
20// check if c++11 is supported
21#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
22#define CDT_CXX11_IS_SUPPORTED
23#elif !defined(__cplusplus) && !defined(_MSC_VER)
25#endif
26
27// 'noexcept' is only available since c++11 and its c++98 spelling 'throw()'
28// is in turn removed in c++20
29#ifdef CDT_CXX11_IS_SUPPORTED
31#define CDT_NOEXCEPT noexcept
32#else
33#define CDT_NOEXCEPT throw()
34#endif
35
36// Functions defined outside the class need to be 'inline'
37// if CDT is configured to be used as header-only library:
38// single-definition rule is violated otherwise
39#ifdef CDT_USE_AS_COMPILED_LIBRARY
40#define CDT_INLINE_IF_HEADER_ONLY
41#include "cdt_export.h" // automatically generated by CMake
42#else
47#define CDT_INLINE_IF_HEADER_ONLY inline
49#define CDT_EXPORT
50#endif
51
52#include <algorithm>
53#include <cassert>
54#include <cmath>
55#include <limits>
56#include <vector>
57
58#ifdef CDT_USE_STRONG_TYPING
59#include <boost/serialization/strong_typedef.hpp>
60#endif
61
62// use fall-backs for c++11 features
63#ifdef CDT_CXX11_IS_SUPPORTED
64
65#include <array>
66#include <functional>
67#include <string>
68#include <tuple>
69#include <unordered_map>
70#include <unordered_set>
71
72#ifdef CDT_DISABLE_EXCEPTIONS
73#include <exception>
74#endif
75
76namespace CDT
77{
78using std::array;
79using std::get;
80using std::make_tuple;
81using std::tie;
82using std::to_string;
83using std::tuple;
84using std::unordered_map;
85using std::unordered_set;
86} // namespace CDT
87
88#else
89#include <boost/array.hpp>
90#include <boost/functional/hash.hpp>
91#include <boost/lexical_cast.hpp>
92#include <boost/tuple/tuple.hpp>
93#include <boost/unordered_map.hpp>
94#include <boost/unordered_set.hpp>
95namespace CDT
96{
97using boost::array;
98using boost::get;
99using boost::make_tuple;
100using boost::tie;
101using boost::tuple;
102using boost::unordered_map;
103using boost::unordered_set;
104
105template <typename T>
106std::string to_string(const T& value)
107{
108 return boost::lexical_cast<std::string>(value);
109}
110} // namespace CDT
111#endif
112
113namespace CDT
114{
115
116template <typename T>
117void handleException(const T& error)
118{
119#ifdef CDT_DISABLE_EXCEPTIONS
120 std::terminate();
121#else
122 throw error;
123#endif
124}
125
127template <typename T>
128array<T, 3> arr3(const T& v0, const T& v1, const T& v2)
129{
130 const array<T, 3> out = {v0, v1, v2};
131 return out;
132}
133
135template <typename T>
136array<T, 3> arr3(const T& v)
137{
138 const array<T, 3> out = {v, v, v};
139 return out;
140}
141
143template <typename T>
144struct CDT_EXPORT V2d
145{
146 T x;
147 T y;
148
151 : x(T(0))
152 , y(T(0))
153 {}
154
156 V2d(const T x, const T y)
157 : x(x)
158 , y(y)
159 {}
160};
161
163template <typename T>
164const T& getX_V2d(const V2d<T>& v)
165{
166 return v.x;
167}
168
170template <typename T>
171const T& getY_V2d(const V2d<T>& v)
172{
173 return v.y;
174}
175
177template <typename T>
178bool operator==(const CDT::V2d<T>& lhs, const CDT::V2d<T>& rhs)
179{
180 return lhs.x == rhs.x && lhs.y == rhs.y;
181}
182
184template <typename T>
185bool operator!=(const CDT::V2d<T>& lhs, const CDT::V2d<T>& rhs)
186{
187 return !(lhs == rhs);
188}
189
190#ifdef CDT_USE_64_BIT_INDEX_TYPE
191typedef unsigned long long IndexSizeType;
192#else
193typedef unsigned int IndexSizeType;
194#endif
195
196#ifdef CDT_USE_STRONG_TYPING
202BOOST_STRONG_TYPEDEF(IndexSizeType, TriInd);
203#else
205typedef unsigned char Index;
207typedef IndexSizeType VertInd;
209typedef IndexSizeType TriInd;
210#endif
211
213const static Index invalidIndex(std::numeric_limits<Index>::max());
215const static IndexSizeType
216 invalidIndexSizeType(std::numeric_limits<IndexSizeType>::max());
219const static IndexSizeType nSuperTriangleVertices(3);
221const static TriInd noNeighbor(invalidIndexSizeType);
223const static VertInd noVertex(invalidIndexSizeType);
224
225typedef std::vector<TriInd> TriIndVec;
226typedef array<VertInd, 3> VerticesArr3;
227typedef array<TriInd, 3> NeighborsArr3;
228
230template <typename T>
231struct CDT_EXPORT Box2d
232{
235
238 : min(std::numeric_limits<T>::max(), std::numeric_limits<T>::max())
239 , max(-std::numeric_limits<T>::max(), -std::numeric_limits<T>::max())
240 {}
241
244 {
245 return envelopPoint(p.x, p.y);
246 }
247
249 Box2d<T>& envelopPoint(const T x, const T y)
250 {
251 min.x = std::min(x, min.x);
252 max.x = std::max(x, max.x);
253 min.y = std::min(y, min.y);
254 max.y = std::max(y, max.y);
255 return *this;
256 }
257
259 template <
260 typename TVertexIter,
261 typename TGetVertexCoordX,
262 typename TGetVertexCoordY>
264 TVertexIter first,
265 TVertexIter last,
266 TGetVertexCoordX getX,
267 TGetVertexCoordY getY)
268 {
269 for(; first != last; ++first)
270 {
271 envelopPoint(getX(*first), getY(*first));
272 }
273 return *this;
274 }
275
277 Box2d<T>& envelopPoints(const std::vector<V2d<T> >& vertices)
278 {
279 return envelopPoints(
280 vertices.begin(), vertices.end(), getX_V2d<T>, getY_V2d<T>);
281 }
282};
283
286struct CDT_EXPORT Edge
287{
289 Edge(const VertInd iV1, const VertInd iV2)
290 : m_vertices(
291 iV1 < iV2 ? std::make_pair(iV1, iV2) : std::make_pair(iV2, iV1))
292 {}
293
295 bool operator==(const Edge& other) const
296 {
297 return m_vertices == other.m_vertices;
298 }
299
301 bool operator!=(const Edge& other) const
302 {
303 return !(this->operator==(other));
304 }
305
307 VertInd v1() const
308 {
309 return m_vertices.first;
310 }
311
313 VertInd v2() const
314 {
315 return m_vertices.second;
316 }
317
319 const std::pair<VertInd, VertInd>& verts() const
320 {
321 return m_vertices;
322 }
323
324private:
325 std::pair<VertInd, VertInd> m_vertices;
326};
327
329inline VertInd edge_get_v1(const Edge& e)
330{
331 return e.v1();
332}
333
335inline VertInd edge_get_v2(const Edge& e)
336{
337 return e.v2();
338}
339
342{
343 return Edge(iV1, iV2);
344}
345
346typedef std::vector<Edge> EdgeVec;
347typedef unordered_set<Edge> EdgeUSet;
348typedef unordered_set<TriInd> TriIndUSet;
349typedef unordered_map<TriInd, TriInd> TriIndUMap;
350
352/*
353 * v3
354 * /\
355 * n3/ \n2
356 * /____\
357 * v1 n1 v2
358 */
359struct CDT_EXPORT Triangle
360{
363
366 : vertices(arr3(noVertex))
367 , neighbors(arr3(noNeighbor))
368 {}
369
375
378 std::pair<TriInd, VertInd> next(const VertInd i) const
379 {
380 assert(vertices[0] == i || vertices[1] == i || vertices[2] == i);
381 if(vertices[0] == i)
382 {
383 return std::make_pair(neighbors[0], vertices[1]);
384 }
385 if(vertices[1] == i)
386 {
387 return std::make_pair(neighbors[1], vertices[2]);
388 }
389 return std::make_pair(neighbors[2], vertices[0]);
390 }
391
394 std::pair<TriInd, VertInd> prev(const VertInd i) const
395 {
396 assert(vertices[0] == i || vertices[1] == i || vertices[2] == i);
397 if(vertices[0] == i)
398 return std::make_pair(neighbors[2], vertices[2]);
399 if(vertices[1] == i)
400 return std::make_pair(neighbors[0], vertices[0]);
401 return std::make_pair(neighbors[1], vertices[1]);
402 }
403
405 bool containsVertex(const VertInd i) const
406 {
407 return std::find(vertices.begin(), vertices.end(), i) != vertices.end();
408 }
409};
410
411typedef std::vector<Triangle> TriangleVec;
412
414CDT_EXPORT Index ccw(Index i);
415
417CDT_EXPORT Index cw(Index i);
418
420struct CDT_EXPORT PtTriLocation
421{
423 enum Enum
424 {
425 Inside,
426 Outside,
427 OnEdge1,
428 OnEdge2,
429 OnEdge3,
430 OnVertex,
431 };
432};
433
435CDT_EXPORT bool isOnEdge(PtTriLocation::Enum location);
436
439CDT_EXPORT Index edgeNeighbor(PtTriLocation::Enum location);
440
442struct CDT_EXPORT PtLineLocation
443{
445 enum Enum
446 {
447 Left,
448 Right,
449 OnLine,
450 };
451};
452
454template <typename T>
455CDT_EXPORT T orient2D(const V2d<T>& p, const V2d<T>& v1, const V2d<T>& v2);
456
458template <typename T>
460 const V2d<T>& p,
461 const V2d<T>& v1,
462 const V2d<T>& v2,
463 T orientationTolerance = T(0));
464
466template <typename T>
467CDT_EXPORT PtLineLocation::Enum
468classifyOrientation(T orientation, T orientationTolerance = T(0));
469
471template <typename T>
473 const V2d<T>& p,
474 const V2d<T>& v1,
475 const V2d<T>& v2,
476 const V2d<T>& v3);
477
479CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoNbr(Index vertIndex);
480
482CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoVrt(Index neighborIndex);
483
485CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
486opposedTriangleInd(const VerticesArr3& vv, VertInd iVert);
487
489CDT_INLINE_IF_HEADER_ONLY Index
490edgeNeighborInd(const VerticesArr3& vv, VertInd iVedge1, VertInd iVedge2);
491
493CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
494opposedVertexInd(const NeighborsArr3& nn, TriInd iTopo);
495
497CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index
498vertexInd(const VerticesArr3& vv, VertInd iV);
499
501CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY TriInd
502opposedTriangle(const Triangle& tri, VertInd iVert);
503
505CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY TriInd
506edgeNeighbor(const Triangle& tri, VertInd iVedge1, VertInd iVedge2);
507
509CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY VertInd
510opposedVertex(const Triangle& tri, TriInd iTopo);
511
513template <typename T>
514CDT_EXPORT bool isInCircumcircle(
515 const V2d<T>& p,
516 const V2d<T>& v1,
517 const V2d<T>& v2,
518 const V2d<T>& v3);
519
521CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY bool
522verticesShareEdge(const TriIndVec& aTris, const TriIndVec& bTris);
523
525template <typename T>
526CDT_EXPORT T distance(const V2d<T>& a, const V2d<T>& b);
527
529template <typename T>
530CDT_EXPORT T distanceSquared(const V2d<T>& a, const V2d<T>& b);
531
533CDT_INLINE_IF_HEADER_ONLY bool touchesSuperTriangle(const Triangle& t);
534} // namespace CDT
535
536#ifndef CDT_USE_AS_COMPILED_LIBRARY
537#include "CDTUtils.hpp"
538#endif
539
540//*****************************************************************************
541// Specialize hash functions
542//*****************************************************************************
543#ifdef CDT_CXX11_IS_SUPPORTED
544namespace std
545#else
546namespace boost
547#endif
548{
549
550#ifdef CDT_USE_STRONG_TYPING
551
553template <>
554struct hash<CDT::VertInd>
555{
557 std::size_t operator()(const CDT::VertInd& vi) const
558 {
559 return std::hash<std::size_t>()(vi.t);
560 }
561};
562
564template <>
565struct hash<CDT::TriInd>
566{
568 std::size_t operator()(const CDT::TriInd& vi) const
569 {
570 return std::hash<std::size_t>()(vi.t);
571 }
572};
573
574#endif // CDT_USE_STRONG_TYPING
575
577template <>
578struct hash<CDT::Edge>
579{
581 std::size_t operator()(const CDT::Edge& e) const
582 {
583 return hashEdge(e);
584 }
585
586private:
587 static void hashCombine(std::size_t& seed, const CDT::VertInd& key)
588 {
589#ifdef CDT_CXX11_IS_SUPPORTED
590 typedef std::hash<CDT::VertInd> Hasher;
591#else
592 typedef boost::hash<CDT::VertInd> Hasher;
593#endif
594 seed ^= Hasher()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
595 }
596
597 static std::size_t hashEdge(const CDT::Edge& e)
598 {
599 std::size_t seed(0);
600 hashCombine(seed, e.v1());
601 hashCombine(seed, e.v2());
602 return seed;
603 }
604};
605
606} // namespace std/boost
607
608#endif // header guard
char couldnt_parse_cxx_standard[-1]
Error: couldn't parse standard.
Definition CDTUtils.h:24
Utilities and helpers - implementation.
Namespace containing triangulation functionality.
std::vector< Edge > EdgeVec
Vector of edges.
Definition CDTUtils.h:346
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY VertInd opposedVertex(const Triangle &tri, TriInd iTopo)
Given two triangles, return vertex of first triangle opposed to the second.
Definition CDTUtils.hpp:203
unordered_set< Edge > EdgeUSet
Hash table of edges.
Definition CDTUtils.h:347
VertInd edge_get_v2(const Edge &e)
Get edge second vertex.
Definition CDTUtils.h:335
std::vector< TriInd > TriIndVec
Vector of triangle indices.
Definition CDTUtils.h:225
CDT_INLINE_IF_HEADER_ONLY Index edgeNeighborInd(const VerticesArr3 &vv, VertInd iVedge1, VertInd iVedge2)
Index of triangle's neighbor opposed to an edge.
Definition CDTUtils.hpp:141
VertInd edge_get_v1(const Edge &e)
Get edge first vertex.
Definition CDTUtils.h:329
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opposedTriangleInd(const VerticesArr3 &vv, VertInd iVert)
Index of triangle's neighbor opposed to a vertex.
Definition CDTUtils.hpp:131
CDT_EXPORT PtLineLocation::Enum classifyOrientation(T orientation, T orientationTolerance=T(0))
Classify value of orient2d predicate.
Definition CDTUtils.hpp:62
array< TriInd, 3 > NeighborsArr3
array of three neighbors
Definition CDTUtils.h:227
CDT_EXPORT T distance(const V2d< T > &a, const V2d< T > &b)
Distance between two 2D points.
Definition CDTUtils.hpp:250
IndexSizeType VertInd
Vertex index.
Definition CDTUtils.h:207
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY bool verticesShareEdge(const TriIndVec &aTris, const TriIndVec &bTris)
Test if two vertices share at least one common triangle.
Definition CDTUtils.hpp:227
CDT_EXPORT Index cw(Index i)
Advance vertex or neighbor index clockwise.
Definition CDTUtils.hpp:26
array< VertInd, 3 > VerticesArr3
array of three vertex indices
Definition CDTUtils.h:226
CDT_INLINE_IF_HEADER_ONLY bool touchesSuperTriangle(const Triangle &t)
Check if any of triangle's vertices belongs to a super-triangle.
Definition CDTUtils.hpp:261
array< T, 3 > arr3(const T &v0, const T &v1, const T &v2)
Needed for c++03 compatibility (no uniform initialization available)
Definition CDTUtils.h:128
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoVrt(Index neighborIndex)
Opposed vertex index from neighbor index.
Definition CDTUtils.hpp:117
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opoNbr(Index vertIndex)
Opposed neighbor index from vertex index.
Definition CDTUtils.hpp:104
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index vertexInd(const VerticesArr3 &vv, VertInd iV)
If triangle has a given vertex return vertex-index.
Definition CDTUtils.hpp:186
CDT_EXPORT T orient2D(const V2d< T > &p, const V2d< T > &v1, const V2d< T > &v2)
Orient p against line v1-v2 2D: robust geometric predicate.
Definition CDTUtils.hpp:45
CDT_EXPORT PtLineLocation::Enum locatePointLine(const V2d< T > &p, const V2d< T > &v1, const V2d< T > &v2, T orientationTolerance=T(0))
Check if point lies to the left of, to the right of, or on a line.
Definition CDTUtils.hpp:51
CDT_EXPORT T distanceSquared(const V2d< T > &a, const V2d< T > &b)
Squared distance between two 2D points.
Definition CDTUtils.hpp:256
unordered_set< TriInd > TriIndUSet
Hash table of triangles.
Definition CDTUtils.h:348
CDT_EXPORT Index ccw(Index i)
Advance vertex or neighbor index counter-clockwise.
Definition CDTUtils.hpp:21
Edge edge_make(VertInd iV1, VertInd iV2)
Get edge second vertex.
Definition CDTUtils.h:341
bool operator!=(const CDT::V2d< T > &lhs, const CDT::V2d< T > &rhs)
If two 2D vectors are not exactly equal.
Definition CDTUtils.h:185
CDT_EXPORT Index edgeNeighbor(PtTriLocation::Enum location)
Neighbor index from a on-edge location.
Definition CDTUtils.hpp:38
unordered_map< TriInd, TriInd > TriIndUMap
Triangle hash map.
Definition CDTUtils.h:349
const T & getX_V2d(const V2d< T > &v)
X- coordinate getter for V2d.
Definition CDTUtils.h:164
bool operator==(const CDT::V2d< T > &lhs, const CDT::V2d< T > &rhs)
If two 2D vectors are exactly equal.
Definition CDTUtils.h:178
unsigned char Index
Index in triangle.
Definition CDTUtils.h:205
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY TriInd opposedTriangle(const Triangle &tri, VertInd iVert)
Given triangle and a vertex find opposed triangle.
Definition CDTUtils.hpp:197
CDT_EXPORT bool isInCircumcircle(const V2d< T > &p, const V2d< T > &v1, const V2d< T > &v2, const V2d< T > &v3)
Test if point lies in a circumscribed circle of a triangle.
Definition CDTUtils.hpp:216
CDT_EXPORT bool isOnEdge(PtTriLocation::Enum location)
Check if location is classified as on any of three edges.
Definition CDTUtils.hpp:31
IndexSizeType TriInd
Triangle index.
Definition CDTUtils.h:209
CDT_EXPORT PtTriLocation::Enum locatePointTriangle(const V2d< T > &p, const V2d< T > &v1, const V2d< T > &v2, const V2d< T > &v3)
Check if point a lies inside of, outside of, or on an edge of a triangle.
Definition CDTUtils.hpp:72
std::vector< Triangle > TriangleVec
Vector of triangles.
Definition CDTUtils.h:411
BOOST_STRONG_TYPEDEF(unsigned char, Index)
Index in triangle.
CDT_EXPORT CDT_INLINE_IF_HEADER_ONLY Index opposedVertexInd(const NeighborsArr3 &nn, TriInd iTopo)
Index of triangle's vertex opposed to a triangle.
Definition CDTUtils.hpp:175
const T & getY_V2d(const V2d< T > &v)
Y-coordinate getter for V2d.
Definition CDTUtils.h:171
Box2d< T > & envelopPoint(const T x, const T y)
Envelop box around a point with given coordinates.
Definition CDTUtils.h:249
Box2d()
Box that doesn't contain any point.
Definition CDTUtils.h:237
V2d< T > max
max box corner
Definition CDTUtils.h:234
Box2d< T > & envelopPoint(const V2d< T > &p)
Envelop box around a point.
Definition CDTUtils.h:243
Box2d< T > & envelopPoints(TVertexIter first, TVertexIter last, TGetVertexCoordX getX, TGetVertexCoordY getY)
Envelop box around a collection of custom points.
Definition CDTUtils.h:263
V2d< T > min
min box corner
Definition CDTUtils.h:233
Box2d< T > & envelopPoints(const std::vector< V2d< T > > &vertices)
Envelop box around a collection of points.
Definition CDTUtils.h:277
Edge connecting two vertices: vertex with smaller index is always first.
Definition CDTUtils.h:287
const std::pair< VertInd, VertInd > & verts() const
Edges' vertices.
Definition CDTUtils.h:319
bool operator==(const Edge &other) const
Equals operator.
Definition CDTUtils.h:295
VertInd v1() const
V1 getter.
Definition CDTUtils.h:307
bool operator!=(const Edge &other) const
Not-equals operator.
Definition CDTUtils.h:301
Edge(const VertInd iV1, const VertInd iV2)
Constructor.
Definition CDTUtils.h:289
VertInd v2() const
V2 getter.
Definition CDTUtils.h:313
Relative location of point to a line.
Definition CDTUtils.h:443
Location of point on a triangle.
Definition CDTUtils.h:421
VerticesArr3 vertices
triangle's three vertices
Definition CDTUtils.h:361
std::pair< TriInd, VertInd > prev(const VertInd i) const
Previous triangle adjacent to a vertex (counter-clockwise)
Definition CDTUtils.h:394
NeighborsArr3 neighbors
triangle's three neighbors
Definition CDTUtils.h:362
bool containsVertex(const VertInd i) const
Check if triangle contains a vertex.
Definition CDTUtils.h:405
Triangle(const VerticesArr3 &vertices, const NeighborsArr3 &neighbors)
Triangle with given vertices and neighbors.
Definition CDTUtils.h:371
Triangle()
Triangle with no vertices and no neighbors.
Definition CDTUtils.h:365
std::pair< TriInd, VertInd > next(const VertInd i) const
Next triangle adjacent to a vertex (clockwise)
Definition CDTUtils.h:378
2D vector
Definition CDTUtils.h:145
V2d(const T x, const T y)
Vertex with given coordinates.
Definition CDTUtils.h:156
V2d()
Vertex with zero coordinates.
Definition CDTUtils.h:150
std::size_t operator()(const CDT::Edge &e) const
Hash operator.
Definition CDTUtils.h:581
std::size_t operator()(const CDT::TriInd &vi) const
Hash operator.
Definition CDTUtils.h:568
std::size_t operator()(const CDT::VertInd &vi) const
Hash operator.
Definition CDTUtils.h:557