triangulator.cpp 41 KB

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