polypartition.cpp 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852
  1. /*************************************************************************/
  2. /* Copyright (c) 2011-2021 Ivan Fratric and contributors. */
  3. /* */
  4. /* Permission is hereby granted, free of charge, to any person obtaining */
  5. /* a copy of this software and associated documentation files (the */
  6. /* "Software"), to deal in the Software without restriction, including */
  7. /* without limitation the rights to use, copy, modify, merge, publish, */
  8. /* distribute, sublicense, and/or sell copies of the Software, and to */
  9. /* permit persons to whom the Software is furnished to do so, subject to */
  10. /* the following conditions: */
  11. /* */
  12. /* The above copyright notice and this permission notice shall be */
  13. /* included in all copies or substantial portions of the Software. */
  14. /* */
  15. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  16. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  17. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  18. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  19. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  20. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  21. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22. /*************************************************************************/
  23. #include "polypartition.h"
  24. #include <math.h>
  25. #include <string.h>
  26. #include <algorithm>
  27. TPPLPoly::TPPLPoly() {
  28. hole = false;
  29. numpoints = 0;
  30. points = NULL;
  31. }
  32. TPPLPoly::~TPPLPoly() {
  33. if (points) {
  34. delete[] points;
  35. }
  36. }
  37. void TPPLPoly::Clear() {
  38. if (points) {
  39. delete[] points;
  40. }
  41. hole = false;
  42. numpoints = 0;
  43. points = NULL;
  44. }
  45. void TPPLPoly::Init(long numpoints) {
  46. Clear();
  47. this->numpoints = numpoints;
  48. points = new TPPLPoint[numpoints];
  49. }
  50. void TPPLPoly::Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
  51. Init(3);
  52. points[0] = p1;
  53. points[1] = p2;
  54. points[2] = p3;
  55. }
  56. TPPLPoly::TPPLPoly(const TPPLPoly &src) :
  57. TPPLPoly() {
  58. hole = src.hole;
  59. numpoints = src.numpoints;
  60. if (numpoints > 0) {
  61. points = new TPPLPoint[numpoints];
  62. memcpy(points, src.points, numpoints * sizeof(TPPLPoint));
  63. }
  64. }
  65. TPPLPoly &TPPLPoly::operator=(const TPPLPoly &src) {
  66. Clear();
  67. hole = src.hole;
  68. numpoints = src.numpoints;
  69. if (numpoints > 0) {
  70. points = new TPPLPoint[numpoints];
  71. memcpy(points, src.points, numpoints * sizeof(TPPLPoint));
  72. }
  73. return *this;
  74. }
  75. TPPLOrientation TPPLPoly::GetOrientation() const {
  76. long i1, i2;
  77. tppl_float area = 0;
  78. for (i1 = 0; i1 < numpoints; i1++) {
  79. i2 = i1 + 1;
  80. if (i2 == numpoints) {
  81. i2 = 0;
  82. }
  83. area += points[i1].x * points[i2].y - points[i1].y * points[i2].x;
  84. }
  85. if (area > 0) {
  86. return TPPL_ORIENTATION_CCW;
  87. }
  88. if (area < 0) {
  89. return TPPL_ORIENTATION_CW;
  90. }
  91. return TPPL_ORIENTATION_NONE;
  92. }
  93. void TPPLPoly::SetOrientation(TPPLOrientation orientation) {
  94. TPPLOrientation polyorientation = GetOrientation();
  95. if (polyorientation != TPPL_ORIENTATION_NONE && polyorientation != orientation) {
  96. Invert();
  97. }
  98. }
  99. void TPPLPoly::Invert() {
  100. std::reverse(points, points + numpoints);
  101. }
  102. TPPLPartition::PartitionVertex::PartitionVertex() :
  103. previous(NULL), next(NULL) {
  104. }
  105. TPPLPoint TPPLPartition::Normalize(const TPPLPoint &p) {
  106. TPPLPoint r;
  107. tppl_float n = sqrt(p.x * p.x + p.y * p.y);
  108. if (n != 0) {
  109. r = p / n;
  110. } else {
  111. r.x = 0;
  112. r.y = 0;
  113. }
  114. return r;
  115. }
  116. tppl_float TPPLPartition::Distance(const TPPLPoint &p1, const TPPLPoint &p2) {
  117. tppl_float dx, dy;
  118. dx = p2.x - p1.x;
  119. dy = p2.y - p1.y;
  120. return (sqrt(dx * dx + dy * dy));
  121. }
  122. // Checks if two lines intersect.
  123. int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22) {
  124. if ((p11.x == p21.x) && (p11.y == p21.y)) {
  125. return 0;
  126. }
  127. if ((p11.x == p22.x) && (p11.y == p22.y)) {
  128. return 0;
  129. }
  130. if ((p12.x == p21.x) && (p12.y == p21.y)) {
  131. return 0;
  132. }
  133. if ((p12.x == p22.x) && (p12.y == p22.y)) {
  134. return 0;
  135. }
  136. TPPLPoint v1ort, v2ort, v;
  137. tppl_float dot11, dot12, dot21, dot22;
  138. v1ort.x = p12.y - p11.y;
  139. v1ort.y = p11.x - p12.x;
  140. v2ort.x = p22.y - p21.y;
  141. v2ort.y = p21.x - p22.x;
  142. v = p21 - p11;
  143. dot21 = v.x * v1ort.x + v.y * v1ort.y;
  144. v = p22 - p11;
  145. dot22 = v.x * v1ort.x + v.y * v1ort.y;
  146. v = p11 - p21;
  147. dot11 = v.x * v2ort.x + v.y * v2ort.y;
  148. v = p12 - p21;
  149. dot12 = v.x * v2ort.x + v.y * v2ort.y;
  150. if (dot11 * dot12 > 0) {
  151. return 0;
  152. }
  153. if (dot21 * dot22 > 0) {
  154. return 0;
  155. }
  156. return 1;
  157. }
  158. // Removes holes from inpolys by merging them with non-holes.
  159. int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
  160. TPPLPolyList polys;
  161. TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2;
  162. long i, i2, holepointindex, polypointindex;
  163. TPPLPoint holepoint, polypoint, bestpolypoint;
  164. TPPLPoint linep1, linep2;
  165. TPPLPoint v1, v2;
  166. TPPLPoly newpoly;
  167. bool hasholes;
  168. bool pointvisible;
  169. bool pointfound;
  170. // Check for the trivial case of no holes.
  171. hasholes = false;
  172. for (iter = inpolys->front(); iter; iter = iter->next()) {
  173. if (iter->get().IsHole()) {
  174. hasholes = true;
  175. break;
  176. }
  177. }
  178. if (!hasholes) {
  179. for (iter = inpolys->front(); iter; iter = iter->next()) {
  180. outpolys->push_back(iter->get());
  181. }
  182. return 1;
  183. }
  184. polys = *inpolys;
  185. while (1) {
  186. // Find the hole point with the largest x.
  187. hasholes = false;
  188. for (iter = polys.front(); iter; iter = iter->next()) {
  189. if (!iter->get().IsHole()) {
  190. continue;
  191. }
  192. if (!hasholes) {
  193. hasholes = true;
  194. holeiter = iter;
  195. holepointindex = 0;
  196. }
  197. for (i = 0; i < iter->get().GetNumPoints(); i++) {
  198. if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) {
  199. holeiter = iter;
  200. holepointindex = i;
  201. }
  202. }
  203. }
  204. if (!hasholes) {
  205. break;
  206. }
  207. holepoint = holeiter->get().GetPoint(holepointindex);
  208. pointfound = false;
  209. for (iter = polys.front(); iter; iter = iter->next()) {
  210. if (iter->get().IsHole()) {
  211. continue;
  212. }
  213. for (i = 0; i < iter->get().GetNumPoints(); i++) {
  214. if (iter->get().GetPoint(i).x <= holepoint.x) {
  215. continue;
  216. }
  217. if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())),
  218. iter->get().GetPoint(i),
  219. iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())),
  220. holepoint)) {
  221. continue;
  222. }
  223. polypoint = iter->get().GetPoint(i);
  224. if (pointfound) {
  225. v1 = Normalize(polypoint - holepoint);
  226. v2 = Normalize(bestpolypoint - holepoint);
  227. if (v2.x > v1.x) {
  228. continue;
  229. }
  230. }
  231. pointvisible = true;
  232. for (iter2 = polys.front(); iter2; iter2 = iter2->next()) {
  233. if (iter2->get().IsHole()) {
  234. continue;
  235. }
  236. for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) {
  237. linep1 = iter2->get().GetPoint(i2);
  238. linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints()));
  239. if (Intersects(holepoint, polypoint, linep1, linep2)) {
  240. pointvisible = false;
  241. break;
  242. }
  243. }
  244. if (!pointvisible) {
  245. break;
  246. }
  247. }
  248. if (pointvisible) {
  249. pointfound = true;
  250. bestpolypoint = polypoint;
  251. polyiter = iter;
  252. polypointindex = i;
  253. }
  254. }
  255. }
  256. if (!pointfound) {
  257. return 0;
  258. }
  259. newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2);
  260. i2 = 0;
  261. for (i = 0; i <= polypointindex; i++) {
  262. newpoly[i2] = polyiter->get().GetPoint(i);
  263. i2++;
  264. }
  265. for (i = 0; i <= holeiter->get().GetNumPoints(); i++) {
  266. newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints());
  267. i2++;
  268. }
  269. for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) {
  270. newpoly[i2] = polyiter->get().GetPoint(i);
  271. i2++;
  272. }
  273. polys.erase(holeiter);
  274. polys.erase(polyiter);
  275. polys.push_back(newpoly);
  276. }
  277. for (iter = polys.front(); iter; iter = iter->next()) {
  278. outpolys->push_back(iter->get());
  279. }
  280. return 1;
  281. }
  282. bool TPPLPartition::IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
  283. tppl_float tmp;
  284. tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
  285. if (tmp > 0) {
  286. return 1;
  287. } else {
  288. return 0;
  289. }
  290. }
  291. bool TPPLPartition::IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
  292. tppl_float tmp;
  293. tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
  294. if (tmp < 0) {
  295. return 1;
  296. } else {
  297. return 0;
  298. }
  299. }
  300. bool TPPLPartition::IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) {
  301. if (IsConvex(p1, p, p2)) {
  302. return false;
  303. }
  304. if (IsConvex(p2, p, p3)) {
  305. return false;
  306. }
  307. if (IsConvex(p3, p, p1)) {
  308. return false;
  309. }
  310. return true;
  311. }
  312. bool TPPLPartition::InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) {
  313. bool convex;
  314. convex = IsConvex(p1, p2, p3);
  315. if (convex) {
  316. if (!IsConvex(p1, p2, p)) {
  317. return false;
  318. }
  319. if (!IsConvex(p2, p3, p)) {
  320. return false;
  321. }
  322. return true;
  323. } else {
  324. if (IsConvex(p1, p2, p)) {
  325. return true;
  326. }
  327. if (IsConvex(p2, p3, p)) {
  328. return true;
  329. }
  330. return false;
  331. }
  332. }
  333. bool TPPLPartition::InCone(PartitionVertex *v, TPPLPoint &p) {
  334. TPPLPoint p1, p2, p3;
  335. p1 = v->previous->p;
  336. p2 = v->p;
  337. p3 = v->next->p;
  338. return InCone(p1, p2, p3, p);
  339. }
  340. void TPPLPartition::UpdateVertexReflexity(PartitionVertex *v) {
  341. PartitionVertex *v1 = NULL, *v3 = NULL;
  342. v1 = v->previous;
  343. v3 = v->next;
  344. v->isConvex = !IsReflex(v1->p, v->p, v3->p);
  345. }
  346. void TPPLPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) {
  347. long i;
  348. PartitionVertex *v1 = NULL, *v3 = NULL;
  349. TPPLPoint vec1, vec3;
  350. v1 = v->previous;
  351. v3 = v->next;
  352. v->isConvex = IsConvex(v1->p, v->p, v3->p);
  353. vec1 = Normalize(v1->p - v->p);
  354. vec3 = Normalize(v3->p - v->p);
  355. v->angle = vec1.x * vec3.x + vec1.y * vec3.y;
  356. if (v->isConvex) {
  357. v->isEar = true;
  358. for (i = 0; i < numvertices; i++) {
  359. if ((vertices[i].p.x == v->p.x) && (vertices[i].p.y == v->p.y)) {
  360. continue;
  361. }
  362. if ((vertices[i].p.x == v1->p.x) && (vertices[i].p.y == v1->p.y)) {
  363. continue;
  364. }
  365. if ((vertices[i].p.x == v3->p.x) && (vertices[i].p.y == v3->p.y)) {
  366. continue;
  367. }
  368. if (IsInside(v1->p, v->p, v3->p, vertices[i].p)) {
  369. v->isEar = false;
  370. break;
  371. }
  372. }
  373. } else {
  374. v->isEar = false;
  375. }
  376. }
  377. // Triangulation by ear removal.
  378. int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) {
  379. if (!poly->Valid()) {
  380. return 0;
  381. }
  382. long numvertices;
  383. PartitionVertex *vertices = NULL;
  384. PartitionVertex *ear = NULL;
  385. TPPLPoly triangle;
  386. long i, j;
  387. bool earfound;
  388. if (poly->GetNumPoints() < 3) {
  389. return 0;
  390. }
  391. if (poly->GetNumPoints() == 3) {
  392. triangles->push_back(*poly);
  393. return 1;
  394. }
  395. numvertices = poly->GetNumPoints();
  396. vertices = new PartitionVertex[numvertices];
  397. for (i = 0; i < numvertices; i++) {
  398. vertices[i].isActive = true;
  399. vertices[i].p = poly->GetPoint(i);
  400. if (i == (numvertices - 1)) {
  401. vertices[i].next = &(vertices[0]);
  402. } else {
  403. vertices[i].next = &(vertices[i + 1]);
  404. }
  405. if (i == 0) {
  406. vertices[i].previous = &(vertices[numvertices - 1]);
  407. } else {
  408. vertices[i].previous = &(vertices[i - 1]);
  409. }
  410. }
  411. for (i = 0; i < numvertices; i++) {
  412. UpdateVertex(&vertices[i], vertices, numvertices);
  413. }
  414. for (i = 0; i < numvertices - 3; i++) {
  415. earfound = false;
  416. // Find the most extruded ear.
  417. for (j = 0; j < numvertices; j++) {
  418. if (!vertices[j].isActive) {
  419. continue;
  420. }
  421. if (!vertices[j].isEar) {
  422. continue;
  423. }
  424. if (!earfound) {
  425. earfound = true;
  426. ear = &(vertices[j]);
  427. } else {
  428. if (vertices[j].angle > ear->angle) {
  429. ear = &(vertices[j]);
  430. }
  431. }
  432. }
  433. if (!earfound) {
  434. delete[] vertices;
  435. return 0;
  436. }
  437. triangle.Triangle(ear->previous->p, ear->p, ear->next->p);
  438. triangles->push_back(triangle);
  439. ear->isActive = false;
  440. ear->previous->next = ear->next;
  441. ear->next->previous = ear->previous;
  442. if (i == numvertices - 4) {
  443. break;
  444. }
  445. UpdateVertex(ear->previous, vertices, numvertices);
  446. UpdateVertex(ear->next, vertices, numvertices);
  447. }
  448. for (i = 0; i < numvertices; i++) {
  449. if (vertices[i].isActive) {
  450. triangle.Triangle(vertices[i].previous->p, vertices[i].p, vertices[i].next->p);
  451. triangles->push_back(triangle);
  452. break;
  453. }
  454. }
  455. delete[] vertices;
  456. return 1;
  457. }
  458. int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
  459. TPPLPolyList outpolys;
  460. TPPLPolyList::Element *iter;
  461. if (!RemoveHoles(inpolys, &outpolys)) {
  462. return 0;
  463. }
  464. for (iter = outpolys.front(); iter; iter = iter->next()) {
  465. if (!Triangulate_EC(&(iter->get()), triangles)) {
  466. return 0;
  467. }
  468. }
  469. return 1;
  470. }
  471. int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
  472. if (!poly->Valid()) {
  473. return 0;
  474. }
  475. TPPLPolyList triangles;
  476. TPPLPolyList::Element *iter1, *iter2;
  477. TPPLPoly *poly1 = NULL, *poly2 = NULL;
  478. TPPLPoly newpoly;
  479. TPPLPoint d1, d2, p1, p2, p3;
  480. long i11, i12, i21, i22, i13, i23, j, k;
  481. bool isdiagonal;
  482. long numreflex;
  483. // Check if the poly is already convex.
  484. numreflex = 0;
  485. for (i11 = 0; i11 < poly->GetNumPoints(); i11++) {
  486. if (i11 == 0) {
  487. i12 = poly->GetNumPoints() - 1;
  488. } else {
  489. i12 = i11 - 1;
  490. }
  491. if (i11 == (poly->GetNumPoints() - 1)) {
  492. i13 = 0;
  493. } else {
  494. i13 = i11 + 1;
  495. }
  496. if (IsReflex(poly->GetPoint(i12), poly->GetPoint(i11), poly->GetPoint(i13))) {
  497. numreflex = 1;
  498. break;
  499. }
  500. }
  501. if (numreflex == 0) {
  502. parts->push_back(*poly);
  503. return 1;
  504. }
  505. if (!Triangulate_EC(poly, &triangles)) {
  506. return 0;
  507. }
  508. for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
  509. poly1 = &(iter1->get());
  510. for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) {
  511. d1 = poly1->GetPoint(i11);
  512. i12 = (i11 + 1) % (poly1->GetNumPoints());
  513. d2 = poly1->GetPoint(i12);
  514. isdiagonal = false;
  515. for (iter2 = iter1; iter2; iter2 = iter2->next()) {
  516. if (iter1 == iter2) {
  517. continue;
  518. }
  519. poly2 = &(iter2->get());
  520. for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) {
  521. if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) {
  522. continue;
  523. }
  524. i22 = (i21 + 1) % (poly2->GetNumPoints());
  525. if ((d1.x != poly2->GetPoint(i22).x) || (d1.y != poly2->GetPoint(i22).y)) {
  526. continue;
  527. }
  528. isdiagonal = true;
  529. break;
  530. }
  531. if (isdiagonal) {
  532. break;
  533. }
  534. }
  535. if (!isdiagonal) {
  536. continue;
  537. }
  538. p2 = poly1->GetPoint(i11);
  539. if (i11 == 0) {
  540. i13 = poly1->GetNumPoints() - 1;
  541. } else {
  542. i13 = i11 - 1;
  543. }
  544. p1 = poly1->GetPoint(i13);
  545. if (i22 == (poly2->GetNumPoints() - 1)) {
  546. i23 = 0;
  547. } else {
  548. i23 = i22 + 1;
  549. }
  550. p3 = poly2->GetPoint(i23);
  551. if (!IsConvex(p1, p2, p3)) {
  552. continue;
  553. }
  554. p2 = poly1->GetPoint(i12);
  555. if (i12 == (poly1->GetNumPoints() - 1)) {
  556. i13 = 0;
  557. } else {
  558. i13 = i12 + 1;
  559. }
  560. p3 = poly1->GetPoint(i13);
  561. if (i21 == 0) {
  562. i23 = poly2->GetNumPoints() - 1;
  563. } else {
  564. i23 = i21 - 1;
  565. }
  566. p1 = poly2->GetPoint(i23);
  567. if (!IsConvex(p1, p2, p3)) {
  568. continue;
  569. }
  570. newpoly.Init(poly1->GetNumPoints() + poly2->GetNumPoints() - 2);
  571. k = 0;
  572. for (j = i12; j != i11; j = (j + 1) % (poly1->GetNumPoints())) {
  573. newpoly[k] = poly1->GetPoint(j);
  574. k++;
  575. }
  576. for (j = i22; j != i21; j = (j + 1) % (poly2->GetNumPoints())) {
  577. newpoly[k] = poly2->GetPoint(j);
  578. k++;
  579. }
  580. triangles.erase(iter2);
  581. iter1->get() = newpoly;
  582. poly1 = &(iter1->get());
  583. i11 = -1;
  584. continue;
  585. }
  586. }
  587. for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
  588. parts->push_back(iter1->get());
  589. }
  590. return 1;
  591. }
  592. int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) {
  593. TPPLPolyList outpolys;
  594. TPPLPolyList::Element *iter;
  595. if (!RemoveHoles(inpolys, &outpolys)) {
  596. return 0;
  597. }
  598. for (iter = outpolys.front(); iter; iter = iter->next()) {
  599. if (!ConvexPartition_HM(&(iter->get()), parts)) {
  600. return 0;
  601. }
  602. }
  603. return 1;
  604. }
  605. // Minimum-weight polygon triangulation by dynamic programming.
  606. // Time complexity: O(n^3)
  607. // Space complexity: O(n^2)
  608. int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) {
  609. if (!poly->Valid()) {
  610. return 0;
  611. }
  612. long i, j, k, gap, n;
  613. DPState **dpstates = NULL;
  614. TPPLPoint p1, p2, p3, p4;
  615. long bestvertex;
  616. tppl_float weight, minweight, d1, d2;
  617. Diagonal diagonal, newdiagonal;
  618. DiagonalList diagonals;
  619. TPPLPoly triangle;
  620. int ret = 1;
  621. n = poly->GetNumPoints();
  622. dpstates = new DPState *[n];
  623. for (i = 1; i < n; i++) {
  624. dpstates[i] = new DPState[i];
  625. }
  626. // Initialize states and visibility.
  627. for (i = 0; i < (n - 1); i++) {
  628. p1 = poly->GetPoint(i);
  629. for (j = i + 1; j < n; j++) {
  630. dpstates[j][i].visible = true;
  631. dpstates[j][i].weight = 0;
  632. dpstates[j][i].bestvertex = -1;
  633. if (j != (i + 1)) {
  634. p2 = poly->GetPoint(j);
  635. // Visibility check.
  636. if (i == 0) {
  637. p3 = poly->GetPoint(n - 1);
  638. } else {
  639. p3 = poly->GetPoint(i - 1);
  640. }
  641. if (i == (n - 1)) {
  642. p4 = poly->GetPoint(0);
  643. } else {
  644. p4 = poly->GetPoint(i + 1);
  645. }
  646. if (!InCone(p3, p1, p4, p2)) {
  647. dpstates[j][i].visible = false;
  648. continue;
  649. }
  650. if (j == 0) {
  651. p3 = poly->GetPoint(n - 1);
  652. } else {
  653. p3 = poly->GetPoint(j - 1);
  654. }
  655. if (j == (n - 1)) {
  656. p4 = poly->GetPoint(0);
  657. } else {
  658. p4 = poly->GetPoint(j + 1);
  659. }
  660. if (!InCone(p3, p2, p4, p1)) {
  661. dpstates[j][i].visible = false;
  662. continue;
  663. }
  664. for (k = 0; k < n; k++) {
  665. p3 = poly->GetPoint(k);
  666. if (k == (n - 1)) {
  667. p4 = poly->GetPoint(0);
  668. } else {
  669. p4 = poly->GetPoint(k + 1);
  670. }
  671. if (Intersects(p1, p2, p3, p4)) {
  672. dpstates[j][i].visible = false;
  673. break;
  674. }
  675. }
  676. }
  677. }
  678. }
  679. dpstates[n - 1][0].visible = true;
  680. dpstates[n - 1][0].weight = 0;
  681. dpstates[n - 1][0].bestvertex = -1;
  682. for (gap = 2; gap < n; gap++) {
  683. for (i = 0; i < (n - gap); i++) {
  684. j = i + gap;
  685. if (!dpstates[j][i].visible) {
  686. continue;
  687. }
  688. bestvertex = -1;
  689. for (k = (i + 1); k < j; k++) {
  690. if (!dpstates[k][i].visible) {
  691. continue;
  692. }
  693. if (!dpstates[j][k].visible) {
  694. continue;
  695. }
  696. if (k <= (i + 1)) {
  697. d1 = 0;
  698. } else {
  699. d1 = Distance(poly->GetPoint(i), poly->GetPoint(k));
  700. }
  701. if (j <= (k + 1)) {
  702. d2 = 0;
  703. } else {
  704. d2 = Distance(poly->GetPoint(k), poly->GetPoint(j));
  705. }
  706. weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2;
  707. if ((bestvertex == -1) || (weight < minweight)) {
  708. bestvertex = k;
  709. minweight = weight;
  710. }
  711. }
  712. if (bestvertex == -1) {
  713. for (i = 1; i < n; i++) {
  714. delete[] dpstates[i];
  715. }
  716. delete[] dpstates;
  717. return 0;
  718. }
  719. dpstates[j][i].bestvertex = bestvertex;
  720. dpstates[j][i].weight = minweight;
  721. }
  722. }
  723. newdiagonal.index1 = 0;
  724. newdiagonal.index2 = n - 1;
  725. diagonals.push_back(newdiagonal);
  726. while (!diagonals.is_empty()) {
  727. diagonal = diagonals.front()->get();
  728. diagonals.pop_front();
  729. bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
  730. if (bestvertex == -1) {
  731. ret = 0;
  732. break;
  733. }
  734. triangle.Triangle(poly->GetPoint(diagonal.index1), poly->GetPoint(bestvertex), poly->GetPoint(diagonal.index2));
  735. triangles->push_back(triangle);
  736. if (bestvertex > (diagonal.index1 + 1)) {
  737. newdiagonal.index1 = diagonal.index1;
  738. newdiagonal.index2 = bestvertex;
  739. diagonals.push_back(newdiagonal);
  740. }
  741. if (diagonal.index2 > (bestvertex + 1)) {
  742. newdiagonal.index1 = bestvertex;
  743. newdiagonal.index2 = diagonal.index2;
  744. diagonals.push_back(newdiagonal);
  745. }
  746. }
  747. for (i = 1; i < n; i++) {
  748. delete[] dpstates[i];
  749. }
  750. delete[] dpstates;
  751. return ret;
  752. }
  753. void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) {
  754. Diagonal newdiagonal;
  755. DiagonalList *pairs = NULL;
  756. long w2;
  757. w2 = dpstates[a][b].weight;
  758. if (w > w2) {
  759. return;
  760. }
  761. pairs = &(dpstates[a][b].pairs);
  762. newdiagonal.index1 = i;
  763. newdiagonal.index2 = j;
  764. if (w < w2) {
  765. pairs->clear();
  766. pairs->push_front(newdiagonal);
  767. dpstates[a][b].weight = w;
  768. } else {
  769. if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) {
  770. return;
  771. }
  772. while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) {
  773. pairs->pop_front();
  774. }
  775. pairs->push_front(newdiagonal);
  776. }
  777. }
  778. void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
  779. DiagonalList *pairs = NULL;
  780. DiagonalList::Element *iter, *lastiter;
  781. long top;
  782. long w;
  783. if (!dpstates[i][j].visible) {
  784. return;
  785. }
  786. top = j;
  787. w = dpstates[i][j].weight;
  788. if (k - j > 1) {
  789. if (!dpstates[j][k].visible) {
  790. return;
  791. }
  792. w += dpstates[j][k].weight + 1;
  793. }
  794. if (j - i > 1) {
  795. pairs = &(dpstates[i][j].pairs);
  796. iter = pairs->back();
  797. lastiter = pairs->back();
  798. while (iter != pairs->front()) {
  799. iter--;
  800. if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) {
  801. lastiter = iter;
  802. } else {
  803. break;
  804. }
  805. }
  806. if (lastiter == pairs->back()) {
  807. w++;
  808. } else {
  809. if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) {
  810. w++;
  811. } else {
  812. top = lastiter->get().index1;
  813. }
  814. }
  815. }
  816. UpdateState(i, k, w, top, j, dpstates);
  817. }
  818. void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
  819. DiagonalList *pairs = NULL;
  820. DiagonalList::Element *iter, *lastiter;
  821. long top;
  822. long w;
  823. if (!dpstates[j][k].visible) {
  824. return;
  825. }
  826. top = j;
  827. w = dpstates[j][k].weight;
  828. if (j - i > 1) {
  829. if (!dpstates[i][j].visible) {
  830. return;
  831. }
  832. w += dpstates[i][j].weight + 1;
  833. }
  834. if (k - j > 1) {
  835. pairs = &(dpstates[j][k].pairs);
  836. iter = pairs->front();
  837. if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) {
  838. lastiter = iter;
  839. while (iter) {
  840. if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) {
  841. lastiter = iter;
  842. iter = iter->next();
  843. } else {
  844. break;
  845. }
  846. }
  847. if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) {
  848. w++;
  849. } else {
  850. top = lastiter->get().index2;
  851. }
  852. } else {
  853. w++;
  854. }
  855. }
  856. UpdateState(i, k, w, j, top, dpstates);
  857. }
  858. int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
  859. if (!poly->Valid()) {
  860. return 0;
  861. }
  862. TPPLPoint p1, p2, p3, p4;
  863. PartitionVertex *vertices = NULL;
  864. DPState2 **dpstates = NULL;
  865. long i, j, k, n, gap;
  866. DiagonalList diagonals, diagonals2;
  867. Diagonal diagonal, newdiagonal;
  868. DiagonalList *pairs = NULL, *pairs2 = NULL;
  869. DiagonalList::Element *iter, *iter2;
  870. int ret;
  871. TPPLPoly newpoly;
  872. List<long> indices;
  873. List<long>::Element *iiter;
  874. bool ijreal, jkreal;
  875. n = poly->GetNumPoints();
  876. vertices = new PartitionVertex[n];
  877. dpstates = new DPState2 *[n];
  878. for (i = 0; i < n; i++) {
  879. dpstates[i] = new DPState2[n];
  880. }
  881. // Initialize vertex information.
  882. for (i = 0; i < n; i++) {
  883. vertices[i].p = poly->GetPoint(i);
  884. vertices[i].isActive = true;
  885. if (i == 0) {
  886. vertices[i].previous = &(vertices[n - 1]);
  887. } else {
  888. vertices[i].previous = &(vertices[i - 1]);
  889. }
  890. if (i == (poly->GetNumPoints() - 1)) {
  891. vertices[i].next = &(vertices[0]);
  892. } else {
  893. vertices[i].next = &(vertices[i + 1]);
  894. }
  895. }
  896. for (i = 1; i < n; i++) {
  897. UpdateVertexReflexity(&(vertices[i]));
  898. }
  899. // Initialize states and visibility.
  900. for (i = 0; i < (n - 1); i++) {
  901. p1 = poly->GetPoint(i);
  902. for (j = i + 1; j < n; j++) {
  903. dpstates[i][j].visible = true;
  904. if (j == i + 1) {
  905. dpstates[i][j].weight = 0;
  906. } else {
  907. dpstates[i][j].weight = 2147483647;
  908. }
  909. if (j != (i + 1)) {
  910. p2 = poly->GetPoint(j);
  911. // Visibility check.
  912. if (!InCone(&vertices[i], p2)) {
  913. dpstates[i][j].visible = false;
  914. continue;
  915. }
  916. if (!InCone(&vertices[j], p1)) {
  917. dpstates[i][j].visible = false;
  918. continue;
  919. }
  920. for (k = 0; k < n; k++) {
  921. p3 = poly->GetPoint(k);
  922. if (k == (n - 1)) {
  923. p4 = poly->GetPoint(0);
  924. } else {
  925. p4 = poly->GetPoint(k + 1);
  926. }
  927. if (Intersects(p1, p2, p3, p4)) {
  928. dpstates[i][j].visible = false;
  929. break;
  930. }
  931. }
  932. }
  933. }
  934. }
  935. for (i = 0; i < (n - 2); i++) {
  936. j = i + 2;
  937. if (dpstates[i][j].visible) {
  938. dpstates[i][j].weight = 0;
  939. newdiagonal.index1 = i + 1;
  940. newdiagonal.index2 = i + 1;
  941. dpstates[i][j].pairs.push_back(newdiagonal);
  942. }
  943. }
  944. dpstates[0][n - 1].visible = true;
  945. vertices[0].isConvex = false; // By convention.
  946. for (gap = 3; gap < n; gap++) {
  947. for (i = 0; i < n - gap; i++) {
  948. if (vertices[i].isConvex) {
  949. continue;
  950. }
  951. k = i + gap;
  952. if (dpstates[i][k].visible) {
  953. if (!vertices[k].isConvex) {
  954. for (j = i + 1; j < k; j++) {
  955. TypeA(i, j, k, vertices, dpstates);
  956. }
  957. } else {
  958. for (j = i + 1; j < (k - 1); j++) {
  959. if (vertices[j].isConvex) {
  960. continue;
  961. }
  962. TypeA(i, j, k, vertices, dpstates);
  963. }
  964. TypeA(i, k - 1, k, vertices, dpstates);
  965. }
  966. }
  967. }
  968. for (k = gap; k < n; k++) {
  969. if (vertices[k].isConvex) {
  970. continue;
  971. }
  972. i = k - gap;
  973. if ((vertices[i].isConvex) && (dpstates[i][k].visible)) {
  974. TypeB(i, i + 1, k, vertices, dpstates);
  975. for (j = i + 2; j < k; j++) {
  976. if (vertices[j].isConvex) {
  977. continue;
  978. }
  979. TypeB(i, j, k, vertices, dpstates);
  980. }
  981. }
  982. }
  983. }
  984. // Recover solution.
  985. ret = 1;
  986. newdiagonal.index1 = 0;
  987. newdiagonal.index2 = n - 1;
  988. diagonals.push_front(newdiagonal);
  989. while (!diagonals.is_empty()) {
  990. diagonal = diagonals.front()->get();
  991. diagonals.pop_front();
  992. if ((diagonal.index2 - diagonal.index1) <= 1) {
  993. continue;
  994. }
  995. pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
  996. if (pairs->is_empty()) {
  997. ret = 0;
  998. break;
  999. }
  1000. if (!vertices[diagonal.index1].isConvex) {
  1001. iter = pairs->back();
  1002. iter--;
  1003. j = iter->get().index2;
  1004. newdiagonal.index1 = j;
  1005. newdiagonal.index2 = diagonal.index2;
  1006. diagonals.push_front(newdiagonal);
  1007. if ((j - diagonal.index1) > 1) {
  1008. if (iter->get().index1 != iter->get().index2) {
  1009. pairs2 = &(dpstates[diagonal.index1][j].pairs);
  1010. while (1) {
  1011. if (pairs2->is_empty()) {
  1012. ret = 0;
  1013. break;
  1014. }
  1015. iter2 = pairs2->back();
  1016. iter2--;
  1017. if (iter->get().index1 != iter2->get().index1) {
  1018. pairs2->pop_back();
  1019. } else {
  1020. break;
  1021. }
  1022. }
  1023. if (ret == 0) {
  1024. break;
  1025. }
  1026. }
  1027. newdiagonal.index1 = diagonal.index1;
  1028. newdiagonal.index2 = j;
  1029. diagonals.push_front(newdiagonal);
  1030. }
  1031. } else {
  1032. iter = pairs->front();
  1033. j = iter->get().index1;
  1034. newdiagonal.index1 = diagonal.index1;
  1035. newdiagonal.index2 = j;
  1036. diagonals.push_front(newdiagonal);
  1037. if ((diagonal.index2 - j) > 1) {
  1038. if (iter->get().index1 != iter->get().index2) {
  1039. pairs2 = &(dpstates[j][diagonal.index2].pairs);
  1040. while (1) {
  1041. if (pairs2->is_empty()) {
  1042. ret = 0;
  1043. break;
  1044. }
  1045. iter2 = pairs2->front();
  1046. if (iter->get().index2 != iter2->get().index2) {
  1047. pairs2->pop_front();
  1048. } else {
  1049. break;
  1050. }
  1051. }
  1052. if (ret == 0) {
  1053. break;
  1054. }
  1055. }
  1056. newdiagonal.index1 = j;
  1057. newdiagonal.index2 = diagonal.index2;
  1058. diagonals.push_front(newdiagonal);
  1059. }
  1060. }
  1061. }
  1062. if (ret == 0) {
  1063. for (i = 0; i < n; i++) {
  1064. delete[] dpstates[i];
  1065. }
  1066. delete[] dpstates;
  1067. delete[] vertices;
  1068. return ret;
  1069. }
  1070. newdiagonal.index1 = 0;
  1071. newdiagonal.index2 = n - 1;
  1072. diagonals.push_front(newdiagonal);
  1073. while (!diagonals.is_empty()) {
  1074. diagonal = diagonals.front()->get();
  1075. diagonals.pop_front();
  1076. if ((diagonal.index2 - diagonal.index1) <= 1) {
  1077. continue;
  1078. }
  1079. indices.clear();
  1080. diagonals2.clear();
  1081. indices.push_back(diagonal.index1);
  1082. indices.push_back(diagonal.index2);
  1083. diagonals2.push_front(diagonal);
  1084. while (!diagonals2.is_empty()) {
  1085. diagonal = diagonals2.front()->get();
  1086. diagonals2.pop_front();
  1087. if ((diagonal.index2 - diagonal.index1) <= 1) {
  1088. continue;
  1089. }
  1090. ijreal = true;
  1091. jkreal = true;
  1092. pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
  1093. if (!vertices[diagonal.index1].isConvex) {
  1094. iter = pairs->back();
  1095. iter--;
  1096. j = iter->get().index2;
  1097. if (iter->get().index1 != iter->get().index2) {
  1098. ijreal = false;
  1099. }
  1100. } else {
  1101. iter = pairs->front();
  1102. j = iter->get().index1;
  1103. if (iter->get().index1 != iter->get().index2) {
  1104. jkreal = false;
  1105. }
  1106. }
  1107. newdiagonal.index1 = diagonal.index1;
  1108. newdiagonal.index2 = j;
  1109. if (ijreal) {
  1110. diagonals.push_back(newdiagonal);
  1111. } else {
  1112. diagonals2.push_back(newdiagonal);
  1113. }
  1114. newdiagonal.index1 = j;
  1115. newdiagonal.index2 = diagonal.index2;
  1116. if (jkreal) {
  1117. diagonals.push_back(newdiagonal);
  1118. } else {
  1119. diagonals2.push_back(newdiagonal);
  1120. }
  1121. indices.push_back(j);
  1122. }
  1123. //std::sort(indices.begin(), indices.end());
  1124. indices.sort();
  1125. newpoly.Init((long)indices.size());
  1126. k = 0;
  1127. for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) {
  1128. newpoly[k] = vertices[iiter->get()].p;
  1129. k++;
  1130. }
  1131. parts->push_back(newpoly);
  1132. }
  1133. for (i = 0; i < n; i++) {
  1134. delete[] dpstates[i];
  1135. }
  1136. delete[] dpstates;
  1137. delete[] vertices;
  1138. return ret;
  1139. }
  1140. // Creates a monotone partition of a list of polygons that
  1141. // can contain holes. Triangulates a set of polygons by
  1142. // first partitioning them into monotone polygons.
  1143. // Time complexity: O(n*log(n)), n is the number of vertices.
  1144. // Space complexity: O(n)
  1145. // The algorithm used here is outlined in the book
  1146. // "Computational Geometry: Algorithms and Applications"
  1147. // by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars.
  1148. int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) {
  1149. TPPLPolyList::Element *iter;
  1150. MonotoneVertex *vertices = NULL;
  1151. long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices;
  1152. long polystartindex, polyendindex;
  1153. TPPLPoly *poly = NULL;
  1154. MonotoneVertex *v = NULL, *v2 = NULL, *vprev = NULL, *vnext = NULL;
  1155. ScanLineEdge newedge;
  1156. bool error = false;
  1157. numvertices = 0;
  1158. for (iter = inpolys->front(); iter; iter = iter->next()) {
  1159. numvertices += iter->get().GetNumPoints();
  1160. }
  1161. maxnumvertices = numvertices * 3;
  1162. vertices = new MonotoneVertex[maxnumvertices];
  1163. newnumvertices = numvertices;
  1164. polystartindex = 0;
  1165. for (iter = inpolys->front(); iter; iter = iter->next()) {
  1166. poly = &(iter->get());
  1167. polyendindex = polystartindex + poly->GetNumPoints() - 1;
  1168. for (i = 0; i < poly->GetNumPoints(); i++) {
  1169. vertices[i + polystartindex].p = poly->GetPoint(i);
  1170. if (i == 0) {
  1171. vertices[i + polystartindex].previous = polyendindex;
  1172. } else {
  1173. vertices[i + polystartindex].previous = i + polystartindex - 1;
  1174. }
  1175. if (i == (poly->GetNumPoints() - 1)) {
  1176. vertices[i + polystartindex].next = polystartindex;
  1177. } else {
  1178. vertices[i + polystartindex].next = i + polystartindex + 1;
  1179. }
  1180. }
  1181. polystartindex = polyendindex + 1;
  1182. }
  1183. // Construct the priority queue.
  1184. long *priority = new long[numvertices];
  1185. for (i = 0; i < numvertices; i++) {
  1186. priority[i] = i;
  1187. }
  1188. std::sort(priority, &(priority[numvertices]), VertexSorter(vertices));
  1189. // Determine vertex types.
  1190. TPPLVertexType *vertextypes = new TPPLVertexType[maxnumvertices];
  1191. for (i = 0; i < numvertices; i++) {
  1192. v = &(vertices[i]);
  1193. vprev = &(vertices[v->previous]);
  1194. vnext = &(vertices[v->next]);
  1195. if (Below(vprev->p, v->p) && Below(vnext->p, v->p)) {
  1196. if (IsConvex(vnext->p, vprev->p, v->p)) {
  1197. vertextypes[i] = TPPL_VERTEXTYPE_START;
  1198. } else {
  1199. vertextypes[i] = TPPL_VERTEXTYPE_SPLIT;
  1200. }
  1201. } else if (Below(v->p, vprev->p) && Below(v->p, vnext->p)) {
  1202. if (IsConvex(vnext->p, vprev->p, v->p)) {
  1203. vertextypes[i] = TPPL_VERTEXTYPE_END;
  1204. } else {
  1205. vertextypes[i] = TPPL_VERTEXTYPE_MERGE;
  1206. }
  1207. } else {
  1208. vertextypes[i] = TPPL_VERTEXTYPE_REGULAR;
  1209. }
  1210. }
  1211. // Helpers.
  1212. long *helpers = new long[maxnumvertices];
  1213. // Binary search tree that holds edges intersecting the scanline.
  1214. // Note that while set doesn't actually have to be implemented as
  1215. // a tree, complexity requirements for operations are the same as
  1216. // for the balanced binary search tree.
  1217. RBSet<ScanLineEdge> edgeTree;
  1218. // Store iterators to the edge tree elements.
  1219. // This makes deleting existing edges much faster.
  1220. RBSet<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter;
  1221. edgeTreeIterators = new RBSet<ScanLineEdge>::Element *[maxnumvertices];
  1222. //Pair<RBSet<ScanLineEdge>::iterator, bool> edgeTreeRet;
  1223. for (i = 0; i < numvertices; i++) {
  1224. edgeTreeIterators[i] = nullptr;
  1225. }
  1226. // For each vertex.
  1227. for (i = 0; i < numvertices; i++) {
  1228. vindex = priority[i];
  1229. v = &(vertices[vindex]);
  1230. vindex2 = vindex;
  1231. v2 = v;
  1232. // Depending on the vertex type, do the appropriate action.
  1233. // Comments in the following sections are copied from
  1234. // "Computational Geometry: Algorithms and Applications".
  1235. // Notation: e_i = e subscript i, v_i = v subscript i, etc.
  1236. switch (vertextypes[vindex]) {
  1237. case TPPL_VERTEXTYPE_START:
  1238. // Insert e_i in T and set helper(e_i) to v_i.
  1239. newedge.p1 = v->p;
  1240. newedge.p2 = vertices[v->next].p;
  1241. newedge.index = vindex;
  1242. //edgeTreeRet = edgeTree.insert(newedge);
  1243. //edgeTreeIterators[vindex] = edgeTreeRet.first;
  1244. edgeTreeIterators[vindex] = edgeTree.insert(newedge);
  1245. helpers[vindex] = vindex;
  1246. break;
  1247. case TPPL_VERTEXTYPE_END:
  1248. if (edgeTreeIterators[v->previous] == edgeTree.back()) {
  1249. error = true;
  1250. break;
  1251. }
  1252. // If helper(e_i - 1) is a merge vertex
  1253. if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
  1254. // Insert the diagonal connecting vi to helper(e_i - 1) in D.
  1255. AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
  1256. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1257. }
  1258. // Delete e_i - 1 from T
  1259. edgeTree.erase(edgeTreeIterators[v->previous]);
  1260. break;
  1261. case TPPL_VERTEXTYPE_SPLIT:
  1262. // Search in T to find the edge e_j directly left of v_i.
  1263. newedge.p1 = v->p;
  1264. newedge.p2 = v->p;
  1265. edgeIter = edgeTree.lower_bound(newedge);
  1266. if (edgeIter == nullptr || edgeIter == edgeTree.front()) {
  1267. error = true;
  1268. break;
  1269. }
  1270. edgeIter--;
  1271. // Insert the diagonal connecting vi to helper(e_j) in D.
  1272. AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
  1273. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1274. vindex2 = newnumvertices - 2;
  1275. v2 = &(vertices[vindex2]);
  1276. // helper(e_j) in v_i.
  1277. helpers[edgeIter->get().index] = vindex;
  1278. // Insert e_i in T and set helper(e_i) to v_i.
  1279. newedge.p1 = v2->p;
  1280. newedge.p2 = vertices[v2->next].p;
  1281. newedge.index = vindex2;
  1282. //edgeTreeRet = edgeTree.insert(newedge);
  1283. //edgeTreeIterators[vindex2] = edgeTreeRet.first;
  1284. edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
  1285. helpers[vindex2] = vindex2;
  1286. break;
  1287. case TPPL_VERTEXTYPE_MERGE:
  1288. if (edgeTreeIterators[v->previous] == edgeTree.back()) {
  1289. error = true;
  1290. break;
  1291. }
  1292. // if helper(e_i - 1) is a merge vertex
  1293. if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
  1294. // Insert the diagonal connecting vi to helper(e_i - 1) in D.
  1295. AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
  1296. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1297. vindex2 = newnumvertices - 2;
  1298. v2 = &(vertices[vindex2]);
  1299. }
  1300. // Delete e_i - 1 from T.
  1301. edgeTree.erase(edgeTreeIterators[v->previous]);
  1302. // Search in T to find the edge e_j directly left of v_i.
  1303. newedge.p1 = v->p;
  1304. newedge.p2 = v->p;
  1305. edgeIter = edgeTree.lower_bound(newedge);
  1306. if (edgeIter == nullptr || edgeIter == edgeTree.front()) {
  1307. error = true;
  1308. break;
  1309. }
  1310. edgeIter--;
  1311. // If helper(e_j) is a merge vertex.
  1312. if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
  1313. // Insert the diagonal connecting v_i to helper(e_j) in D.
  1314. AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index],
  1315. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1316. }
  1317. // helper(e_j) <- v_i
  1318. helpers[edgeIter->get().index] = vindex2;
  1319. break;
  1320. case TPPL_VERTEXTYPE_REGULAR:
  1321. // If the interior of P lies to the right of v_i.
  1322. if (Below(v->p, vertices[v->previous].p)) {
  1323. if (edgeTreeIterators[v->previous] == edgeTree.back()) {
  1324. error = true;
  1325. break;
  1326. }
  1327. // If helper(e_i - 1) is a merge vertex.
  1328. if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
  1329. // Insert the diagonal connecting v_i to helper(e_i - 1) in D.
  1330. AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
  1331. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1332. vindex2 = newnumvertices - 2;
  1333. v2 = &(vertices[vindex2]);
  1334. }
  1335. // Delete e_i - 1 from T.
  1336. edgeTree.erase(edgeTreeIterators[v->previous]);
  1337. // Insert e_i in T and set helper(e_i) to v_i.
  1338. newedge.p1 = v2->p;
  1339. newedge.p2 = vertices[v2->next].p;
  1340. newedge.index = vindex2;
  1341. //edgeTreeRet = edgeTree.insert(newedge);
  1342. //edgeTreeIterators[vindex2] = edgeTreeRet.first;
  1343. edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
  1344. helpers[vindex2] = vindex;
  1345. } else {
  1346. // Search in T to find the edge e_j directly left of v_i.
  1347. newedge.p1 = v->p;
  1348. newedge.p2 = v->p;
  1349. edgeIter = edgeTree.lower_bound(newedge);
  1350. if (edgeIter == nullptr || edgeIter == edgeTree.front()) {
  1351. error = true;
  1352. break;
  1353. }
  1354. edgeIter = edgeIter->prev();
  1355. // If helper(e_j) is a merge vertex.
  1356. if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
  1357. // Insert the diagonal connecting v_i to helper(e_j) in D.
  1358. AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
  1359. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1360. }
  1361. // helper(e_j) <- v_i.
  1362. helpers[edgeIter->get().index] = vindex;
  1363. }
  1364. break;
  1365. }
  1366. if (error)
  1367. break;
  1368. }
  1369. char *used = new char[newnumvertices];
  1370. memset(used, 0, newnumvertices * sizeof(char));
  1371. if (!error) {
  1372. // Return result.
  1373. long size;
  1374. TPPLPoly mpoly;
  1375. for (i = 0; i < newnumvertices; i++) {
  1376. if (used[i]) {
  1377. continue;
  1378. }
  1379. v = &(vertices[i]);
  1380. vnext = &(vertices[v->next]);
  1381. size = 1;
  1382. while (vnext != v) {
  1383. vnext = &(vertices[vnext->next]);
  1384. size++;
  1385. }
  1386. mpoly.Init(size);
  1387. v = &(vertices[i]);
  1388. mpoly[0] = v->p;
  1389. vnext = &(vertices[v->next]);
  1390. size = 1;
  1391. used[i] = 1;
  1392. used[v->next] = 1;
  1393. while (vnext != v) {
  1394. mpoly[size] = vnext->p;
  1395. used[vnext->next] = 1;
  1396. vnext = &(vertices[vnext->next]);
  1397. size++;
  1398. }
  1399. monotonePolys->push_back(mpoly);
  1400. }
  1401. }
  1402. // Cleanup.
  1403. delete[] vertices;
  1404. delete[] priority;
  1405. delete[] vertextypes;
  1406. delete[] edgeTreeIterators;
  1407. delete[] helpers;
  1408. delete[] used;
  1409. if (error) {
  1410. return 0;
  1411. } else {
  1412. return 1;
  1413. }
  1414. }
  1415. // Adds a diagonal to the doubly-connected list of vertices.
  1416. void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
  1417. TPPLVertexType *vertextypes, RBSet<ScanLineEdge>::Element **edgeTreeIterators,
  1418. RBSet<ScanLineEdge> *edgeTree, long *helpers) {
  1419. long newindex1, newindex2;
  1420. newindex1 = *numvertices;
  1421. (*numvertices)++;
  1422. newindex2 = *numvertices;
  1423. (*numvertices)++;
  1424. vertices[newindex1].p = vertices[index1].p;
  1425. vertices[newindex2].p = vertices[index2].p;
  1426. vertices[newindex2].next = vertices[index2].next;
  1427. vertices[newindex1].next = vertices[index1].next;
  1428. vertices[vertices[index2].next].previous = newindex2;
  1429. vertices[vertices[index1].next].previous = newindex1;
  1430. vertices[index1].next = newindex2;
  1431. vertices[newindex2].previous = index1;
  1432. vertices[index2].next = newindex1;
  1433. vertices[newindex1].previous = index2;
  1434. // Update all relevant structures.
  1435. vertextypes[newindex1] = vertextypes[index1];
  1436. edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
  1437. helpers[newindex1] = helpers[index1];
  1438. if (edgeTreeIterators[newindex1] != edgeTree->back()) {
  1439. edgeTreeIterators[newindex1]->get().index = newindex1;
  1440. }
  1441. vertextypes[newindex2] = vertextypes[index2];
  1442. edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
  1443. helpers[newindex2] = helpers[index2];
  1444. if (edgeTreeIterators[newindex2] != edgeTree->back()) {
  1445. edgeTreeIterators[newindex2]->get().index = newindex2;
  1446. }
  1447. }
  1448. bool TPPLPartition::Below(TPPLPoint &p1, TPPLPoint &p2) {
  1449. if (p1.y < p2.y) {
  1450. return true;
  1451. } else if (p1.y == p2.y) {
  1452. if (p1.x < p2.x) {
  1453. return true;
  1454. }
  1455. }
  1456. return false;
  1457. }
  1458. // Sorts in the falling order of y values, if y is equal, x is used instead.
  1459. bool TPPLPartition::VertexSorter::operator()(long index1, long index2) {
  1460. if (vertices[index1].p.y > vertices[index2].p.y) {
  1461. return true;
  1462. } else if (vertices[index1].p.y == vertices[index2].p.y) {
  1463. if (vertices[index1].p.x > vertices[index2].p.x) {
  1464. return true;
  1465. }
  1466. }
  1467. return false;
  1468. }
  1469. bool TPPLPartition::ScanLineEdge::IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const {
  1470. tppl_float tmp;
  1471. tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
  1472. if (tmp > 0) {
  1473. return 1;
  1474. }
  1475. return 0;
  1476. }
  1477. bool TPPLPartition::ScanLineEdge::operator<(const ScanLineEdge &other) const {
  1478. if (other.p1.y == other.p2.y) {
  1479. if (p1.y == p2.y) {
  1480. return (p1.y < other.p1.y);
  1481. }
  1482. return IsConvex(p1, p2, other.p1);
  1483. } else if (p1.y == p2.y) {
  1484. return !IsConvex(other.p1, other.p2, p1);
  1485. } else if (p1.y < other.p1.y) {
  1486. return !IsConvex(other.p1, other.p2, p1);
  1487. } else {
  1488. return IsConvex(p1, p2, other.p1);
  1489. }
  1490. }
  1491. // Triangulates monotone polygon.
  1492. // Time complexity: O(n)
  1493. // Space complexity: O(n)
  1494. int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles) {
  1495. if (!inPoly->Valid()) {
  1496. return 0;
  1497. }
  1498. long i, i2, j, topindex, bottomindex, leftindex, rightindex, vindex;
  1499. TPPLPoint *points = NULL;
  1500. long numpoints;
  1501. TPPLPoly triangle;
  1502. numpoints = inPoly->GetNumPoints();
  1503. points = inPoly->GetPoints();
  1504. // Trivial case.
  1505. if (numpoints == 3) {
  1506. triangles->push_back(*inPoly);
  1507. return 1;
  1508. }
  1509. topindex = 0;
  1510. bottomindex = 0;
  1511. for (i = 1; i < numpoints; i++) {
  1512. if (Below(points[i], points[bottomindex])) {
  1513. bottomindex = i;
  1514. }
  1515. if (Below(points[topindex], points[i])) {
  1516. topindex = i;
  1517. }
  1518. }
  1519. // Check if the poly is really monotone.
  1520. i = topindex;
  1521. while (i != bottomindex) {
  1522. i2 = i + 1;
  1523. if (i2 >= numpoints) {
  1524. i2 = 0;
  1525. }
  1526. if (!Below(points[i2], points[i])) {
  1527. return 0;
  1528. }
  1529. i = i2;
  1530. }
  1531. i = bottomindex;
  1532. while (i != topindex) {
  1533. i2 = i + 1;
  1534. if (i2 >= numpoints) {
  1535. i2 = 0;
  1536. }
  1537. if (!Below(points[i], points[i2])) {
  1538. return 0;
  1539. }
  1540. i = i2;
  1541. }
  1542. char *vertextypes = new char[numpoints];
  1543. long *priority = new long[numpoints];
  1544. // Merge left and right vertex chains.
  1545. priority[0] = topindex;
  1546. vertextypes[topindex] = 0;
  1547. leftindex = topindex + 1;
  1548. if (leftindex >= numpoints) {
  1549. leftindex = 0;
  1550. }
  1551. rightindex = topindex - 1;
  1552. if (rightindex < 0) {
  1553. rightindex = numpoints - 1;
  1554. }
  1555. for (i = 1; i < (numpoints - 1); i++) {
  1556. if (leftindex == bottomindex) {
  1557. priority[i] = rightindex;
  1558. rightindex--;
  1559. if (rightindex < 0) {
  1560. rightindex = numpoints - 1;
  1561. }
  1562. vertextypes[priority[i]] = -1;
  1563. } else if (rightindex == bottomindex) {
  1564. priority[i] = leftindex;
  1565. leftindex++;
  1566. if (leftindex >= numpoints) {
  1567. leftindex = 0;
  1568. }
  1569. vertextypes[priority[i]] = 1;
  1570. } else {
  1571. if (Below(points[leftindex], points[rightindex])) {
  1572. priority[i] = rightindex;
  1573. rightindex--;
  1574. if (rightindex < 0) {
  1575. rightindex = numpoints - 1;
  1576. }
  1577. vertextypes[priority[i]] = -1;
  1578. } else {
  1579. priority[i] = leftindex;
  1580. leftindex++;
  1581. if (leftindex >= numpoints) {
  1582. leftindex = 0;
  1583. }
  1584. vertextypes[priority[i]] = 1;
  1585. }
  1586. }
  1587. }
  1588. priority[i] = bottomindex;
  1589. vertextypes[bottomindex] = 0;
  1590. long *stack = new long[numpoints];
  1591. long stackptr = 0;
  1592. stack[0] = priority[0];
  1593. stack[1] = priority[1];
  1594. stackptr = 2;
  1595. // For each vertex from top to bottom trim as many triangles as possible.
  1596. for (i = 2; i < (numpoints - 1); i++) {
  1597. vindex = priority[i];
  1598. if (vertextypes[vindex] != vertextypes[stack[stackptr - 1]]) {
  1599. for (j = 0; j < (stackptr - 1); j++) {
  1600. if (vertextypes[vindex] == 1) {
  1601. triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]);
  1602. } else {
  1603. triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]);
  1604. }
  1605. triangles->push_back(triangle);
  1606. }
  1607. stack[0] = priority[i - 1];
  1608. stack[1] = priority[i];
  1609. stackptr = 2;
  1610. } else {
  1611. stackptr--;
  1612. while (stackptr > 0) {
  1613. if (vertextypes[vindex] == 1) {
  1614. if (IsConvex(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]])) {
  1615. triangle.Triangle(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]]);
  1616. triangles->push_back(triangle);
  1617. stackptr--;
  1618. } else {
  1619. break;
  1620. }
  1621. } else {
  1622. if (IsConvex(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]])) {
  1623. triangle.Triangle(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]]);
  1624. triangles->push_back(triangle);
  1625. stackptr--;
  1626. } else {
  1627. break;
  1628. }
  1629. }
  1630. }
  1631. stackptr++;
  1632. stack[stackptr] = vindex;
  1633. stackptr++;
  1634. }
  1635. }
  1636. vindex = priority[i];
  1637. for (j = 0; j < (stackptr - 1); j++) {
  1638. if (vertextypes[stack[j + 1]] == 1) {
  1639. triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]);
  1640. } else {
  1641. triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]);
  1642. }
  1643. triangles->push_back(triangle);
  1644. }
  1645. delete[] priority;
  1646. delete[] vertextypes;
  1647. delete[] stack;
  1648. return 1;
  1649. }
  1650. int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
  1651. TPPLPolyList monotone;
  1652. TPPLPolyList::Element *iter;
  1653. if (!MonotonePartition(inpolys, &monotone)) {
  1654. return 0;
  1655. }
  1656. for (iter = monotone.front(); iter; iter = iter->next()) {
  1657. if (!TriangulateMonotone(&(iter->get()), triangles)) {
  1658. return 0;
  1659. }
  1660. }
  1661. return 1;
  1662. }
  1663. int TPPLPartition::Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles) {
  1664. TPPLPolyList polys;
  1665. polys.push_back(*poly);
  1666. return Triangulate_MONO(&polys, triangles);
  1667. }