triangulator.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543
  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. #include <stdio.h>
  21. #include <string.h>
  22. #include <math.h>
  23. #include <algorithm>
  24. #include "triangulator.h"
  25. using namespace std;
  26. #define TRIANGULATOR_VERTEXTYPE_REGULAR 0
  27. #define TRIANGULATOR_VERTEXTYPE_START 1
  28. #define TRIANGULATOR_VERTEXTYPE_END 2
  29. #define TRIANGULATOR_VERTEXTYPE_SPLIT 3
  30. #define TRIANGULATOR_VERTEXTYPE_MERGE 4
  31. TriangulatorPoly::TriangulatorPoly() {
  32. hole = false;
  33. numpoints = 0;
  34. points = NULL;
  35. }
  36. TriangulatorPoly::~TriangulatorPoly() {
  37. if(points) delete [] points;
  38. }
  39. void TriangulatorPoly::Clear() {
  40. if(points) delete [] points;
  41. hole = false;
  42. numpoints = 0;
  43. points = NULL;
  44. }
  45. void TriangulatorPoly::Init(long numpoints) {
  46. Clear();
  47. this->numpoints = numpoints;
  48. points = new Vector2[numpoints];
  49. }
  50. void TriangulatorPoly::Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3) {
  51. Init(3);
  52. points[0] = p1;
  53. points[1] = p2;
  54. points[2] = p3;
  55. }
  56. TriangulatorPoly::TriangulatorPoly(const TriangulatorPoly &src) {
  57. hole = src.hole;
  58. numpoints = src.numpoints;
  59. points = new Vector2[numpoints];
  60. memcpy(points, src.points, numpoints*sizeof(Vector2));
  61. }
  62. TriangulatorPoly& TriangulatorPoly::operator=(const TriangulatorPoly &src) {
  63. Clear();
  64. hole = src.hole;
  65. numpoints = src.numpoints;
  66. points = new Vector2[numpoints];
  67. memcpy(points, src.points, numpoints*sizeof(Vector2));
  68. return *this;
  69. }
  70. int TriangulatorPoly::GetOrientation() {
  71. long i1,i2;
  72. real_t area = 0;
  73. for(i1=0; i1<numpoints; i1++) {
  74. i2 = i1+1;
  75. if(i2 == numpoints) i2 = 0;
  76. area += points[i1].x * points[i2].y - points[i1].y * points[i2].x;
  77. }
  78. if(area>0) return TRIANGULATOR_CCW;
  79. if(area<0) return TRIANGULATOR_CW;
  80. return 0;
  81. }
  82. void TriangulatorPoly::SetOrientation(int orientation) {
  83. int polyorientation = GetOrientation();
  84. if(polyorientation&&(polyorientation!=orientation)) {
  85. Invert();
  86. }
  87. }
  88. void TriangulatorPoly::Invert() {
  89. long i;
  90. Vector2 *invpoints;
  91. invpoints = new Vector2[numpoints];
  92. for(i=0;i<numpoints;i++) {
  93. invpoints[i] = points[numpoints-i-1];
  94. }
  95. delete [] points;
  96. points = invpoints;
  97. }
  98. Vector2 TriangulatorPartition::Normalize(const Vector2 &p) {
  99. Vector2 r;
  100. real_t n = sqrt(p.x*p.x + p.y*p.y);
  101. if(n!=0) {
  102. r = p/n;
  103. } else {
  104. r.x = 0;
  105. r.y = 0;
  106. }
  107. return r;
  108. }
  109. real_t TriangulatorPartition::Distance(const Vector2 &p1, const Vector2 &p2) {
  110. real_t dx,dy;
  111. dx = p2.x - p1.x;
  112. dy = p2.y - p1.y;
  113. return(sqrt(dx*dx + dy*dy));
  114. }
  115. //checks if two lines intersect
  116. int TriangulatorPartition::Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22) {
  117. if((p11.x == p21.x)&&(p11.y == p21.y)) return 0;
  118. if((p11.x == p22.x)&&(p11.y == p22.y)) return 0;
  119. if((p12.x == p21.x)&&(p12.y == p21.y)) return 0;
  120. if((p12.x == p22.x)&&(p12.y == p22.y)) return 0;
  121. Vector2 v1ort,v2ort,v;
  122. real_t dot11,dot12,dot21,dot22;
  123. v1ort.x = p12.y-p11.y;
  124. v1ort.y = p11.x-p12.x;
  125. v2ort.x = p22.y-p21.y;
  126. v2ort.y = p21.x-p22.x;
  127. v = p21-p11;
  128. dot21 = v.x*v1ort.x + v.y*v1ort.y;
  129. v = p22-p11;
  130. dot22 = v.x*v1ort.x + v.y*v1ort.y;
  131. v = p11-p21;
  132. dot11 = v.x*v2ort.x + v.y*v2ort.y;
  133. v = p12-p21;
  134. dot12 = v.x*v2ort.x + v.y*v2ort.y;
  135. if(dot11*dot12>0) return 0;
  136. if(dot21*dot22>0) return 0;
  137. return 1;
  138. }
  139. //removes holes from inpolys by merging them with non-holes
  140. int TriangulatorPartition::RemoveHoles(list<TriangulatorPoly> *inpolys, list<TriangulatorPoly> *outpolys) {
  141. list<TriangulatorPoly> polys;
  142. list<TriangulatorPoly>::iterator holeiter,polyiter,iter,iter2;
  143. long i,i2,holepointindex,polypointindex;
  144. Vector2 holepoint,polypoint,bestpolypoint;
  145. Vector2 linep1,linep2;
  146. Vector2 v1,v2;
  147. TriangulatorPoly newpoly;
  148. bool hasholes;
  149. bool pointvisible;
  150. bool pointfound;
  151. //check for trivial case (no holes)
  152. hasholes = false;
  153. for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) {
  154. if(iter->IsHole()) {
  155. hasholes = true;
  156. break;
  157. }
  158. }
  159. if(!hasholes) {
  160. for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) {
  161. outpolys->push_back(*iter);
  162. }
  163. return 1;
  164. }
  165. polys = *inpolys;
  166. while(1) {
  167. //find the hole point with the largest x
  168. hasholes = false;
  169. for(iter = polys.begin(); iter!=polys.end(); iter++) {
  170. if(!iter->IsHole()) continue;
  171. if(!hasholes) {
  172. hasholes = true;
  173. holeiter = iter;
  174. holepointindex = 0;
  175. }
  176. for(i=0; i < iter->GetNumPoints(); i++) {
  177. if(iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) {
  178. holeiter = iter;
  179. holepointindex = i;
  180. }
  181. }
  182. }
  183. if(!hasholes) break;
  184. holepoint = holeiter->GetPoint(holepointindex);
  185. pointfound = false;
  186. for(iter = polys.begin(); iter!=polys.end(); iter++) {
  187. if(iter->IsHole()) continue;
  188. for(i=0; i < iter->GetNumPoints(); i++) {
  189. if(iter->GetPoint(i).x <= holepoint.x) continue;
  190. if(!InCone(iter->GetPoint((i+iter->GetNumPoints()-1)%(iter->GetNumPoints())),
  191. iter->GetPoint(i),
  192. iter->GetPoint((i+1)%(iter->GetNumPoints())),
  193. holepoint))
  194. continue;
  195. polypoint = iter->GetPoint(i);
  196. if(pointfound) {
  197. v1 = Normalize(polypoint-holepoint);
  198. v2 = Normalize(bestpolypoint-holepoint);
  199. if(v2.x > v1.x) continue;
  200. }
  201. pointvisible = true;
  202. for(iter2 = polys.begin(); iter2!=polys.end(); iter2++) {
  203. if(iter2->IsHole()) continue;
  204. for(i2=0; i2 < iter2->GetNumPoints(); i2++) {
  205. linep1 = iter2->GetPoint(i2);
  206. linep2 = iter2->GetPoint((i2+1)%(iter2->GetNumPoints()));
  207. if(Intersects(holepoint,polypoint,linep1,linep2)) {
  208. pointvisible = false;
  209. break;
  210. }
  211. }
  212. if(!pointvisible) break;
  213. }
  214. if(pointvisible) {
  215. pointfound = true;
  216. bestpolypoint = polypoint;
  217. polyiter = iter;
  218. polypointindex = i;
  219. }
  220. }
  221. }
  222. if(!pointfound) return 0;
  223. newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2);
  224. i2 = 0;
  225. for(i=0;i<=polypointindex;i++) {
  226. newpoly[i2] = polyiter->GetPoint(i);
  227. i2++;
  228. }
  229. for(i=0;i<=holeiter->GetNumPoints();i++) {
  230. newpoly[i2] = holeiter->GetPoint((i+holepointindex)%holeiter->GetNumPoints());
  231. i2++;
  232. }
  233. for(i=polypointindex;i<polyiter->GetNumPoints();i++) {
  234. newpoly[i2] = polyiter->GetPoint(i);
  235. i2++;
  236. }
  237. polys.erase(holeiter);
  238. polys.erase(polyiter);
  239. polys.push_back(newpoly);
  240. }
  241. for(iter = polys.begin(); iter!=polys.end(); iter++) {
  242. outpolys->push_back(*iter);
  243. }
  244. return 1;
  245. }
  246. bool TriangulatorPartition::IsConvex(Vector2& p1, Vector2& p2, Vector2& p3) {
  247. real_t tmp;
  248. tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
  249. if(tmp>0) return 1;
  250. else return 0;
  251. }
  252. bool TriangulatorPartition::IsReflex(Vector2& p1, Vector2& p2, Vector2& p3) {
  253. real_t tmp;
  254. tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
  255. if(tmp<0) return 1;
  256. else return 0;
  257. }
  258. bool TriangulatorPartition::IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p) {
  259. if(IsConvex(p1,p,p2)) return false;
  260. if(IsConvex(p2,p,p3)) return false;
  261. if(IsConvex(p3,p,p1)) return false;
  262. return true;
  263. }
  264. bool TriangulatorPartition::InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p) {
  265. bool convex;
  266. convex = IsConvex(p1,p2,p3);
  267. if(convex) {
  268. if(!IsConvex(p1,p2,p)) return false;
  269. if(!IsConvex(p2,p3,p)) return false;
  270. return true;
  271. } else {
  272. if(IsConvex(p1,p2,p)) return true;
  273. if(IsConvex(p2,p3,p)) return true;
  274. return false;
  275. }
  276. }
  277. bool TriangulatorPartition::InCone(PartitionVertex *v, Vector2 &p) {
  278. Vector2 p1,p2,p3;
  279. p1 = v->previous->p;
  280. p2 = v->p;
  281. p3 = v->next->p;
  282. return InCone(p1,p2,p3,p);
  283. }
  284. void TriangulatorPartition::UpdateVertexReflexity(PartitionVertex *v) {
  285. PartitionVertex *v1,*v3;
  286. v1 = v->previous;
  287. v3 = v->next;
  288. v->isConvex = !IsReflex(v1->p,v->p,v3->p);
  289. }
  290. void TriangulatorPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) {
  291. long i;
  292. PartitionVertex *v1,*v3;
  293. Vector2 vec1,vec3;
  294. v1 = v->previous;
  295. v3 = v->next;
  296. v->isConvex = IsConvex(v1->p,v->p,v3->p);
  297. vec1 = Normalize(v1->p - v->p);
  298. vec3 = Normalize(v3->p - v->p);
  299. v->angle = vec1.x*vec3.x + vec1.y*vec3.y;
  300. if(v->isConvex) {
  301. v->isEar = true;
  302. for(i=0;i<numvertices;i++) {
  303. if((vertices[i].p.x==v->p.x)&&(vertices[i].p.y==v->p.y)) continue;
  304. if((vertices[i].p.x==v1->p.x)&&(vertices[i].p.y==v1->p.y)) continue;
  305. if((vertices[i].p.x==v3->p.x)&&(vertices[i].p.y==v3->p.y)) continue;
  306. if(IsInside(v1->p,v->p,v3->p,vertices[i].p)) {
  307. v->isEar = false;
  308. break;
  309. }
  310. }
  311. } else {
  312. v->isEar = false;
  313. }
  314. }
  315. //triangulation by ear removal
  316. int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, list<TriangulatorPoly> *triangles) {
  317. long numvertices;
  318. PartitionVertex *vertices;
  319. PartitionVertex *ear;
  320. TriangulatorPoly triangle;
  321. long i,j;
  322. bool earfound;
  323. if(poly->GetNumPoints() < 3) return 0;
  324. if(poly->GetNumPoints() == 3) {
  325. triangles->push_back(*poly);
  326. return 1;
  327. }
  328. numvertices = poly->GetNumPoints();
  329. vertices = new PartitionVertex[numvertices];
  330. for(i=0;i<numvertices;i++) {
  331. vertices[i].isActive = true;
  332. vertices[i].p = poly->GetPoint(i);
  333. if(i==(numvertices-1)) vertices[i].next=&(vertices[0]);
  334. else vertices[i].next=&(vertices[i+1]);
  335. if(i==0) vertices[i].previous = &(vertices[numvertices-1]);
  336. else vertices[i].previous = &(vertices[i-1]);
  337. }
  338. for(i=0;i<numvertices;i++) {
  339. UpdateVertex(&vertices[i],vertices,numvertices);
  340. }
  341. for(i=0;i<numvertices-3;i++) {
  342. earfound = false;
  343. //find the most extruded ear
  344. for(j=0;j<numvertices;j++) {
  345. if(!vertices[j].isActive) continue;
  346. if(!vertices[j].isEar) continue;
  347. if(!earfound) {
  348. earfound = true;
  349. ear = &(vertices[j]);
  350. } else {
  351. if(vertices[j].angle > ear->angle) {
  352. ear = &(vertices[j]);
  353. }
  354. }
  355. }
  356. if(!earfound) {
  357. delete [] vertices;
  358. return 0;
  359. }
  360. triangle.Triangle(ear->previous->p,ear->p,ear->next->p);
  361. triangles->push_back(triangle);
  362. ear->isActive = false;
  363. ear->previous->next = ear->next;
  364. ear->next->previous = ear->previous;
  365. if(i==numvertices-4) break;
  366. UpdateVertex(ear->previous,vertices,numvertices);
  367. UpdateVertex(ear->next,vertices,numvertices);
  368. }
  369. for(i=0;i<numvertices;i++) {
  370. if(vertices[i].isActive) {
  371. triangle.Triangle(vertices[i].previous->p,vertices[i].p,vertices[i].next->p);
  372. triangles->push_back(triangle);
  373. break;
  374. }
  375. }
  376. delete [] vertices;
  377. return 1;
  378. }
  379. int TriangulatorPartition::Triangulate_EC(list<TriangulatorPoly> *inpolys, list<TriangulatorPoly> *triangles) {
  380. list<TriangulatorPoly> outpolys;
  381. list<TriangulatorPoly>::iterator iter;
  382. if(!RemoveHoles(inpolys,&outpolys)) return 0;
  383. for(iter=outpolys.begin();iter!=outpolys.end();iter++) {
  384. if(!Triangulate_EC(&(*iter),triangles)) return 0;
  385. }
  386. return 1;
  387. }
  388. int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, list<TriangulatorPoly> *parts) {
  389. list<TriangulatorPoly> triangles;
  390. list<TriangulatorPoly>::iterator iter1,iter2;
  391. TriangulatorPoly *poly1,*poly2;
  392. TriangulatorPoly newpoly;
  393. Vector2 d1,d2,p1,p2,p3;
  394. long i11,i12,i21,i22,i13,i23,j,k;
  395. bool isdiagonal;
  396. long numreflex;
  397. //check if the poly is already convex
  398. numreflex = 0;
  399. for(i11=0;i11<poly->GetNumPoints();i11++) {
  400. if(i11==0) i12 = poly->GetNumPoints()-1;
  401. else i12=i11-1;
  402. if(i11==(poly->GetNumPoints()-1)) i13=0;
  403. else i13=i11+1;
  404. if(IsReflex(poly->GetPoint(i12),poly->GetPoint(i11),poly->GetPoint(i13))) {
  405. numreflex = 1;
  406. break;
  407. }
  408. }
  409. if(numreflex == 0) {
  410. parts->push_back(*poly);
  411. return 1;
  412. }
  413. if(!Triangulate_EC(poly,&triangles)) return 0;
  414. for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
  415. poly1 = &(*iter1);
  416. for(i11=0;i11<poly1->GetNumPoints();i11++) {
  417. d1 = poly1->GetPoint(i11);
  418. i12 = (i11+1)%(poly1->GetNumPoints());
  419. d2 = poly1->GetPoint(i12);
  420. isdiagonal = false;
  421. for(iter2 = iter1; iter2 != triangles.end(); iter2++) {
  422. if(iter1 == iter2) continue;
  423. poly2 = &(*iter2);
  424. for(i21=0;i21<poly2->GetNumPoints();i21++) {
  425. if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue;
  426. i22 = (i21+1)%(poly2->GetNumPoints());
  427. if((d1.x != poly2->GetPoint(i22).x)||(d1.y != poly2->GetPoint(i22).y)) continue;
  428. isdiagonal = true;
  429. break;
  430. }
  431. if(isdiagonal) break;
  432. }
  433. if(!isdiagonal) continue;
  434. p2 = poly1->GetPoint(i11);
  435. if(i11 == 0) i13 = poly1->GetNumPoints()-1;
  436. else i13 = i11-1;
  437. p1 = poly1->GetPoint(i13);
  438. if(i22 == (poly2->GetNumPoints()-1)) i23 = 0;
  439. else i23 = i22+1;
  440. p3 = poly2->GetPoint(i23);
  441. if(!IsConvex(p1,p2,p3)) continue;
  442. p2 = poly1->GetPoint(i12);
  443. if(i12 == (poly1->GetNumPoints()-1)) i13 = 0;
  444. else i13 = i12+1;
  445. p3 = poly1->GetPoint(i13);
  446. if(i21 == 0) i23 = poly2->GetNumPoints()-1;
  447. else i23 = i21-1;
  448. p1 = poly2->GetPoint(i23);
  449. if(!IsConvex(p1,p2,p3)) continue;
  450. newpoly.Init(poly1->GetNumPoints()+poly2->GetNumPoints()-2);
  451. k = 0;
  452. for(j=i12;j!=i11;j=(j+1)%(poly1->GetNumPoints())) {
  453. newpoly[k] = poly1->GetPoint(j);
  454. k++;
  455. }
  456. for(j=i22;j!=i21;j=(j+1)%(poly2->GetNumPoints())) {
  457. newpoly[k] = poly2->GetPoint(j);
  458. k++;
  459. }
  460. triangles.erase(iter2);
  461. *iter1 = newpoly;
  462. poly1 = &(*iter1);
  463. i11 = -1;
  464. continue;
  465. }
  466. }
  467. for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
  468. parts->push_back(*iter1);
  469. }
  470. return 1;
  471. }
  472. int TriangulatorPartition::ConvexPartition_HM(list<TriangulatorPoly> *inpolys, list<TriangulatorPoly> *parts) {
  473. list<TriangulatorPoly> outpolys;
  474. list<TriangulatorPoly>::iterator iter;
  475. if(!RemoveHoles(inpolys,&outpolys)) return 0;
  476. for(iter=outpolys.begin();iter!=outpolys.end();iter++) {
  477. if(!ConvexPartition_HM(&(*iter),parts)) return 0;
  478. }
  479. return 1;
  480. }
  481. //minimum-weight polygon triangulation by dynamic programming
  482. //O(n^3) time complexity
  483. //O(n^2) space complexity
  484. int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, list<TriangulatorPoly> *triangles) {
  485. long i,j,k,gap,n;
  486. DPState **dpstates;
  487. Vector2 p1,p2,p3,p4;
  488. long bestvertex;
  489. real_t weight,minweight,d1,d2;
  490. Diagonal diagonal,newdiagonal;
  491. list<Diagonal> diagonals;
  492. TriangulatorPoly triangle;
  493. int ret = 1;
  494. n = poly->GetNumPoints();
  495. dpstates = new DPState *[n];
  496. for(i=1;i<n;i++) {
  497. dpstates[i] = new DPState[i];
  498. }
  499. //init states and visibility
  500. for(i=0;i<(n-1);i++) {
  501. p1 = poly->GetPoint(i);
  502. for(j=i+1;j<n;j++) {
  503. dpstates[j][i].visible = true;
  504. dpstates[j][i].weight = 0;
  505. dpstates[j][i].bestvertex = -1;
  506. if(j!=(i+1)) {
  507. p2 = poly->GetPoint(j);
  508. //visibility check
  509. if(i==0) p3 = poly->GetPoint(n-1);
  510. else p3 = poly->GetPoint(i-1);
  511. if(i==(n-1)) p4 = poly->GetPoint(0);
  512. else p4 = poly->GetPoint(i+1);
  513. if(!InCone(p3,p1,p4,p2)) {
  514. dpstates[j][i].visible = false;
  515. continue;
  516. }
  517. if(j==0) p3 = poly->GetPoint(n-1);
  518. else p3 = poly->GetPoint(j-1);
  519. if(j==(n-1)) p4 = poly->GetPoint(0);
  520. else p4 = poly->GetPoint(j+1);
  521. if(!InCone(p3,p2,p4,p1)) {
  522. dpstates[j][i].visible = false;
  523. continue;
  524. }
  525. for(k=0;k<n;k++) {
  526. p3 = poly->GetPoint(k);
  527. if(k==(n-1)) p4 = poly->GetPoint(0);
  528. else p4 = poly->GetPoint(k+1);
  529. if(Intersects(p1,p2,p3,p4)) {
  530. dpstates[j][i].visible = false;
  531. break;
  532. }
  533. }
  534. }
  535. }
  536. }
  537. dpstates[n-1][0].visible = true;
  538. dpstates[n-1][0].weight = 0;
  539. dpstates[n-1][0].bestvertex = -1;
  540. for(gap = 2; gap<n; gap++) {
  541. for(i=0; i<(n-gap); i++) {
  542. j = i+gap;
  543. if(!dpstates[j][i].visible) continue;
  544. bestvertex = -1;
  545. for(k=(i+1);k<j;k++) {
  546. if(!dpstates[k][i].visible) continue;
  547. if(!dpstates[j][k].visible) continue;
  548. if(k<=(i+1)) d1=0;
  549. else d1 = Distance(poly->GetPoint(i),poly->GetPoint(k));
  550. if(j<=(k+1)) d2=0;
  551. else d2 = Distance(poly->GetPoint(k),poly->GetPoint(j));
  552. weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2;
  553. if((bestvertex == -1)||(weight<minweight)) {
  554. bestvertex = k;
  555. minweight = weight;
  556. }
  557. }
  558. if(bestvertex == -1) {
  559. for(i=1;i<n;i++) {
  560. delete [] dpstates[i];
  561. }
  562. delete [] dpstates;
  563. return 0;
  564. }
  565. dpstates[j][i].bestvertex = bestvertex;
  566. dpstates[j][i].weight = minweight;
  567. }
  568. }
  569. newdiagonal.index1 = 0;
  570. newdiagonal.index2 = n-1;
  571. diagonals.push_back(newdiagonal);
  572. while(!diagonals.empty()) {
  573. diagonal = *(diagonals.begin());
  574. diagonals.pop_front();
  575. bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
  576. if(bestvertex == -1) {
  577. ret = 0;
  578. break;
  579. }
  580. triangle.Triangle(poly->GetPoint(diagonal.index1),poly->GetPoint(bestvertex),poly->GetPoint(diagonal.index2));
  581. triangles->push_back(triangle);
  582. if(bestvertex > (diagonal.index1+1)) {
  583. newdiagonal.index1 = diagonal.index1;
  584. newdiagonal.index2 = bestvertex;
  585. diagonals.push_back(newdiagonal);
  586. }
  587. if(diagonal.index2 > (bestvertex+1)) {
  588. newdiagonal.index1 = bestvertex;
  589. newdiagonal.index2 = diagonal.index2;
  590. diagonals.push_back(newdiagonal);
  591. }
  592. }
  593. for(i=1;i<n;i++) {
  594. delete [] dpstates[i];
  595. }
  596. delete [] dpstates;
  597. return ret;
  598. }
  599. void TriangulatorPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) {
  600. Diagonal newdiagonal;
  601. list<Diagonal> *pairs;
  602. long w2;
  603. w2 = dpstates[a][b].weight;
  604. if(w>w2) return;
  605. pairs = &(dpstates[a][b].pairs);
  606. newdiagonal.index1 = i;
  607. newdiagonal.index2 = j;
  608. if(w<w2) {
  609. pairs->clear();
  610. pairs->push_front(newdiagonal);
  611. dpstates[a][b].weight = w;
  612. } else {
  613. if((!pairs->empty())&&(i <= pairs->begin()->index1)) return;
  614. while((!pairs->empty())&&(pairs->begin()->index2 >= j)) pairs->pop_front();
  615. pairs->push_front(newdiagonal);
  616. }
  617. }
  618. void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
  619. list<Diagonal> *pairs;
  620. list<Diagonal>::iterator iter,lastiter;
  621. long top;
  622. long w;
  623. if(!dpstates[i][j].visible) return;
  624. top = j;
  625. w = dpstates[i][j].weight;
  626. if(k-j > 1) {
  627. if (!dpstates[j][k].visible) return;
  628. w += dpstates[j][k].weight + 1;
  629. }
  630. if(j-i > 1) {
  631. pairs = &(dpstates[i][j].pairs);
  632. iter = pairs->end();
  633. lastiter = pairs->end();
  634. while(iter!=pairs->begin()) {
  635. iter--;
  636. if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter;
  637. else break;
  638. }
  639. if(lastiter == pairs->end()) w++;
  640. else {
  641. if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->index1].p)) w++;
  642. else top = lastiter->index1;
  643. }
  644. }
  645. UpdateState(i,k,w,top,j,dpstates);
  646. }
  647. void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
  648. list<Diagonal> *pairs;
  649. list<Diagonal>::iterator iter,lastiter;
  650. long top;
  651. long w;
  652. if(!dpstates[j][k].visible) return;
  653. top = j;
  654. w = dpstates[j][k].weight;
  655. if (j-i > 1) {
  656. if (!dpstates[i][j].visible) return;
  657. w += dpstates[i][j].weight + 1;
  658. }
  659. if (k-j > 1) {
  660. pairs = &(dpstates[j][k].pairs);
  661. iter = pairs->begin();
  662. if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p))) {
  663. lastiter = iter;
  664. while(iter!=pairs->end()) {
  665. if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) {
  666. lastiter = iter;
  667. iter++;
  668. }
  669. else break;
  670. }
  671. if(IsReflex(vertices[lastiter->index2].p,vertices[k].p,vertices[i].p)) w++;
  672. else top = lastiter->index2;
  673. } else w++;
  674. }
  675. UpdateState(i,k,w,j,top,dpstates);
  676. }
  677. int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, list<TriangulatorPoly> *parts) {
  678. Vector2 p1,p2,p3,p4;
  679. PartitionVertex *vertices;
  680. DPState2 **dpstates;
  681. long i,j,k,n,gap;
  682. list<Diagonal> diagonals,diagonals2;
  683. Diagonal diagonal,newdiagonal;
  684. list<Diagonal> *pairs,*pairs2;
  685. list<Diagonal>::iterator iter,iter2;
  686. int ret;
  687. TriangulatorPoly newpoly;
  688. list<long> indices;
  689. list<long>::iterator iiter;
  690. bool ijreal,jkreal;
  691. n = poly->GetNumPoints();
  692. vertices = new PartitionVertex[n];
  693. dpstates = new DPState2 *[n];
  694. for(i=0;i<n;i++) {
  695. dpstates[i] = new DPState2[n];
  696. }
  697. //init vertex information
  698. for(i=0;i<n;i++) {
  699. vertices[i].p = poly->GetPoint(i);
  700. vertices[i].isActive = true;
  701. if(i==0) vertices[i].previous = &(vertices[n-1]);
  702. else vertices[i].previous = &(vertices[i-1]);
  703. if(i==(poly->GetNumPoints()-1)) vertices[i].next = &(vertices[0]);
  704. else vertices[i].next = &(vertices[i+1]);
  705. }
  706. for(i=1;i<n;i++) {
  707. UpdateVertexReflexity(&(vertices[i]));
  708. }
  709. //init states and visibility
  710. for(i=0;i<(n-1);i++) {
  711. p1 = poly->GetPoint(i);
  712. for(j=i+1;j<n;j++) {
  713. dpstates[i][j].visible = true;
  714. if(j==i+1) {
  715. dpstates[i][j].weight = 0;
  716. } else {
  717. dpstates[i][j].weight = 2147483647;
  718. }
  719. if(j!=(i+1)) {
  720. p2 = poly->GetPoint(j);
  721. //visibility check
  722. if(!InCone(&vertices[i],p2)) {
  723. dpstates[i][j].visible = false;
  724. continue;
  725. }
  726. if(!InCone(&vertices[j],p1)) {
  727. dpstates[i][j].visible = false;
  728. continue;
  729. }
  730. for(k=0;k<n;k++) {
  731. p3 = poly->GetPoint(k);
  732. if(k==(n-1)) p4 = poly->GetPoint(0);
  733. else p4 = poly->GetPoint(k+1);
  734. if(Intersects(p1,p2,p3,p4)) {
  735. dpstates[i][j].visible = false;
  736. break;
  737. }
  738. }
  739. }
  740. }
  741. }
  742. for(i=0;i<(n-2);i++) {
  743. j = i+2;
  744. if(dpstates[i][j].visible) {
  745. dpstates[i][j].weight = 0;
  746. newdiagonal.index1 = i+1;
  747. newdiagonal.index2 = i+1;
  748. dpstates[i][j].pairs.push_back(newdiagonal);
  749. }
  750. }
  751. dpstates[0][n-1].visible = true;
  752. vertices[0].isConvex = false; //by convention
  753. for(gap=3; gap<n; gap++) {
  754. for(i=0;i<n-gap;i++) {
  755. if(vertices[i].isConvex) continue;
  756. k = i+gap;
  757. if(dpstates[i][k].visible) {
  758. if(!vertices[k].isConvex) {
  759. for(j=i+1;j<k;j++) TypeA(i,j,k,vertices,dpstates);
  760. } else {
  761. for(j=i+1;j<(k-1);j++) {
  762. if(vertices[j].isConvex) continue;
  763. TypeA(i,j,k,vertices,dpstates);
  764. }
  765. TypeA(i,k-1,k,vertices,dpstates);
  766. }
  767. }
  768. }
  769. for(k=gap;k<n;k++) {
  770. if(vertices[k].isConvex) continue;
  771. i = k-gap;
  772. if((vertices[i].isConvex)&&(dpstates[i][k].visible)) {
  773. TypeB(i,i+1,k,vertices,dpstates);
  774. for(j=i+2;j<k;j++) {
  775. if(vertices[j].isConvex) continue;
  776. TypeB(i,j,k,vertices,dpstates);
  777. }
  778. }
  779. }
  780. }
  781. //recover solution
  782. ret = 1;
  783. newdiagonal.index1 = 0;
  784. newdiagonal.index2 = n-1;
  785. diagonals.push_front(newdiagonal);
  786. while(!diagonals.empty()) {
  787. diagonal = *(diagonals.begin());
  788. diagonals.pop_front();
  789. if((diagonal.index2 - diagonal.index1) <=1) continue;
  790. pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
  791. if(pairs->empty()) {
  792. ret = 0;
  793. break;
  794. }
  795. if(!vertices[diagonal.index1].isConvex) {
  796. iter = pairs->end();
  797. iter--;
  798. j = iter->index2;
  799. newdiagonal.index1 = j;
  800. newdiagonal.index2 = diagonal.index2;
  801. diagonals.push_front(newdiagonal);
  802. if((j - diagonal.index1)>1) {
  803. if(iter->index1 != iter->index2) {
  804. pairs2 = &(dpstates[diagonal.index1][j].pairs);
  805. while(1) {
  806. if(pairs2->empty()) {
  807. ret = 0;
  808. break;
  809. }
  810. iter2 = pairs2->end();
  811. iter2--;
  812. if(iter->index1 != iter2->index1) pairs2->pop_back();
  813. else break;
  814. }
  815. if(ret == 0) break;
  816. }
  817. newdiagonal.index1 = diagonal.index1;
  818. newdiagonal.index2 = j;
  819. diagonals.push_front(newdiagonal);
  820. }
  821. } else {
  822. iter = pairs->begin();
  823. j = iter->index1;
  824. newdiagonal.index1 = diagonal.index1;
  825. newdiagonal.index2 = j;
  826. diagonals.push_front(newdiagonal);
  827. if((diagonal.index2 - j) > 1) {
  828. if(iter->index1 != iter->index2) {
  829. pairs2 = &(dpstates[j][diagonal.index2].pairs);
  830. while(1) {
  831. if(pairs2->empty()) {
  832. ret = 0;
  833. break;
  834. }
  835. iter2 = pairs2->begin();
  836. if(iter->index2 != iter2->index2) pairs2->pop_front();
  837. else break;
  838. }
  839. if(ret == 0) break;
  840. }
  841. newdiagonal.index1 = j;
  842. newdiagonal.index2 = diagonal.index2;
  843. diagonals.push_front(newdiagonal);
  844. }
  845. }
  846. }
  847. if(ret == 0) {
  848. for(i=0;i<n;i++) {
  849. delete [] dpstates[i];
  850. }
  851. delete [] dpstates;
  852. delete [] vertices;
  853. return ret;
  854. }
  855. newdiagonal.index1 = 0;
  856. newdiagonal.index2 = n-1;
  857. diagonals.push_front(newdiagonal);
  858. while(!diagonals.empty()) {
  859. diagonal = *(diagonals.begin());
  860. diagonals.pop_front();
  861. if((diagonal.index2 - diagonal.index1) <= 1) continue;
  862. indices.clear();
  863. diagonals2.clear();
  864. indices.push_back(diagonal.index1);
  865. indices.push_back(diagonal.index2);
  866. diagonals2.push_front(diagonal);
  867. while(!diagonals2.empty()) {
  868. diagonal = *(diagonals2.begin());
  869. diagonals2.pop_front();
  870. if((diagonal.index2 - diagonal.index1) <= 1) continue;
  871. ijreal = true;
  872. jkreal = true;
  873. pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
  874. if(!vertices[diagonal.index1].isConvex) {
  875. iter = pairs->end();
  876. iter--;
  877. j = iter->index2;
  878. if(iter->index1 != iter->index2) ijreal = false;
  879. } else {
  880. iter = pairs->begin();
  881. j = iter->index1;
  882. if(iter->index1 != iter->index2) jkreal = false;
  883. }
  884. newdiagonal.index1 = diagonal.index1;
  885. newdiagonal.index2 = j;
  886. if(ijreal) {
  887. diagonals.push_back(newdiagonal);
  888. } else {
  889. diagonals2.push_back(newdiagonal);
  890. }
  891. newdiagonal.index1 = j;
  892. newdiagonal.index2 = diagonal.index2;
  893. if(jkreal) {
  894. diagonals.push_back(newdiagonal);
  895. } else {
  896. diagonals2.push_back(newdiagonal);
  897. }
  898. indices.push_back(j);
  899. }
  900. indices.sort();
  901. newpoly.Init((long)indices.size());
  902. k=0;
  903. for(iiter = indices.begin();iiter!=indices.end();iiter++) {
  904. newpoly[k] = vertices[*iiter].p;
  905. k++;
  906. }
  907. parts->push_back(newpoly);
  908. }
  909. for(i=0;i<n;i++) {
  910. delete [] dpstates[i];
  911. }
  912. delete [] dpstates;
  913. delete [] vertices;
  914. return ret;
  915. }
  916. //triangulates a set of polygons by first partitioning them into monotone polygons
  917. //O(n*log(n)) time complexity, O(n) space complexity
  918. //the algorithm used here is outlined in the book
  919. //"Computational Geometry: Algorithms and Applications"
  920. //by Mark de Berg, Otfried Cheong, Marc van Kreveld and Mark Overmars
  921. int TriangulatorPartition::MonotonePartition(list<TriangulatorPoly> *inpolys, list<TriangulatorPoly> *monotonePolys) {
  922. list<TriangulatorPoly>::iterator iter;
  923. MonotoneVertex *vertices;
  924. long i,numvertices,vindex,vindex2,newnumvertices,maxnumvertices;
  925. long polystartindex, polyendindex;
  926. TriangulatorPoly *poly;
  927. MonotoneVertex *v,*v2,*vprev,*vnext;
  928. ScanLineEdge newedge;
  929. bool error = false;
  930. numvertices = 0;
  931. for(iter = inpolys->begin(); iter != inpolys->end(); iter++) {
  932. numvertices += iter->GetNumPoints();
  933. }
  934. maxnumvertices = numvertices*3;
  935. vertices = new MonotoneVertex[maxnumvertices];
  936. newnumvertices = numvertices;
  937. polystartindex = 0;
  938. for(iter = inpolys->begin(); iter != inpolys->end(); iter++) {
  939. poly = &(*iter);
  940. polyendindex = polystartindex + poly->GetNumPoints()-1;
  941. for(i=0;i<poly->GetNumPoints();i++) {
  942. vertices[i+polystartindex].p = poly->GetPoint(i);
  943. if(i==0) vertices[i+polystartindex].previous = polyendindex;
  944. else vertices[i+polystartindex].previous = i+polystartindex-1;
  945. if(i==(poly->GetNumPoints()-1)) vertices[i+polystartindex].next = polystartindex;
  946. else vertices[i+polystartindex].next = i+polystartindex+1;
  947. }
  948. polystartindex = polyendindex+1;
  949. }
  950. //construct the priority queue
  951. long *priority = new long [numvertices];
  952. for(i=0;i<numvertices;i++) priority[i] = i;
  953. std::sort(priority,&(priority[numvertices]),VertexSorter(vertices));
  954. //determine vertex types
  955. char *vertextypes = new char[maxnumvertices];
  956. for(i=0;i<numvertices;i++) {
  957. v = &(vertices[i]);
  958. vprev = &(vertices[v->previous]);
  959. vnext = &(vertices[v->next]);
  960. if(Below(vprev->p,v->p)&&Below(vnext->p,v->p)) {
  961. if(IsConvex(vnext->p,vprev->p,v->p)) {
  962. vertextypes[i] = TRIANGULATOR_VERTEXTYPE_START;
  963. } else {
  964. vertextypes[i] = TRIANGULATOR_VERTEXTYPE_SPLIT;
  965. }
  966. } else if(Below(v->p,vprev->p)&&Below(v->p,vnext->p)) {
  967. if(IsConvex(vnext->p,vprev->p,v->p))
  968. {
  969. vertextypes[i] = TRIANGULATOR_VERTEXTYPE_END;
  970. } else {
  971. vertextypes[i] = TRIANGULATOR_VERTEXTYPE_MERGE;
  972. }
  973. } else {
  974. vertextypes[i] = TRIANGULATOR_VERTEXTYPE_REGULAR;
  975. }
  976. }
  977. //helpers
  978. long *helpers = new long[maxnumvertices];
  979. //binary search tree that holds edges intersecting the scanline
  980. //note that while set doesn't actually have to be implemented as a tree
  981. //complexity requirements for operations are the same as for the balanced binary search tree
  982. set<ScanLineEdge> edgeTree;
  983. //store iterators to the edge tree elements
  984. //this makes deleting existing edges much faster
  985. set<ScanLineEdge>::iterator *edgeTreeIterators,edgeIter;
  986. edgeTreeIterators = new set<ScanLineEdge>::iterator[maxnumvertices];
  987. pair<set<ScanLineEdge>::iterator,bool> edgeTreeRet;
  988. for(i = 0; i<numvertices; i++) edgeTreeIterators[i] = edgeTree.end();
  989. //for each vertex
  990. for(i=0;i<numvertices;i++) {
  991. vindex = priority[i];
  992. v = &(vertices[vindex]);
  993. vindex2 = vindex;
  994. v2 = v;
  995. //depending on the vertex type, do the appropriate action
  996. //comments in the following sections are copied from "Computational Geometry: Algorithms and Applications"
  997. switch(vertextypes[vindex]) {
  998. case TRIANGULATOR_VERTEXTYPE_START:
  999. //Insert ei in T and set helper(ei) to vi.
  1000. newedge.p1 = v->p;
  1001. newedge.p2 = vertices[v->next].p;
  1002. newedge.index = vindex;
  1003. edgeTreeRet = edgeTree.insert(newedge);
  1004. edgeTreeIterators[vindex] = edgeTreeRet.first;
  1005. helpers[vindex] = vindex;
  1006. break;
  1007. case TRIANGULATOR_VERTEXTYPE_END:
  1008. //if helper(ei-1) is a merge vertex
  1009. if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
  1010. //Insert the diagonal connecting vi to helper(ei-1) in D.
  1011. AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
  1012. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1013. }
  1014. //Delete ei-1 from T
  1015. edgeTree.erase(edgeTreeIterators[v->previous]);
  1016. break;
  1017. case TRIANGULATOR_VERTEXTYPE_SPLIT:
  1018. //Search in T to find the edge e j directly left of vi.
  1019. newedge.p1 = v->p;
  1020. newedge.p2 = v->p;
  1021. edgeIter = edgeTree.lower_bound(newedge);
  1022. if(edgeIter == edgeTree.begin()) {
  1023. error = true;
  1024. break;
  1025. }
  1026. edgeIter--;
  1027. //Insert the diagonal connecting vi to helper(ej) in D.
  1028. AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index],
  1029. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1030. vindex2 = newnumvertices-2;
  1031. v2 = &(vertices[vindex2]);
  1032. //helper(e j)�vi
  1033. helpers[edgeIter->index] = vindex;
  1034. //Insert ei in T and set helper(ei) to vi.
  1035. newedge.p1 = v2->p;
  1036. newedge.p2 = vertices[v2->next].p;
  1037. newedge.index = vindex2;
  1038. edgeTreeRet = edgeTree.insert(newedge);
  1039. edgeTreeIterators[vindex2] = edgeTreeRet.first;
  1040. helpers[vindex2] = vindex2;
  1041. break;
  1042. case TRIANGULATOR_VERTEXTYPE_MERGE:
  1043. //if helper(ei-1) is a merge vertex
  1044. if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
  1045. //Insert the diagonal connecting vi to helper(ei-1) in D.
  1046. AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
  1047. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1048. vindex2 = newnumvertices-2;
  1049. v2 = &(vertices[vindex2]);
  1050. }
  1051. //Delete ei-1 from T.
  1052. edgeTree.erase(edgeTreeIterators[v->previous]);
  1053. //Search in T to find the edge e j directly left of vi.
  1054. newedge.p1 = v->p;
  1055. newedge.p2 = v->p;
  1056. edgeIter = edgeTree.lower_bound(newedge);
  1057. if(edgeIter == edgeTree.begin()) {
  1058. error = true;
  1059. break;
  1060. }
  1061. edgeIter--;
  1062. //if helper(ej) is a merge vertex
  1063. if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
  1064. //Insert the diagonal connecting vi to helper(e j) in D.
  1065. AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->index],
  1066. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1067. }
  1068. //helper(e j)�vi
  1069. helpers[edgeIter->index] = vindex2;
  1070. break;
  1071. case TRIANGULATOR_VERTEXTYPE_REGULAR:
  1072. //if the interior of P lies to the right of vi
  1073. if(Below(v->p,vertices[v->previous].p)) {
  1074. //if helper(ei-1) is a merge vertex
  1075. if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
  1076. //Insert the diagonal connecting vi to helper(ei-1) in D.
  1077. AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
  1078. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1079. vindex2 = newnumvertices-2;
  1080. v2 = &(vertices[vindex2]);
  1081. }
  1082. //Delete ei-1 from T.
  1083. edgeTree.erase(edgeTreeIterators[v->previous]);
  1084. //Insert ei in T and set helper(ei) to vi.
  1085. newedge.p1 = v2->p;
  1086. newedge.p2 = vertices[v2->next].p;
  1087. newedge.index = vindex2;
  1088. edgeTreeRet = edgeTree.insert(newedge);
  1089. edgeTreeIterators[vindex2] = edgeTreeRet.first;
  1090. helpers[vindex2] = vindex;
  1091. } else {
  1092. //Search in T to find the edge ej directly left of vi.
  1093. newedge.p1 = v->p;
  1094. newedge.p2 = v->p;
  1095. edgeIter = edgeTree.lower_bound(newedge);
  1096. if(edgeIter == edgeTree.begin()) {
  1097. error = true;
  1098. break;
  1099. }
  1100. edgeIter--;
  1101. //if helper(ej) is a merge vertex
  1102. if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
  1103. //Insert the diagonal connecting vi to helper(e j) in D.
  1104. AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index],
  1105. vertextypes, edgeTreeIterators, &edgeTree, helpers);
  1106. }
  1107. //helper(e j)�vi
  1108. helpers[edgeIter->index] = vindex;
  1109. }
  1110. break;
  1111. }
  1112. if(error) break;
  1113. }
  1114. char *used = new char[newnumvertices];
  1115. memset(used,0,newnumvertices*sizeof(char));
  1116. if(!error) {
  1117. //return result
  1118. long size;
  1119. TriangulatorPoly mpoly;
  1120. for(i=0;i<newnumvertices;i++) {
  1121. if(used[i]) continue;
  1122. v = &(vertices[i]);
  1123. vnext = &(vertices[v->next]);
  1124. size = 1;
  1125. while(vnext!=v) {
  1126. vnext = &(vertices[vnext->next]);
  1127. size++;
  1128. }
  1129. mpoly.Init(size);
  1130. v = &(vertices[i]);
  1131. mpoly[0] = v->p;
  1132. vnext = &(vertices[v->next]);
  1133. size = 1;
  1134. used[i] = 1;
  1135. used[v->next] = 1;
  1136. while(vnext!=v) {
  1137. mpoly[size] = vnext->p;
  1138. used[vnext->next] = 1;
  1139. vnext = &(vertices[vnext->next]);
  1140. size++;
  1141. }
  1142. monotonePolys->push_back(mpoly);
  1143. }
  1144. }
  1145. //cleanup
  1146. delete [] vertices;
  1147. delete [] priority;
  1148. delete [] vertextypes;
  1149. delete [] edgeTreeIterators;
  1150. delete [] helpers;
  1151. delete [] used;
  1152. if(error) {
  1153. return 0;
  1154. } else {
  1155. return 1;
  1156. }
  1157. }
  1158. //adds a diagonal to the doubly-connected list of vertices
  1159. void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
  1160. char *vertextypes, set<ScanLineEdge>::iterator *edgeTreeIterators,
  1161. set<ScanLineEdge> *edgeTree, long *helpers)
  1162. {
  1163. long newindex1,newindex2;
  1164. newindex1 = *numvertices;
  1165. (*numvertices)++;
  1166. newindex2 = *numvertices;
  1167. (*numvertices)++;
  1168. vertices[newindex1].p = vertices[index1].p;
  1169. vertices[newindex2].p = vertices[index2].p;
  1170. vertices[newindex2].next = vertices[index2].next;
  1171. vertices[newindex1].next = vertices[index1].next;
  1172. vertices[vertices[index2].next].previous = newindex2;
  1173. vertices[vertices[index1].next].previous = newindex1;
  1174. vertices[index1].next = newindex2;
  1175. vertices[newindex2].previous = index1;
  1176. vertices[index2].next = newindex1;
  1177. vertices[newindex1].previous = index2;
  1178. //update all relevant structures
  1179. vertextypes[newindex1] = vertextypes[index1];
  1180. edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
  1181. helpers[newindex1] = helpers[index1];
  1182. if(edgeTreeIterators[newindex1] != edgeTree->end())
  1183. edgeTreeIterators[newindex1]->index = newindex1;
  1184. vertextypes[newindex2] = vertextypes[index2];
  1185. edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
  1186. helpers[newindex2] = helpers[index2];
  1187. if(edgeTreeIterators[newindex2] != edgeTree->end())
  1188. edgeTreeIterators[newindex2]->index = newindex2;
  1189. }
  1190. bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) {
  1191. if(p1.y < p2.y) return true;
  1192. else if(p1.y == p2.y) {
  1193. if(p1.x < p2.x) return true;
  1194. }
  1195. return false;
  1196. }
  1197. //sorts in the falling order of y values, if y is equal, x is used instead
  1198. bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) {
  1199. if(vertices[index1].p.y > vertices[index2].p.y) return true;
  1200. else if(vertices[index1].p.y == vertices[index2].p.y) {
  1201. if(vertices[index1].p.x > vertices[index2].p.x) return true;
  1202. }
  1203. return false;
  1204. }
  1205. bool TriangulatorPartition::ScanLineEdge::IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const {
  1206. real_t tmp;
  1207. tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
  1208. if(tmp>0) return 1;
  1209. else return 0;
  1210. }
  1211. bool TriangulatorPartition::ScanLineEdge::operator < (const ScanLineEdge & other) const {
  1212. if(other.p1.y == other.p2.y) {
  1213. if(p1.y == p2.y) {
  1214. if(p1.y < other.p1.y) return true;
  1215. else return false;
  1216. }
  1217. if(IsConvex(p1,p2,other.p1)) return true;
  1218. else return false;
  1219. } else if(p1.y == p2.y) {
  1220. if(IsConvex(other.p1,other.p2,p1)) return false;
  1221. else return true;
  1222. } else if(p1.y < other.p1.y) {
  1223. if(IsConvex(other.p1,other.p2,p1)) return false;
  1224. else return true;
  1225. } else {
  1226. if(IsConvex(p1,p2,other.p1)) return true;
  1227. else return false;
  1228. }
  1229. }
  1230. //triangulates monotone polygon
  1231. //O(n) time, O(n) space complexity
  1232. int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, list<TriangulatorPoly> *triangles) {
  1233. long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex;
  1234. Vector2 *points;
  1235. long numpoints;
  1236. TriangulatorPoly triangle;
  1237. numpoints = inPoly->GetNumPoints();
  1238. points = inPoly->GetPoints();
  1239. //trivial calses
  1240. if(numpoints < 3) return 0;
  1241. if(numpoints == 3) {
  1242. triangles->push_back(*inPoly);
  1243. }
  1244. topindex = 0; bottomindex=0;
  1245. for(i=1;i<numpoints;i++) {
  1246. if(Below(points[i],points[bottomindex])) bottomindex = i;
  1247. if(Below(points[topindex],points[i])) topindex = i;
  1248. }
  1249. //check if the poly is really monotone
  1250. i = topindex;
  1251. while(i!=bottomindex) {
  1252. i2 = i+1; if(i2>=numpoints) i2 = 0;
  1253. if(!Below(points[i2],points[i])) return 0;
  1254. i = i2;
  1255. }
  1256. i = bottomindex;
  1257. while(i!=topindex) {
  1258. i2 = i+1; if(i2>=numpoints) i2 = 0;
  1259. if(!Below(points[i],points[i2])) return 0;
  1260. i = i2;
  1261. }
  1262. char *vertextypes = new char[numpoints];
  1263. long *priority = new long[numpoints];
  1264. //merge left and right vertex chains
  1265. priority[0] = topindex;
  1266. vertextypes[topindex] = 0;
  1267. leftindex = topindex+1; if(leftindex>=numpoints) leftindex = 0;
  1268. rightindex = topindex-1; if(rightindex<0) rightindex = numpoints-1;
  1269. for(i=1;i<(numpoints-1);i++) {
  1270. if(leftindex==bottomindex) {
  1271. priority[i] = rightindex;
  1272. rightindex--; if(rightindex<0) rightindex = numpoints-1;
  1273. vertextypes[priority[i]] = -1;
  1274. } else if(rightindex==bottomindex) {
  1275. priority[i] = leftindex;
  1276. leftindex++; if(leftindex>=numpoints) leftindex = 0;
  1277. vertextypes[priority[i]] = 1;
  1278. } else {
  1279. if(Below(points[leftindex],points[rightindex])) {
  1280. priority[i] = rightindex;
  1281. rightindex--; if(rightindex<0) rightindex = numpoints-1;
  1282. vertextypes[priority[i]] = -1;
  1283. } else {
  1284. priority[i] = leftindex;
  1285. leftindex++; if(leftindex>=numpoints) leftindex = 0;
  1286. vertextypes[priority[i]] = 1;
  1287. }
  1288. }
  1289. }
  1290. priority[i] = bottomindex;
  1291. vertextypes[bottomindex] = 0;
  1292. long *stack = new long[numpoints];
  1293. long stackptr = 0;
  1294. stack[0] = priority[0];
  1295. stack[1] = priority[1];
  1296. stackptr = 2;
  1297. //for each vertex from top to bottom trim as many triangles as possible
  1298. for(i=2;i<(numpoints-1);i++) {
  1299. vindex = priority[i];
  1300. if(vertextypes[vindex]!=vertextypes[stack[stackptr-1]]) {
  1301. for(j=0;j<(stackptr-1);j++) {
  1302. if(vertextypes[vindex]==1) {
  1303. triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]);
  1304. } else {
  1305. triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]);
  1306. }
  1307. triangles->push_back(triangle);
  1308. }
  1309. stack[0] = priority[i-1];
  1310. stack[1] = priority[i];
  1311. stackptr = 2;
  1312. } else {
  1313. stackptr--;
  1314. while(stackptr>0) {
  1315. if(vertextypes[vindex]==1) {
  1316. if(IsConvex(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]])) {
  1317. triangle.Triangle(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]]);
  1318. triangles->push_back(triangle);
  1319. stackptr--;
  1320. } else {
  1321. break;
  1322. }
  1323. } else {
  1324. if(IsConvex(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]])) {
  1325. triangle.Triangle(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]]);
  1326. triangles->push_back(triangle);
  1327. stackptr--;
  1328. } else {
  1329. break;
  1330. }
  1331. }
  1332. }
  1333. stackptr++;
  1334. stack[stackptr] = vindex;
  1335. stackptr++;
  1336. }
  1337. }
  1338. vindex = priority[i];
  1339. for(j=0;j<(stackptr-1);j++) {
  1340. if(vertextypes[stack[j+1]]==1) {
  1341. triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]);
  1342. } else {
  1343. triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]);
  1344. }
  1345. triangles->push_back(triangle);
  1346. }
  1347. delete [] priority;
  1348. delete [] vertextypes;
  1349. delete [] stack;
  1350. return 1;
  1351. }
  1352. int TriangulatorPartition::Triangulate_MONO(list<TriangulatorPoly> *inpolys, list<TriangulatorPoly> *triangles) {
  1353. list<TriangulatorPoly> monotone;
  1354. list<TriangulatorPoly>::iterator iter;
  1355. if(!MonotonePartition(inpolys,&monotone)) return 0;
  1356. for(iter = monotone.begin(); iter!=monotone.end();iter++) {
  1357. if(!TriangulateMonotone(&(*iter),triangles)) return 0;
  1358. }
  1359. return 1;
  1360. }
  1361. int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, list<TriangulatorPoly> *triangles) {
  1362. list<TriangulatorPoly> polys;
  1363. polys.push_back(*poly);
  1364. return Triangulate_MONO(&polys, triangles);
  1365. }