triangulator.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //Copyright (C) 2011 by Ivan Fratric
  2. //
  3. //Permission is hereby granted, free of charge, to any person obtaining a copy
  4. //of this software and associated documentation files (the "Software"), to deal
  5. //in the Software without restriction, including without limitation the rights
  6. //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. //copies of the Software, and to permit persons to whom the Software is
  8. //furnished to do so, subject to the following conditions:
  9. //
  10. //The above copyright notice and this permission notice shall be included in
  11. //all copies or substantial portions of the Software.
  12. //
  13. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. //THE SOFTWARE.
  20. #ifndef TRIANGULATOR_H
  21. #define TRIANGULATOR_H
  22. #include "core/list.h"
  23. #include "core/math/vector2.h"
  24. #include "core/set.h"
  25. //2D point structure
  26. #define TRIANGULATOR_CCW 1
  27. #define TRIANGULATOR_CW -1
  28. //Polygon implemented as an array of points with a 'hole' flag
  29. class TriangulatorPoly {
  30. protected:
  31. Vector2 *points;
  32. long numpoints;
  33. bool hole;
  34. public:
  35. //constructors/destructors
  36. TriangulatorPoly();
  37. ~TriangulatorPoly();
  38. TriangulatorPoly(const TriangulatorPoly &src);
  39. TriangulatorPoly& operator=(const TriangulatorPoly &src);
  40. //getters and setters
  41. long GetNumPoints() {
  42. return numpoints;
  43. }
  44. bool IsHole() {
  45. return hole;
  46. }
  47. void SetHole(bool hole) {
  48. this->hole = hole;
  49. }
  50. Vector2 &GetPoint(long i) {
  51. return points[i];
  52. }
  53. Vector2 *GetPoints() {
  54. return points;
  55. }
  56. Vector2& operator[] (int i) {
  57. return points[i];
  58. }
  59. //clears the polygon points
  60. void Clear();
  61. //inits the polygon with numpoints vertices
  62. void Init(long numpoints);
  63. //creates a triangle with points p1,p2,p3
  64. void Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3);
  65. //inverts the orfer of vertices
  66. void Invert();
  67. //returns the orientation of the polygon
  68. //possible values:
  69. // Triangulator_CCW : polygon vertices are in counter-clockwise order
  70. // Triangulator_CW : polygon vertices are in clockwise order
  71. // 0 : the polygon has no (measurable) area
  72. int GetOrientation();
  73. //sets the polygon orientation
  74. //orientation can be
  75. // Triangulator_CCW : sets vertices in counter-clockwise order
  76. // Triangulator_CW : sets vertices in clockwise order
  77. void SetOrientation(int orientation);
  78. };
  79. class TriangulatorPartition {
  80. protected:
  81. struct PartitionVertex {
  82. bool isActive;
  83. bool isConvex;
  84. bool isEar;
  85. Vector2 p;
  86. real_t angle;
  87. PartitionVertex *previous;
  88. PartitionVertex *next;
  89. };
  90. struct MonotoneVertex {
  91. Vector2 p;
  92. long previous;
  93. long next;
  94. };
  95. struct VertexSorter{
  96. mutable MonotoneVertex *vertices;
  97. bool operator() (long index1, long index2) const;
  98. };
  99. struct Diagonal {
  100. long index1;
  101. long index2;
  102. };
  103. //dynamic programming state for minimum-weight triangulation
  104. struct DPState {
  105. bool visible;
  106. real_t weight;
  107. long bestvertex;
  108. };
  109. //dynamic programming state for convex partitioning
  110. struct DPState2 {
  111. bool visible;
  112. long weight;
  113. List<Diagonal> pairs;
  114. };
  115. //edge that intersects the scanline
  116. struct ScanLineEdge {
  117. mutable long index;
  118. Vector2 p1;
  119. Vector2 p2;
  120. //determines if the edge is to the left of another edge
  121. bool operator< (const ScanLineEdge & other) const;
  122. bool IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const;
  123. };
  124. //standard helper functions
  125. bool IsConvex(Vector2& p1, Vector2& p2, Vector2& p3);
  126. bool IsReflex(Vector2& p1, Vector2& p2, Vector2& p3);
  127. bool IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p);
  128. bool InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p);
  129. bool InCone(PartitionVertex *v, Vector2 &p);
  130. int Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22);
  131. Vector2 Normalize(const Vector2 &p);
  132. real_t Distance(const Vector2 &p1, const Vector2 &p2);
  133. //helper functions for Triangulate_EC
  134. void UpdateVertexReflexity(PartitionVertex *v);
  135. void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices);
  136. //helper functions for ConvexPartition_OPT
  137. void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
  138. void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
  139. void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
  140. //helper functions for MonotonePartition
  141. bool Below(Vector2 &p1, Vector2 &p2);
  142. void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
  143. char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
  144. Set<ScanLineEdge> *edgeTree, long *helpers);
  145. //triangulates a monotone polygon, used in Triangulate_MONO
  146. int TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles);
  147. public:
  148. //simple heuristic procedure for removing holes from a list of polygons
  149. //works by creating a diagonal from the rightmost hole vertex to some visible vertex
  150. //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
  151. //space complexity: O(n)
  152. //params:
  153. // inpolys : a list of polygons that can contain holes
  154. // vertices of all non-hole polys have to be in counter-clockwise order
  155. // vertices of all hole polys have to be in clockwise order
  156. // outpolys : a list of polygons without holes
  157. //returns 1 on success, 0 on failure
  158. int RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys);
  159. //triangulates a polygon by ear clipping
  160. //time complexity O(n^2), n is the number of vertices
  161. //space complexity: O(n)
  162. //params:
  163. // poly : an input polygon to be triangulated
  164. // vertices have to be in counter-clockwise order
  165. // triangles : a list of triangles (result)
  166. //returns 1 on success, 0 on failure
  167. int Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
  168. //triangulates a list of polygons that may contain holes by ear clipping algorithm
  169. //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon
  170. //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
  171. //space complexity: O(n)
  172. //params:
  173. // inpolys : a list of polygons to be triangulated (can contain holes)
  174. // vertices of all non-hole polys have to be in counter-clockwise order
  175. // vertices of all hole polys have to be in clockwise order
  176. // triangles : a list of triangles (result)
  177. //returns 1 on success, 0 on failure
  178. int Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
  179. //creates an optimal polygon triangulation in terms of minimal edge length
  180. //time complexity: O(n^3), n is the number of vertices
  181. //space complexity: O(n^2)
  182. //params:
  183. // poly : an input polygon to be triangulated
  184. // vertices have to be in counter-clockwise order
  185. // triangles : a list of triangles (result)
  186. //returns 1 on success, 0 on failure
  187. int Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
  188. //triangulates a polygons by firstly partitioning it into monotone polygons
  189. //time complexity: O(n*log(n)), n is the number of vertices
  190. //space complexity: O(n)
  191. //params:
  192. // poly : an input polygon to be triangulated
  193. // vertices have to be in counter-clockwise order
  194. // triangles : a list of triangles (result)
  195. //returns 1 on success, 0 on failure
  196. int Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
  197. //triangulates a list of polygons by firstly partitioning them into monotone polygons
  198. //time complexity: O(n*log(n)), n is the number of vertices
  199. //space complexity: O(n)
  200. //params:
  201. // inpolys : a list of polygons to be triangulated (can contain holes)
  202. // vertices of all non-hole polys have to be in counter-clockwise order
  203. // vertices of all hole polys have to be in clockwise order
  204. // triangles : a list of triangles (result)
  205. //returns 1 on success, 0 on failure
  206. int Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
  207. //creates a monotone partition of a list of polygons that can contain holes
  208. //time complexity: O(n*log(n)), n is the number of vertices
  209. //space complexity: O(n)
  210. //params:
  211. // inpolys : a list of polygons to be triangulated (can contain holes)
  212. // vertices of all non-hole polys have to be in counter-clockwise order
  213. // vertices of all hole polys have to be in clockwise order
  214. // monotonePolys : a list of monotone polygons (result)
  215. //returns 1 on success, 0 on failure
  216. int MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys);
  217. //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm
  218. //the algorithm gives at most four times the number of parts as the optimal algorithm
  219. //however, in practice it works much better than that and often gives optimal partition
  220. //uses triangulation obtained by ear clipping as intermediate result
  221. //time complexity O(n^2), n is the number of vertices
  222. //space complexity: O(n)
  223. //params:
  224. // poly : an input polygon to be partitioned
  225. // vertices have to be in counter-clockwise order
  226. // parts : resulting list of convex polygons
  227. //returns 1 on success, 0 on failure
  228. int ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
  229. //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm
  230. //the algorithm gives at most four times the number of parts as the optimal algorithm
  231. //however, in practice it works much better than that and often gives optimal partition
  232. //uses triangulation obtained by ear clipping as intermediate result
  233. //time complexity O(n^2), n is the number of vertices
  234. //space complexity: O(n)
  235. //params:
  236. // inpolys : an input list of polygons to be partitioned
  237. // vertices of all non-hole polys have to be in counter-clockwise order
  238. // vertices of all hole polys have to be in clockwise order
  239. // parts : resulting list of convex polygons
  240. //returns 1 on success, 0 on failure
  241. int ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts);
  242. //optimal convex partitioning (in terms of number of resulting convex polygons)
  243. //using the Keil-Snoeyink algorithm
  244. //M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998
  245. //time complexity O(n^3), n is the number of vertices
  246. //space complexity: O(n^3)
  247. // poly : an input polygon to be partitioned
  248. // vertices have to be in counter-clockwise order
  249. // parts : resulting list of convex polygons
  250. //returns 1 on success, 0 on failure
  251. int ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
  252. };
  253. #endif