shapes.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 guard
  32. #ifndef SHAPES_H
  33. #define SHAPES_H
  34. #include <vector>
  35. #include <cstddef>
  36. #include <assert.h>
  37. #include <cmath>
  38. namespace p2t {
  39. struct Edge;
  40. struct Point {
  41. double x, y;
  42. /// Default constructor does nothing (for performance).
  43. Point()
  44. {
  45. x = 0.0;
  46. y = 0.0;
  47. }
  48. /// The edges this point constitutes an upper ending point
  49. std::vector<Edge*> edge_list;
  50. /// Construct using coordinates.
  51. Point(double x, double y) : x(x), y(y) {}
  52. /// Set this point to all zeros.
  53. void set_zero()
  54. {
  55. x = 0.0;
  56. y = 0.0;
  57. }
  58. /// Set this point to some specified coordinates.
  59. void set(double x_, double y_)
  60. {
  61. x = x_;
  62. y = y_;
  63. }
  64. /// Negate this point.
  65. Point operator -() const
  66. {
  67. Point v;
  68. v.set(-x, -y);
  69. return v;
  70. }
  71. /// Add a point to this point.
  72. void operator +=(const Point& v)
  73. {
  74. x += v.x;
  75. y += v.y;
  76. }
  77. /// Subtract a point from this point.
  78. void operator -=(const Point& v)
  79. {
  80. x -= v.x;
  81. y -= v.y;
  82. }
  83. /// Multiply this point by a scalar.
  84. void operator *=(double a)
  85. {
  86. x *= a;
  87. y *= a;
  88. }
  89. /// Get the length of this point (the norm).
  90. double Length() const
  91. {
  92. return sqrt(x * x + y * y);
  93. }
  94. /// Convert this point into a unit point. Returns the Length.
  95. double Normalize()
  96. {
  97. const double len = Length();
  98. x /= len;
  99. y /= len;
  100. return len;
  101. }
  102. };
  103. // Represents a simple polygon's edge
  104. struct Edge {
  105. Point* p, *q;
  106. /// Constructor
  107. Edge(Point& p1, Point& p2) : p(&p1), q(&p2)
  108. {
  109. if (p1.y > p2.y) {
  110. q = &p1;
  111. p = &p2;
  112. } else if (p1.y == p2.y) {
  113. if (p1.x > p2.x) {
  114. q = &p1;
  115. p = &p2;
  116. } else if (p1.x == p2.x) {
  117. // Repeat points
  118. assert(false);
  119. }
  120. }
  121. q->edge_list.push_back(this);
  122. }
  123. };
  124. // Triangle-based data structures are know to have better performance than quad-edge structures
  125. // See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
  126. // "Triangulations in CGAL"
  127. class Triangle {
  128. public:
  129. /// Constructor
  130. Triangle(Point& a, Point& b, Point& c);
  131. /// Flags to determine if an edge is a Constrained edge
  132. bool constrained_edge[3];
  133. /// Flags to determine if an edge is a Delauney edge
  134. bool delaunay_edge[3];
  135. Point* GetPoint(int index);
  136. Point* PointCW(const Point& point);
  137. Point* PointCCW(const Point& point);
  138. Point* OppositePoint(Triangle& t, const Point& p);
  139. Triangle* GetNeighbor(int index);
  140. void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
  141. void MarkNeighbor(Triangle& t);
  142. void MarkConstrainedEdge(int index);
  143. void MarkConstrainedEdge(Edge& edge);
  144. void MarkConstrainedEdge(Point* p, Point* q);
  145. int Index(const Point* p);
  146. int EdgeIndex(const Point* p1, const Point* p2);
  147. Triangle* NeighborCW(const Point& point);
  148. Triangle* NeighborCCW(const Point& point);
  149. bool GetConstrainedEdgeCCW(const Point& p);
  150. bool GetConstrainedEdgeCW(const Point& p);
  151. void SetConstrainedEdgeCCW(const Point& p, bool ce);
  152. void SetConstrainedEdgeCW(const Point& p, bool ce);
  153. bool GetDelunayEdgeCCW(const Point& p);
  154. bool GetDelunayEdgeCW(const Point& p);
  155. void SetDelunayEdgeCCW(const Point& p, bool e);
  156. void SetDelunayEdgeCW(const Point& p, bool e);
  157. bool Contains(const Point* p);
  158. bool Contains(const Edge& e);
  159. bool Contains(const Point* p, const Point* q);
  160. void Legalize(Point& point);
  161. void Legalize(Point& opoint, Point& npoint);
  162. /**
  163. * Clears all references to all other triangles and points
  164. */
  165. void Clear();
  166. void ClearNeighbor(const Triangle *triangle);
  167. void ClearNeighbors();
  168. void ClearDelunayEdges();
  169. inline bool IsInterior();
  170. inline void IsInterior(bool b);
  171. Triangle& NeighborAcross(const Point& opoint);
  172. void DebugPrint();
  173. private:
  174. /// Triangle points
  175. Point* points_[3];
  176. /// Neighbor list
  177. Triangle* neighbors_[3];
  178. /// Has this triangle been marked as an interior triangle?
  179. bool interior_;
  180. };
  181. inline bool cmp(const Point* a, const Point* b)
  182. {
  183. if (a->y < b->y) {
  184. return true;
  185. } else if (a->y == b->y) {
  186. // Make sure q is point with greater x value
  187. if (a->x < b->x) {
  188. return true;
  189. }
  190. }
  191. return false;
  192. }
  193. /// Add two points_ component-wise.
  194. inline Point operator +(const Point& a, const Point& b)
  195. {
  196. return Point(a.x + b.x, a.y + b.y);
  197. }
  198. /// Subtract two points_ component-wise.
  199. inline Point operator -(const Point& a, const Point& b)
  200. {
  201. return Point(a.x - b.x, a.y - b.y);
  202. }
  203. /// Multiply point by scalar
  204. inline Point operator *(double s, const Point& a)
  205. {
  206. return Point(s * a.x, s * a.y);
  207. }
  208. inline bool operator ==(const Point& a, const Point& b)
  209. {
  210. return a.x == b.x && a.y == b.y;
  211. }
  212. inline bool operator !=(const Point& a, const Point& b)
  213. {
  214. return !(a.x == b.x) && !(a.y == b.y);
  215. }
  216. /// Peform the dot product on two vectors.
  217. inline double Dot(const Point& a, const Point& b)
  218. {
  219. return a.x * b.x + a.y * b.y;
  220. }
  221. /// Perform the cross product on two vectors. In 2D this produces a scalar.
  222. inline double Cross(const Point& a, const Point& b)
  223. {
  224. return a.x * b.y - a.y * b.x;
  225. }
  226. /// Perform the cross product on a point and a scalar. In 2D this produces
  227. /// a point.
  228. inline Point Cross(const Point& a, double s)
  229. {
  230. return Point(s * a.y, -s * a.x);
  231. }
  232. /// Perform the cross product on a scalar and a point. In 2D this produces
  233. /// a point.
  234. inline Point Cross(double s, const Point& a)
  235. {
  236. return Point(-s * a.y, s * a.x);
  237. }
  238. inline Point* Triangle::GetPoint(int index)
  239. {
  240. return points_[index];
  241. }
  242. inline Triangle* Triangle::GetNeighbor(int index)
  243. {
  244. return neighbors_[index];
  245. }
  246. inline bool Triangle::Contains(const Point* p)
  247. {
  248. return p == points_[0] || p == points_[1] || p == points_[2];
  249. }
  250. inline bool Triangle::Contains(const Edge& e)
  251. {
  252. return Contains(e.p) && Contains(e.q);
  253. }
  254. inline bool Triangle::Contains(const Point* p, const Point* q)
  255. {
  256. return Contains(p) && Contains(q);
  257. }
  258. inline bool Triangle::IsInterior()
  259. {
  260. return interior_;
  261. }
  262. inline void Triangle::IsInterior(bool b)
  263. {
  264. interior_ = b;
  265. }
  266. }
  267. #endif