CUGL 1.3
Cornell University Game Library
CUDelaunayTriangulator.h
1 //
2 // CUDelaunayTriangulator.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module is a factory for a Delaunay triangulator. Delaunay support is
6 // not necessary for texture tesselation, but it is useful for applications
7 // like HRTF support that require certain geometric guaranties on the
8 // triangulation. In addition, this triangulator can be used to extract the
9 // Voronoi diagram as well.
10 //
11 // Because math objects are intended to be on the stack, we do not provide
12 // any shared pointer support in this class.
13 //
14 // This implementation is based on the Bowyer-Watson algorithm detailed at
15 //
16 // https://en.wikipedia.org/wiki/Bowyer–Watson_algorithm
17 //
18 // CUGL MIT License:
19 // This software is provided 'as-is', without any express or implied
20 // warranty. In no event will the authors be held liable for any damages
21 // arising from the use of this software.
22 //
23 // Permission is granted to anyone to use this software for any purpose,
24 // including commercial applications, and to alter it and redistribute it
25 // freely, subject to the following restrictions:
26 //
27 // 1. The origin of this software must not be misrepresented; you must not
28 // claim that you wrote the original software. If you use this software
29 // in a product, an acknowledgment in the product documentation would be
30 // appreciated but is not required.
31 //
32 // 2. Altered source versions must be plainly marked as such, and must not
33 // be misrepresented as being the original software.
34 //
35 // 3. This notice may not be removed or altered from any source distribution.
36 //
37 // Author: Walker White
38 // Version: 2/8/18
39 //
40 #ifndef __CU_DELAUNAY_TRIANGULATOR_H__
41 #define __CU_DELAUNAY_TRIANGULATOR_H__
42 
43 #include <cugl/math/CUPoly2.h>
44 #include <cugl/math/CUVec2.h>
45 #include <cugl/math/CUVec3.h>
46 #include <vector>
47 #include <unordered_map>
48 
49 namespace cugl {
50 
76 private:
77 #pragma mark Vertex
78 
85  class Vertex {
86  public:
88  Vec2 point;
90  Sint64 index;
91 
97  Vertex() : index(-1) {}
98 
105  Vertex(const Vec2& p, Sint64 i);
106 
116  bool operator==(const Vertex& v) const;
117 
127  bool operator!=(const Vertex& v) const { return !(*this == v); }
128 
139  bool operator<(const Vertex& v) const;
140 
151  bool operator> (const Vertex& v) const { return v < *this; }
152 
163  bool operator<=(const Vertex& v) const { return !(v < *this); }
164 
175  bool operator>=(const Vertex& v) const { return !(*this < v); }
176 
188  size_t operator()(const Vertex& v) const;
189 
190  };
191 
192 
193 #pragma mark -
194 #pragma mark Edge
195 
204  class Edge {
205  public:
207  Vertex v1;
209  Vertex v2;
210 
216  Edge() {}
217 
226  Edge(const Vertex& p1, const Vertex& p2);
227 
238  bool operator==(const Edge& t) const;
239 
250  bool operator!=(const Edge& t) const { return !(*this == t); }
251 
263  size_t operator()(const Edge& t) const;
264 
272  bool hasVertex(const Vec2& v) const;
273 
281  bool isDegenerate() const;
282  };
283 
284 #pragma mark -
285 #pragma mark Triangle
286 
295  class Triangle {
296  public:
298  Vertex v1;
300  Vertex v2;
302  Vertex v3;
304  bool isbad;
305 
311  Triangle() : isbad(true) {}
312 
322  Triangle(const Vertex& p1, const Vertex& p2, const Vertex& p3);
323 
334  bool operator==(const Triangle& t);
335 
346  bool operator!=(const Triangle& t) { return !(*this == t); }
347 
359  size_t operator()(const Triangle& t) const;
360 
368  bool hasVertex(const Vec2& v);
369 
377  Vec3 getBarycentric(const Vec2& point) const;
378 
384  Vec2 getCircleCenter() const;
385 
391  float getCircleRadius() const;
392 
400  bool containsInCircle(const Vec2& point) const;
401 
407  void setBad(bool bad);
408 
414  bool isBad() const;
415 
423  bool isDegenerate() const;
424 
432  bool isExterior() const;
433  };
434 
435 #pragma mark -
436 #pragma mark Delaunay
437 
438  std::vector<Vec2> _input;
440  std::vector<Triangle> _output;
442  std::vector<Vec2> _dual;
444  std::vector<std::vector<Edge>> _voronoi;
446  bool _calculated;
448  bool _dualated;
449 
450 public:
455 
464  DelaunayTriangulator(const std::vector<Vec2>& points) : _calculated(false) { _input = points; }
465 
477  DelaunayTriangulator(const Poly2& poly) : _calculated(false) { _input = poly._vertices; }
478 
483 
484 #pragma mark Initialization
485 
499  void set(const Poly2& poly) {
500  reset();
501  _input = poly._vertices;
502  }
503 
515  void set(const std::vector<Vec2>& points) {
516  reset();
517  _input = points;
518  }
519 
523  void reset() {
524  _calculated = false; _dualated = false;
525  _output.clear(); _voronoi.clear();
526  }
527 
534  void clear() {
535  _calculated = false; _dualated = false;
536  _input.clear(); _output.clear(); _voronoi.clear();
537  }
538 
539 #pragma mark Calculation
540 
546  void calculate();
547 
554  void calculateDual();
555 
556 #pragma mark Materialization
557 
571  std::vector<unsigned short> getTriangulation() const;
572 
586  size_t getTriangulation(std::vector<unsigned short>& buffer) const;
587 
600  Poly2 getPolygon() const;
601 
616  Poly2* getPolygon(Poly2* buffer) const;
617 
618 
619 #pragma mark Voronoization
620 
636  std::vector<Poly2> getVoronoi() const;
637 
653  Poly2 getVoronoiCell(size_t index) const;
654 
671  Poly2* getVoronoiCell(size_t index, Poly2* buffer) const;
672 
685  Poly2 getVoronoiFrame() const;
686 
702  Poly2* getVoronoiFrame(Poly2* buffer) const;
703 
704 #pragma mark -
705 #pragma mark Internal Data Generation
706 
711  Rect getBoundingBox() const;
712 
720  void computeDelaunay(const Rect& rect);
721 
729  void computeVoronoi(const Rect& rect);
730 
740  void sortCell(size_t index, const Rect& rect);
741 };
742 
743 
744 }
745 
746 #endif /* __CU_DELAUNAY_TRIANGULATOR_H__ */
cugl::DelaunayTriangulator::DelaunayTriangulator
DelaunayTriangulator(const Poly2 &poly)
Definition: CUDelaunayTriangulator.h:477
cugl::DelaunayTriangulator::getVoronoiCell
Poly2 getVoronoiCell(size_t index) const
cugl::DelaunayTriangulator::calculate
void calculate()
cugl::DelaunayTriangulator::getVoronoi
std::vector< Poly2 > getVoronoi() const
cugl::DelaunayTriangulator::sortCell
void sortCell(size_t index, const Rect &rect)
cugl::DelaunayTriangulator::getTriangulation
std::vector< unsigned short > getTriangulation() const
cugl::DelaunayTriangulator::getVoronoiFrame
Poly2 getVoronoiFrame() const
cugl::DelaunayTriangulator::clear
void clear()
Definition: CUDelaunayTriangulator.h:534
cugl::DelaunayTriangulator::getBoundingBox
Rect getBoundingBox() const
cugl::DelaunayTriangulator::computeDelaunay
void computeDelaunay(const Rect &rect)
cugl::DelaunayTriangulator::getPolygon
Poly2 getPolygon() const
cugl::DelaunayTriangulator::calculateDual
void calculateDual()
cugl::Rect
Definition: CURect.h:45
cugl::DelaunayTriangulator::reset
void reset()
Definition: CUDelaunayTriangulator.h:523
cugl::DelaunayTriangulator::set
void set(const Poly2 &poly)
Definition: CUDelaunayTriangulator.h:499
cugl::Poly2
Definition: CUPoly2.h:109
cugl::DelaunayTriangulator::set
void set(const std::vector< Vec2 > &points)
Definition: CUDelaunayTriangulator.h:515
cugl::Vec2
Definition: CUVec2.h:61
cugl::DelaunayTriangulator::DelaunayTriangulator
DelaunayTriangulator(const std::vector< Vec2 > &points)
Definition: CUDelaunayTriangulator.h:464
cugl::DelaunayTriangulator::computeVoronoi
void computeVoronoi(const Rect &rect)
cugl::DelaunayTriangulator
Definition: CUDelaunayTriangulator.h:75
cugl::DelaunayTriangulator::~DelaunayTriangulator
~DelaunayTriangulator()
Definition: CUDelaunayTriangulator.h:482
cugl::Vec3
Definition: CUVec3.h:61
cugl::DelaunayTriangulator::DelaunayTriangulator
DelaunayTriangulator()
Definition: CUDelaunayTriangulator.h:454