GeoModel - GeoModelCore
PolygonTriangulator.cxx
1 #include "PolygonTriangulator.h"
2 
4 // //
5 // Class: PolygonTriangulator //
6 // //
7 // Description: Triangulates any (non-complex) 2D polygon. //
8 // //
9 // Author: Thomas Kittelmann (Thomas.Kittelmann@cern.ch), March 2007 //
10 // //
11 // Notes: //
12 // //
13 // Actual algorithms are adapted from //
14 // http://www.mema.ucl.ac.be/~wu/Poly2Tri/poly2tri.html //
15 // (see copyright notice below) //
16 // //
17 // Main changes performed for the present incarnation are //
18 // interface & namespace changes, indentation, small //
19 // performance tweaks and removal of unused features. //
20 // Most importantly, got rid of static and globals so the class //
21 // can be reliably used more than once per process. Also, the //
22 // output triangles are sorted to preserve "handedness". //
23 // //
25 
31 //
32 // Poly2Tri:Fast and Robust Simple Polygon triangulation with/without holes
33 // by Sweep Line Algorithm
34 // Liang, Wu
35 // http://www.mema.ucl.ac.be/~wu/Poly2Tri/poly2tri.html
36 // Copyright (C) 2003, 2004, 2005, ALL RIGHTS RESERVED.
37 //
38 // ---------------------------------------------------------------------
39 // wu@mema.ucl.ac.be wuliang@femagsoft.com
40 // Centre for Sys. Eng. & App. Mech. FEMAGSoft S.A.
41 // Universite Cathalique de Louvain 4, Avenue Albert Einstein
42 // Batiment Euler, Avenue Georges Lemaitre, 4 B-1348 Louvain-la-Neuve
43 // B-1348, Louvain-la-Neuve Belgium
44 // Belgium
45 // ---------------------------------------------------------------------
46 //
47 // This program is distributed in the hope that it will be useful, but
48 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
49 // TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
50 //
51 // This program may be freely redistributed under the condition that all
52 // the copyright notices in all source files ( including the copyright
53 // notice printed when the `-h' switch is selected) are not removed.Both
54 // the binary and source codes may not be sold or included in any comme-
55 // rcial products without a license from the corresponding author(s) &
56 // entities.
57 //
58 // 1) Arbitrary precision floating-point arithmetic and fast robust geo-
59 // metric predicates (predicates.cc) is copyrighted by
60 // Jonathan Shewchuk (http://www.cs.berkeley.edu/~jrs) and you may get
61 // the source code from http://www.cs.cmu.edu/~quake/robust.html
62 //
63 // 2) The shell script mps2eps is copyrighted by Jon Edvardsson
64 // (http://www.ida.liu.se/~pelab/members/index.php4/?12) and you may
65 // get the copy from http://www.ida.liu.se/~joned/download/mps2eps/
66 //
67 // 3) All other source codes and exmaples files distributed in Poly2Tri
68 // are copyrighted by Liang, Wu (http://www.mema.ucl.ac.be/~wu) and
69 // FEMAGSoft S.A.
70 //
74 
75 #include <algorithm>
76 #include <cmath>
77 #include <cstdlib>
78 #include <map>
79 #include <limits>
80 #include <list>
81 #include <queue>
82 #include <set>
83 #include <iostream>
84 #include <stack>
85 #include <assert.h>
86 
87 namespace internal_poltrig {
88 
94 
95  //-------------------------------------------------------------------------/
96  //Copyright (C) 2003, 2004, 2005, ALL RIGHTS RESERVED.
97  //Centre for Sys. Eng. & App. Mech. FEMAGSoft S.A.
98  //Universite Cathalique de Louvain 4, Avenue Albert Einstein
99  //Batiment Euler, Avenue Georges Lemaitre, 4 B-1348 Louvain-la-Neuve
100  //B-1348, Louvain-la-Neuve Belgium
101  //Belgium
102  //-------------------------------------------------------------------------/
103  //Name: defs.h
104  //Purpose: some definition for mesh generation
105  //Author: Wu Liang
106  //Created: 03/2000
107  //-------------------------------------------------------------------------/
108 
109 
110 #define sqr(t) (t)*(t)
111 
112  //const double PI=3.141592653589793238462643383279502884197169399375105820974944592308;
113  enum Type { UNKNOWN, INPUT, INSERT, START, END, MERGE, SPLIT, REGULAR_UP, REGULAR_DOWN};
114 
115  class Pointbase;
116  class Linebase;
117 
118  template <class T, class KeyType> class SplayTree;
119  typedef std::map<unsigned int, Pointbase*> PointbaseMap;
120  typedef std::map<unsigned int, Linebase*> LineMap;
121  typedef std::priority_queue<Pointbase> PQueue;
123  typedef std::list<unsigned int> Monopoly;
124  typedef std::list<Monopoly> Monopolys;
125  typedef std::vector<unsigned int> Triangle;
126  typedef std::list<Triangle> Triangles;
127  typedef std::map<unsigned int, std::set<unsigned int> > AdjEdgeMap;
128 
129 
135 
136  /*****************************************************************************/
137  /* */
138  /* Routines for Arbitrary Precision Floating-point Arithmetic */
139  /* and Fast Robust Geometric Predicates */
140  /* (predicates.cc) */
141  /* */
142  /* May 18, 1996 */
143  /* */
144  /* Placed in the public domain by */
145  /* Jonathan Richard Shewchuk */
146  /* School of Computer Science */
147  /* Carnegie Mellon University */
148  /* 5000 Forbes Avenue */
149  /* Pittsburgh, Pennsylvania 15213-3891 */
150  /* jrs@cs.cmu.edu */
151  /* */
152  /* This file contains C implementation of algorithms for exact addition */
153  /* and multiplication of floating-point numbers, and predicates for */
154  /* robustly performing the orientation and incircle tests used in */
155  /* computational geometry. The algorithms and underlying theory are */
156  /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
157  /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
158  /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
159  /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
160  /* Discrete & Computational Geometry.) */
161  /* */
162  /* This file, the paper listed above, and other information are available */
163  /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
164  /* */
165  /*****************************************************************************/
166 
167  /*****************************************************************************/
168  /* */
169  /* Using this code: */
170  /* */
171  /* First, read the short or long version of the paper (from the Web page */
172  /* above). */
173  /* */
174  /* Be sure to call exactinit() once, before calling any of the arithmetic */
175  /* functions or geometric predicates. Also be sure to turn on the */
176  /* optimizer when compiling this file. */
177  /* */
178  /* */
179  /* Several geometric predicates are defined. Their parameters are all */
180  /* points. Each point is an array of two or three floating-point */
181  /* numbers. The geometric predicates, described in the papers, are */
182  /* */
183  /* orient2d(pa, pb, pc) */
184  /* orient2dfast(pa, pb, pc) */
185  /* orient3d(pa, pb, pc, pd) */
186  /* orient3dfast(pa, pb, pc, pd) */
187  /* incircle(pa, pb, pc, pd) */
188  /* incirclefast(pa, pb, pc, pd) */
189  /* insphere(pa, pb, pc, pd, pe) */
190  /* inspherefast(pa, pb, pc, pd, pe) */
191  /* */
192  /* Those with suffix "fast" are approximate, non-robust versions. Those */
193  /* without the suffix are adaptive precision, robust versions. There */
194  /* are also versions with the suffices "exact" and "slow", which are */
195  /* non-adaptive, exact arithmetic versions, which I use only for timings */
196  /* in my arithmetic papers. */
197  /* */
198  /* */
199  /* An expansion is represented by an array of floating-point numbers, */
200  /* sorted from smallest to largest magnitude (possibly with interspersed */
201  /* zeros). The length of each expansion is stored as a separate integer, */
202  /* and each arithmetic function returns an integer which is the length */
203  /* of the expansion it created. */
204  /* */
205  /* Several arithmetic functions are defined. Their parameters are */
206  /* */
207  /* e, f Input expansions */
208  /* elen, flen Lengths of input expansions (must be >= 1) */
209  /* h Output expansion */
210  /* b Input scalar */
211  /* */
212  /* The arithmetic functions are */
213  /* */
214  /* grow_expansion(elen, e, b, h) */
215  /* grow_expansion_zeroelim(elen, e, b, h) */
216  /* expansion_sum(elen, e, flen, f, h) */
217  /* expansion_sum_zeroelim1(elen, e, flen, f, h) */
218  /* expansion_sum_zeroelim2(elen, e, flen, f, h) */
219  /* fast_expansion_sum(elen, e, flen, f, h) */
220  /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
221  /* linear_expansion_sum(elen, e, flen, f, h) */
222  /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
223  /* scale_expansion(elen, e, b, h) */
224  /* scale_expansion_zeroelim(elen, e, b, h) */
225  /* compress(elen, e, h) */
226  /* */
227  /* All of these are described in the long version of the paper; some are */
228  /* described in the short version. All return an integer that is the */
229  /* length of h. Those with suffix _zeroelim perform zero elimination, */
230  /* and are recommended over their counterparts. The procedure */
231  /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
232  /* processors that do not use the round-to-even tiebreaking rule) is */
233  /* recommended over expansion_sum_zeroelim(). Each procedure has a */
234  /* little note next to it (in the code below) that tells you whether or */
235  /* not the output expansion may be the same array as one of the input */
236  /* expansions. */
237  /* */
238  /* */
239  /* If you look around below, you'll also find macros for a bunch of */
240  /* simple unrolled arithmetic operations, and procedures for printing */
241  /* expansions (commented out because they don't work with all C */
242  /* compilers) and for generating rand floating-point numbers whose */
243  /* significand bits are all rand. Most of the macros have undocumented */
244  /* requirements that certain of their parameters should not be the same */
245  /* variable; for safety, better to make sure all the parameters are */
246  /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
247  /* have questions. */
248  /* */
249  /*****************************************************************************/
250 
251  /* On some machines, the exact arithmetic routines might be defeated by the */
252  /* use of internal extended precision floating-point registers. Sometimes */
253  /* this problem can be fixed by defining certain values to be volatile, */
254  /* thus forcing them to be stored to memory and rounded off. This isn't */
255  /* a great solution, though, as it slows the arithmetic down. */
256  /* */
257  /* To try this out, write "#define INEXACT volatile" below. Normally, */
258  /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
259 
260 #define INEXACT /* Nothing */
261  /* #define INEXACT volatile */
262 
263 #define REAL double /* float or double */
264 
265  /* Which of the following two methods of finding the absolute values is */
266  /* fastest is compiler-dependent. A few compilers can inline and optimize */
267  /* the fabs() call; but most will incur the overhead of a function call, */
268  /* which is disastrously slow. A faster way on IEEE machines might be to */
269  /* mask the appropriate bit, but that's difficult to do in C. */
270 
271 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
272  /* #define Absolute(a) fabs(a) */
273 
274  /* Many of the operations are broken up into two pieces, a main part that */
275  /* performs an approximate operation, and a "tail" that computes the */
276  /* roundoff error of that operation. */
277  /* */
278  /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
279  /* Split(), and Two_Product() are all implemented as described in the */
280  /* reference. Each of these macros requires certain variables to be */
281  /* defined in the calling routine. The variables `bvirt', `c', `abig', */
282  /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
283  /* they store the result of an operation that may incur roundoff error. */
284  /* The input parameter `x' (or the highest numbered `x_' parameter) must */
285  /* also be declared `INEXACT'. */
286 
287 #define Fast_Two_Sum_Tail(a, b, x, y) \
288  bvirt = x - a; \
289  y = b - bvirt
290 
291 #define Fast_Two_Sum(a, b, x, y) \
292  x = (REAL) (a + b); \
293  Fast_Two_Sum_Tail(a, b, x, y)
294 
295 #define Two_Sum_Tail(a, b, x, y) \
296  bvirt = (REAL) (x - a); \
297  avirt = x - bvirt; \
298  bround = b - bvirt; \
299  around = a - avirt; \
300  y = around + bround
301 
302 #define Two_Sum(a, b, x, y) \
303  x = (REAL) (a + b); \
304  Two_Sum_Tail(a, b, x, y)
305 
306 #define Two_Diff_Tail(a, b, x, y) \
307  bvirt = (REAL) (a - x); \
308  avirt = x + bvirt; \
309  bround = bvirt - b; \
310  around = a - avirt; \
311  y = around + bround
312 
313 #define Two_Diff(a, b, x, y) \
314  x = (REAL) (a - b); \
315  Two_Diff_Tail(a, b, x, y)
316 
317 
318  // c = (REAL) (splitter * a);
319 
320 #define Split(a, ahi, alo) \
321  c = (REAL) (1.0 * a); \
322  abig = (REAL) (c - a); \
323  ahi = c - abig; \
324  alo = a - ahi
325 
326 #define Two_Product_Tail(a, b, x, y) \
327  Split(a, ahi, alo); \
328  Split(b, bhi, blo); \
329  err1 = x - (ahi * bhi); \
330  err2 = err1 - (alo * bhi); \
331  err3 = err2 - (ahi * blo); \
332  y = (alo * blo) - err3
333 
334 #define Two_Product(a, b, x, y) \
335  x = (REAL) (a * b); \
336  Two_Product_Tail(a, b, x, y)
337 
338  /* Macros for summing expansions of various fixed lengths. These are all */
339  /* unrolled versions of Expansion_Sum(). */
340 
341 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
342  Two_Diff(a0, b , i, x0); \
343  Two_Sum( a1, i, x2, x1)
344 
345 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
346  Two_One_Diff(a1, a0, b0, j, zero, x0); \
347  Two_One_Diff(j, zero, b1, x3, x2, x1)
348 
349 
350  //TK: weird globals, never initialised. Just replaced with 1.0 everywhere...
351  // REAL splitter(1); /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
352  /* A set of coefficients used to calculate maximum roundoff errors. */
353  // REAL resulterrbound;
354  // REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
355  // REAL o3derrboundA, o3derrboundB, o3derrboundC;
356  // REAL iccerrboundA, iccerrboundB, iccerrboundC;
357  // REAL isperrboundA, isperrboundB, isperrboundC;
358 
359  /*****************************************************************************/
360  /* */
361  /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
362  /* components from the output expansion. */
363  /* */
364  /* Sets h = e + f. See the long version of my paper for details. */
365  /* */
366  /* If round-to-even is used (as with IEEE 754), maintains the strongly */
367  /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
368  /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
369  /* properties. */
370  /* */
371  /*****************************************************************************/
372 
373  int fast_expansion_sum_zeroelim(const int& elen, REAL* e, const int& flen, REAL* f, REAL* h)
374  /* h cannot be e or f. */
375  {
376  REAL Q;
377  INEXACT REAL Qnew;
378  INEXACT REAL hh;
379  INEXACT REAL bvirt;
380  REAL avirt, bround, around;
381  int eindex, findex, hindex;
382  REAL enow, fnow;
383 
384  enow = e[0];
385  fnow = f[0];
386  eindex = findex = 0;
387  if ((fnow > enow) == (fnow > -enow)) {
388  Q = enow;
389  enow = e[++eindex];
390  } else {
391  Q = fnow;
392  fnow = f[++findex];
393  }
394  hindex = 0;
395  if ((eindex < elen) && (findex < flen)) {
396  if ((fnow > enow) == (fnow > -enow)) {
397  Fast_Two_Sum(enow, Q, Qnew, hh);
398  enow = e[++eindex];
399  } else {
400  Fast_Two_Sum(fnow, Q, Qnew, hh);
401  fnow = f[++findex];
402  }
403  Q = Qnew;
404  if (hh != 0.0) {
405  h[hindex++] = hh;
406  }
407  while ((eindex < elen) && (findex < flen)) {
408  if ((fnow > enow) == (fnow > -enow)) {
409  Two_Sum(Q, enow, Qnew, hh);
410  enow = e[++eindex];
411  } else {
412  Two_Sum(Q, fnow, Qnew, hh);
413  fnow = f[++findex];
414  }
415  Q = Qnew;
416  if (hh != 0.0) {
417  h[hindex++] = hh;
418  }
419  }
420  }
421  while (eindex < elen) {
422  Two_Sum(Q, enow, Qnew, hh);
423  enow = e[++eindex];
424  Q = Qnew;
425  if (hh != 0.0) {
426  h[hindex++] = hh;
427  }
428  }
429  while (findex < flen) {
430  Two_Sum(Q, fnow, Qnew, hh);
431  fnow = f[++findex];
432  Q = Qnew;
433  if (hh != 0.0) {
434  h[hindex++] = hh;
435  }
436  }
437  if ((Q != 0.0) || (hindex == 0)) {
438  h[hindex++] = Q;
439  }
440  return hindex;
441  }
442 
443 
444  /*****************************************************************************/
445  /* */
446  /* estimate() Produce a one-word estimate of an expansion's value. */
447  /* */
448  /* See either version of my paper for details. */
449  /* */
450  /*****************************************************************************/
451 
452  REAL estimate(const int& elen, REAL* e)
453  {
454  REAL Q;
455  int eindex;
456 
457  Q = e[0];
458  for (eindex = 1; eindex < elen; ++eindex) {
459  Q += e[eindex];
460  }
461  return Q;
462  }
463 
464  /*****************************************************************************/
465  /* */
466  /* orient2dfast() Approximate 2D orientation test. Nonrobust. */
467  /* orient2dexact() Exact 2D orientation test. Robust. */
468  /* orient2dslow() Another exact 2D orientation test. Robust. */
469  /* orient2d() Adaptive exact 2D orientation test. Robust. */
470  /* */
471  /* Return a positive value if the points pa, pb, and pc occur */
472  /* in counterclockwise order; a negative value if they occur */
473  /* in clockwise order; and zero if they are collinear. The */
474  /* result is also a rough approximation of twice the signed */
475  /* area of the triangle defined by the three points. */
476  /* */
477  /* Only the first and last routine should be used; the middle two are for */
478  /* timings. */
479  /* */
480  /* The last three use exact arithmetic to ensure a correct answer. The */
481  /* result returned is the determinant of a matrix. In orient2d() only, */
482  /* this determinant is computed adaptively, in the sense that exact */
483  /* arithmetic is used only to the degree it is needed to ensure that the */
484  /* returned value has the correct sign. Hence, orient2d() is usually quite */
485  /* fast, but will run more slowly when the input points are collinear or */
486  /* nearly so. */
487  /* */
488  /*****************************************************************************/
489 
490  REAL orient2dadapt(REAL* pa, REAL* pb, REAL* pc, const REAL& detsum)
491  {
492  INEXACT REAL acx, acy, bcx, bcy;
493  REAL acxtail, acytail, bcxtail, bcytail;
494  INEXACT REAL detleft, detright;
495  REAL detlefttail, detrighttail;
496  REAL det, errbound;
497  REAL B[4], C1[8], C2[12], D[16];
498  INEXACT REAL B3;
499  int C1length, C2length, Dlength;
500  REAL u[4];
501  INEXACT REAL u3;
502  INEXACT REAL s1, t1;
503  REAL s0, t0;
504 
505  INEXACT REAL bvirt;
506  REAL avirt, bround, around;
507  INEXACT REAL c;
508  INEXACT REAL abig;
509  REAL ahi, alo, bhi, blo;
510  REAL err1, err2, err3;
511  INEXACT REAL i, j;
512  REAL zero;
513 
514  acx = (REAL) (pa[0] - pc[0]);
515  bcx = (REAL) (pb[0] - pc[0]);
516  acy = (REAL) (pa[1] - pc[1]);
517  bcy = (REAL) (pb[1] - pc[1]);
518 
519  Two_Product(acx, bcy, detleft, detlefttail);
520  Two_Product(acy, bcx, detright, detrighttail);
521 
522  Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
523  B3, B[2], B[1], B[0]);
524  B[3] = B3;
525 
526  det = estimate(4, B);
527  // errbound = ccwerrboundB * detsum;
528  errbound = detsum;
529  if ((det >= errbound) || (-det >= errbound)) {
530  return det;
531  }
532 
533  Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
534  Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
535  Two_Diff_Tail(pa[1], pc[1], acy, acytail);
536  Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
537 
538  if ((acxtail == 0.0) && (acytail == 0.0)
539  && (bcxtail == 0.0) && (bcytail == 0.0)) {
540  return det;
541  }
542 
543  // errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
544  errbound = detsum + Absolute(det);
545  det += (acx * bcytail + bcy * acxtail)
546  - (acy * bcxtail + bcx * acytail);
547  if ((det >= errbound) || (-det >= errbound)) {
548  return det;
549  }
550 
551  Two_Product(acxtail, bcy, s1, s0);
552  Two_Product(acytail, bcx, t1, t0);
553  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
554  u[3] = u3;
555  C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
556 
557  Two_Product(acx, bcytail, s1, s0);
558  Two_Product(acy, bcxtail, t1, t0);
559  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
560  u[3] = u3;
561  C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
562 
563  Two_Product(acxtail, bcytail, s1, s0);
564  Two_Product(acytail, bcxtail, t1, t0);
565  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
566  u[3] = u3;
567  Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
568 
569  return(D[Dlength - 1]);
570  }
571 
572  REAL orient2d(REAL* pa, REAL* pb, REAL* pc)
573  {
574  REAL detleft, detright, det;
575  REAL detsum, errbound;
576 
577  detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
578  detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
579  det = detleft - detright;
580 
581  if (detleft > 0.0) {
582  if (detright <= 0.0) {
583  return det;
584  } else {
585  detsum = detleft + detright;
586  }
587  } else if (detleft < 0.0) {
588  if (detright >= 0.0) {
589  return det;
590  } else {
591  detsum = -detleft - detright;
592  }
593  } else {
594  return det;
595  }
596 
597  // errbound = ccwerrboundA * detsum;
598  errbound = detsum;
599  if ((det >= errbound) || (-det >= errbound)) {
600  return det;
601  }
602 
603  return orient2dadapt(pa, pb, pc, detsum);
604  }
605 
606 
608 
614 
615  //-------------------------------------------------------------------------/
616  //Copyright (C) 2003, 2004, 2005, ALL RIGHTS RESERVED.
617  //Centre for Sys. Eng. & App. Mech. FEMAGSoft S.A.
618  //Universite Cathalique de Louvain 4, Avenue Albert Einstein
619  //Batiment Euler, Avenue Georges Lemaitre, 4 B-1348 Louvain-la-Neuve
620  //B-1348, Louvain-la-Neuve Belgium
621  //Belgium
622  //-------------------------------------------------------------------------/
623  //
624  //Name: splay.h (self-adjusting balanced binary search tree)
625  //Purpose: declaration and implentation of splay tree class for fast
626  // binary searching
627  //Author: Liang, Wu (wu@mema.ucl.ac.be, wuliang@femagsoft.com)
628  //Created: 03/2002
629  //Modified: 2003, 2004, 2005
630  //-------------------------------------------------------------------------/
631 
632  template <class T, class KeyType>
633  class SplayTree;
634 
635  template <class T, class KeyType>
636  class BTreeNode
637  {
638  public:
639  friend class SplayTree<T, KeyType>;
640  BTreeNode( ) : m_data(), m_left( nullptr ), m_right( nullptr ), m_visited(false) { }
641  BTreeNode( const T & data, BTreeNode *lt, BTreeNode *rt )
642  : m_data(data),m_left( lt ), m_right( rt ), m_visited(false) { }
643 
644  T& data() { return m_data; }
645  BTreeNode* Left() { return m_left; }
646  BTreeNode* Right() { return m_right; }
647  void SetVisited(const bool& visited) { m_visited=visited; }
648  bool GetVisited() { return m_visited; }
649  KeyType keyValue() { return m_data->keyValue(); }
650 
651  private:
652  T m_data;
653  BTreeNode *m_left;
654  BTreeNode *m_right;
655  bool m_visited;
656 
657  };
658 
659 
660  template <class T, class KeyType>
661  class SplayTree
662  {
663  public:
664  explicit SplayTree( ):m_root(nullptr),m_size(0) { }
665  SplayTree( const SplayTree & rhs );
666  ~SplayTree( );
667 
668  void MakeEmpty( );
669  bool IsEmpty( ) const;
670  long int Size() { return m_size; }
671  BTreeNode<T, KeyType>* Root() {
672  // cppcheck false positive:
673  // cppcheck-suppress CastIntegerToAddressAtReturn
674  return m_root;
675  }
676 
677  void Find( const KeyType& keys, BTreeNode<T, KeyType>* & res);
678  void FindMin( BTreeNode<T, KeyType>* &min );
679  void FindMax( BTreeNode<T, KeyType>* &max );
680  // We only use this function for polygon Triangulation to find the direct
681  // left edge of an event vertex;
682  void FindMaxSmallerThan( const KeyType& keys, BTreeNode<T, KeyType>* &res);
683 
684  void Insert( const T & x );
685  void Delete( const KeyType& keys);
686  void Delete( const KeyType& keys, BTreeNode<T, KeyType>* &res);
687  void DeleteMin(BTreeNode<T, KeyType>* &min);
688  void DeleteMax(BTreeNode<T, KeyType>* &max);
689 
690  const SplayTree & operator=( const SplayTree & rhs );
691  void PreOrder( void(*Visit)(BTreeNode<T,KeyType> *u) )
692  { PreOrder(Visit, m_root); }
693  void InOrder( void(*Visit)(BTreeNode<T,KeyType> *u) )
694  { InOrder(Visit, m_root); }
695 
696  void InOrder( void(*Visit)(BTreeNode<T,KeyType>*u, double y), double y)
697  { InOrder(Visit, m_root, y); }
698 
699  void PostOrder( void(*Visit)(BTreeNode<T,KeyType> *u) )
700  { PostOrder(Visit, m_root); }
701 
702  int Height( ) const { return Height(m_root); } //height of m_root
703  int Height(BTreeNode<T, KeyType> *t) const; //Height of subtree t;
704  BTreeNode<T, KeyType>* Left(BTreeNode<T, KeyType> *node) { return node->m_left; }
705  BTreeNode<T, KeyType>* Right(BTreeNode<T, KeyType> *node) { return node->m_right; }
706 
707  private:
708  BTreeNode<T, KeyType> *m_root;
709  long int m_size;
710 
711  void reclaimMemory( BTreeNode<T, KeyType> * t ) const;
712  BTreeNode<T, KeyType> * clone( BTreeNode<T, KeyType> *t ) const;
713 
714  //Transverse
715  void PreOrder( void(*Visit)(BTreeNode<T, KeyType> *u), BTreeNode<T, KeyType> *t);
716  void InOrder( void(*Visit)(BTreeNode<T, KeyType> *u), BTreeNode<T, KeyType> *t);
717  void PostOrder( void(*Visit)(BTreeNode<T, KeyType> *u), BTreeNode<T, KeyType> *t);
718 
719  void InOrder( void(*Visit)(BTreeNode<T, KeyType>*, double y),
720  BTreeNode<T, KeyType> *t, double y);
721 
722 
723 
724  // Tree manipulations
725  void rotateWithLeftChild( BTreeNode<T, KeyType> * & k2 ) const;
726  void rotateWithRightChild( BTreeNode<T, KeyType> * & k1 ) const;
727  void splay( const KeyType& keys, BTreeNode<T, KeyType> * & t ) const;
728  };
729 
730  //----------------------------------------------------------------------
731  //Constructor;
732  //----------------------------------------------------------------------
733  template <class T, class KeyType>
735  {
736  *this = rhs;
737  }
738 
739  //-----------------------------------------------------------------------
740  //Destructor.
741  //-----------------------------------------------------------------------
742  template <class T, class KeyType>
744  {
745  MakeEmpty( );
746  }
747 
748  //------------------------------------------------------------------------
749  //Insert x into the tree.
750  //------------------------------------------------------------------------
751  template <class T, class KeyType>
752  void SplayTree<T, KeyType>::Insert( const T & x )
753  {
754 
756  newNode->m_data=x;
757 
758  if( m_root == nullptr )
759  {
760  newNode->m_left = newNode->m_right = nullptr;
761  m_root = newNode; ++m_size;
762  }
763  else
764  {
765  KeyType keys=x->keyValue();
766  splay( keys, m_root );
767  KeyType rootk=m_root->keyValue();
768  if( keys < rootk )
769  {
770  newNode->m_left = m_root->m_left;
771  newNode->m_right = m_root;
772  m_root->m_left = nullptr;
773  m_root = newNode;
774  ++m_size;
775  }
776  else if( keys > rootk )
777  {
778 
779  newNode->m_right = m_root->m_right;
780  newNode->m_left = m_root;
781  m_root->m_right = nullptr;
782  m_root = newNode;
783  ++m_size;
784  }
785  else
786  {
787  //slight incresed the keyvalue to avoid duplicated keys
788  x->increaseKeyValue(1.0e-10);
789  Insert(x);
790  delete newNode;
791  }
792  }
793  }
794 
795  //---------------------------------------------------------------------
796  //Remove the node with the keys from the tree, and retrieve the result
797  //---------------------------------------------------------------------
798  template <class T, class KeyType>
799  void SplayTree<T, KeyType>::Delete( const KeyType& keys, BTreeNode<T, KeyType>* &res)
800  {
801  BTreeNode<T, KeyType> *newTree;
802 
803  splay( keys, m_root );
804  if( m_root->keyValue() != keys ) { res=nullptr; return; } // Item not found; do nothing
805 
806  res = m_root;
807 
808  if( m_root->m_left == nullptr )
809  newTree = m_root->m_right;
810  else
811  {
812  // Find the maximum in the m_left subtree
813  // Splay it to the m_root; and then attach m_right child
814  newTree = m_root->m_left;
815  splay( keys, newTree );
816  newTree->m_right = m_root->m_right;
817  }
818 
819  m_root = newTree;
820  m_size--;
821  }
822 
823  //---------------------------------------------------------------------
824  //Remove the node with the keys from the tree.
825  //---------------------------------------------------------------------
826  template <class T, class KeyType>
827  void SplayTree<T, KeyType>::Delete( const KeyType& keys)
828  {
829  BTreeNode<T, KeyType> *newTree;
830 
831  splay( keys, m_root );
832  KeyType rootk=m_root->keyValue();
833  if( rootk != keys ) { return; } // Item not found; do nothing
834 
835  if( m_root->m_left == nullptr ) newTree = m_root->m_right;
836  else
837  {
838  // Find the maximum in the m_left subtree
839  // Splay it to the m_root; and then attach m_right child
840  newTree = m_root->m_left;
841  splay( keys, newTree );
842  newTree->m_right = m_root->m_right;
843  }
844 
845  delete m_root;
846  m_root = newTree;
847  m_size--;
848  }
849 
850 
851 
852  //---------------------------------------------------------------------
853  //Find and Delete the node with min keys from the tree;
854  //---------------------------------------------------------------------
855  template <class T, class KeyType>
857  {
858  if( IsEmpty( ) ) { min=nullptr; return; }
859 
860  double keys=-1.0e30;
861  splay( keys, m_root );
862 
863  min = m_root;
864 
865  BTreeNode<T, KeyType> *newTree;
866  if( m_root->m_left == nullptr ) newTree = m_root->m_right;
867  else
868  {
869  newTree = m_root->m_left;
870  splay( keys, newTree );
871  newTree->m_right = m_root->m_right;
872  }
873 
874  m_size--;
875  m_root = newTree;
876 
877  }
878 
879  //----------------------------------------------------------------------
880  //Find and Delete the node with max keys from the tree;
881  //----------------------------------------------------------------------
882  template <class T, class KeyType>
884  {
885  if( IsEmpty( ) ) { max=nullptr; return; }
886 
887  double keys=1.0e30;
888  splay( keys, m_root );
889 
890  max = m_root;
891 
892  BTreeNode<T, KeyType> *newTree;
893  if( m_root->m_left == nullptr ) newTree = m_root->m_right;
894  else
895  {
896  newTree = m_root->m_left;
897  splay( keys, newTree );
898  newTree->m_right = m_root->m_right;
899  }
900  m_size--;
901  m_root = newTree;
902  }
903 
904 
905  //----------------------------------------------------------------------
906  //Find the smallest item in the tree, but won't delete it from the tree.
907  //----------------------------------------------------------------------
908  template <class T, class KeyType>
910  {
911  if( IsEmpty( ) ) { min=nullptr; return; }
912  BTreeNode<T, KeyType> *ptr = m_root;
913 
914  while( ptr->m_left != nullptr ) ptr = ptr->m_left;
915  splay( ptr->keyValue(), m_root );
916  min = ptr;
917  }
918 
919  //----------------------------------------------------------------------
920  //Find the largest item in the tree. but won't delete it from the tree.
921  //----------------------------------------------------------------------
922  template <class T, class KeyType>
924  {
925  if( IsEmpty( ) ) { max=nullptr; return; }
926 
927  BTreeNode<T, KeyType> *ptr = m_root;
928  while( ptr->m_right != nullptr ) ptr = ptr->m_right;
929  splay( ptr->keyValue(), m_root );
930  max = ptr;
931  }
932 
933  //--------------------------------------------------------------------
934  //Find the node with the keys in the tree.
935  //res==nullptr if it donesn't exist in the tree;
936  //--------------------------------------------------------------------
937  template <class T, class KeyType>
938  void SplayTree<T, KeyType>::Find( const KeyType& keys, BTreeNode<T, KeyType>* & res)
939  {
940  if( IsEmpty( ) ) { res=nullptr; return; }
941  splay( keys, m_root );
942  if( m_root->keyValue() != keys ) { res=nullptr; return; }
943  else res = m_root;
944  }
945 
946  //--------------------------------------------------------------------
947  //Find the maximum node smaller than or equal to the given key.
948  //This function specially designed for polygon Triangulation to
949  //find the direct left edge at event vertex;
950  //--------------------------------------------------------------------
951  template <class T, class KeyType>
952  void SplayTree<T, KeyType>::FindMaxSmallerThan( const KeyType& keys, BTreeNode<T, KeyType>* &res)
953  {
954  if( IsEmpty( ) ) { res=nullptr; return; }
955  splay( keys, m_root );
956 
957  if( m_root->data()->keyValue() < keys) res=m_root;
958  else if(m_root->m_left)
959  {
960  res=m_root->m_left;
961  while(res->m_right) res=res->m_right;
962  }
963  else
964  {
965  assert(false);
966  }
967  }
968 
969  //--------------------------------------------------------------------
970  //Make the tree logically empty.
971  //--------------------------------------------------------------------
972  template <class T, class KeyType>
974  {
976  while( !IsEmpty( ) )
977  {
978  DeleteMax(ptr);
979  delete ptr;
980  }
981  }
982 
983  //---------------------------------------------------------------------
984  //Test if the tree is logically empty.
985  //---------------------------------------------------------------------
986  template <class T, class KeyType>
987  bool SplayTree<T, KeyType>::IsEmpty( ) const
988  {
989  return m_root == nullptr;
990  }
991 
992  //----------------------------------------------------------------------
993  //copy overload operator.
994  //----------------------------------------------------------------------
995  template <class T, class KeyType>
997  {
998  if( this != &rhs )
999  {
1000  MakeEmpty( );
1001  m_root = clone( rhs.m_root );
1002  }
1003 
1004  return *this;
1005  }
1006 
1007  //-----------------------------------------------------------------------
1008  //Internal method to perform a top-down splay.
1009  //x is the key of target node to splay around.
1010  //t is the m_root of the subtree to splay.
1011  //-----------------------------------------------------------------------
1012  template <class T, class KeyType>
1013  void SplayTree<T, KeyType>::splay( const KeyType& keys, BTreeNode<T, KeyType> * & t ) const
1014  {
1015  BTreeNode<T, KeyType> *leftTreeMax, *rightTreeMin;
1016  // static BTreeNode<T, KeyType> header;
1017  BTreeNode<T, KeyType> header;//TK: Removed static keyword. Rather a bit slower than thread problems...
1018 
1019  header.m_left = header.m_right = nullptr;
1020  leftTreeMax = rightTreeMin = &header;
1021 
1022  for( ; ; )
1023  {
1024  KeyType rkey=t->keyValue();
1025  if( keys < rkey )
1026  {
1027  if(t->m_left == nullptr) break;
1028  if( keys < t->m_left->keyValue() ) rotateWithLeftChild( t );
1029  if( t->m_left == nullptr ) break;
1030 
1031  // Link Right
1032  rightTreeMin->m_left = t;
1033  rightTreeMin = t;
1034  t = t->m_left;
1035  }
1036  else if( keys > rkey )
1037  {
1038  if( t->m_right == nullptr ) break;
1039  if( keys > t->m_right->keyValue() ) rotateWithRightChild( t );
1040  if( t->m_right == nullptr ) break;
1041 
1042  // Link Left
1043  leftTreeMax->m_right = t;
1044  leftTreeMax = t;
1045  t = t->m_right;
1046  }
1047  else break;
1048  }
1049 
1050  leftTreeMax->m_right = t->m_left;
1051  rightTreeMin->m_left = t->m_right;
1052  t->m_left = header.m_right;
1053  t->m_right = header.m_left;
1054 
1055  }
1056 
1057  //--------------------------------------------------------------------
1058  //Rotate binary tree node with m_left child.
1059  //--------------------------------------------------------------------
1060  template <class T, class KeyType>
1062  {
1063  BTreeNode<T, KeyType> *k1 = k2->m_left;
1064  k2->m_left = k1->m_right;
1065  k1->m_right = k2;
1066  k2 = k1;
1067  }
1068 
1069  //---------------------------------------------------------------------
1070  //Rotate binary tree node with m_right child.
1071  //---------------------------------------------------------------------
1072  template <class T, class KeyType>
1074  {
1075  BTreeNode<T, KeyType> *k2 = k1->m_right;
1076  k1->m_right = k2->m_left;
1077  k2->m_left = k1;
1078  k1 = k2;
1079  }
1080 
1081  //----------------------------------------------------------------------
1082  //Internal method to reclaim internal nodes in subtree t.
1083  //WARNING: This is prone to running out of stack space.
1084  //----------------------------------------------------------------------
1085  template <class T, class KeyType>
1087  {
1088  if( t != t->m_left )
1089  {
1090  reclaimMemory( t->m_left );
1091  reclaimMemory( t->m_right );
1092  delete t;
1093  }
1094  }
1095 
1096  //-----------------------------------------------------------------------
1097  //Internal method to clone subtree.
1098  //WARNING: This is prone to running out of stack space.
1099  //-----------------------------------------------------------------------
1100  template <class T, class KeyType>
1102  {
1103  if( t == t->m_left ) // Cannot test against nullptrNode!!!
1104  return nullptr;
1105  else
1106  return new BTreeNode<T, KeyType>( t->m_data, clone( t->m_left ), clone( t->m_right ) );
1107  }
1108 
1109  //-----------------------------------------------------------------------
1110  //Tranverse the tree by pre-order method;
1111  //-----------------------------------------------------------------------
1112  template<class T, class KeyType>
1114  {
1115  if(t!=nullptr)
1116  {
1117  Visit(t);
1118  PreOrder(Visit,t->m_left);
1119  PreOrder(Visit,t->m_right);
1120  }
1121 
1122  }
1123 
1124  //-----------------------------------------------------------------------
1125  //Tranverse the tree by in-order method;
1126  //-----------------------------------------------------------------------
1127  template<class T, class KeyType>
1129  {
1130  if(t!=nullptr)
1131  {
1132  InOrder(Visit,t->m_left);
1133  Visit(t);
1134  InOrder(Visit,t->m_right);
1135  }
1136  }
1137 
1138 
1139  //-----------------------------------------------------------------------
1140  //Tranverse the tree by in-order method;
1141  //-----------------------------------------------------------------------
1142  template<class T, class KeyType>
1143  void SplayTree<T, KeyType>::InOrder( void(*Visit)(BTreeNode<T, KeyType>*u, double y)
1144  , BTreeNode<T, KeyType> *t, double y)
1145  {
1146  if(t!=nullptr)
1147  {
1148  InOrder(Visit,t->m_left, y);
1149  Visit(t, y);
1150  InOrder(Visit,t->m_right, y);
1151  }
1152  }
1153 
1154 
1155 
1156  //-----------------------------------------------------------------------
1157  //Tranverse the tree by post-order method;
1158  //-----------------------------------------------------------------------
1159  template<class T, class KeyType>
1161  {
1162  if(t!=nullptr)
1163  {
1164  PostOrder(Visit,t->m_left);
1165  PostOrder(Visit,t->m_right);
1166  Visit(t);
1167  }
1168  }
1169 
1170  //-----------------------------------------------------------------------
1171  //return the height of subtree
1172  //-----------------------------------------------------------------------
1173  template<class T, class KeyType>
1175  {
1176  if(subtree==nullptr) return 0;
1177  int lh=Height(subtree->m_left);
1178  int rh=Height(subtree->m_right);
1179 
1180  return (lh>rh)?(++lh):(++rh);
1181  }
1182 
1183 
1189 
1190  //-------------------------------------------------------------------------/
1191  //Copyright (C) 2003, 2004, 2005, ALL RIGHTS RESERVED.
1192  //Centre for Sys. Eng. & App. Mech. FEMAGSoft S.A.
1193  //Universite Cathalique de Louvain 4, Avenue Albert Einstein
1194  //Batiment Euler, Avenue Georges Lemaitre, 4 B-1348 Louvain-la-Neuve
1195  //B-1348, Louvain-la-Neuve Belgium
1196  //Belgium
1197  //-------------------------------------------------------------------------/
1198  //
1199  //Name: geometry.h (all geometry primitives related polygon triang-
1200  // ulation by sweep line algorithm)
1201  //Author: Liang, Wu (wu@mema.ucl.ac.be, wuliang@femagsoft.com)
1202  //Created: 03/2001
1203  //Modified: 10/2005. Modified and simplified only for polygon triangul-
1204  // ation purpose.
1205  //-------------------------------------------------------------------------/
1206 
1207 
1208  //base class for points;
1210  {
1211  public:
1212  //constructors and destructor
1213  Pointbase(): id(0), x(0.), y(0.), type(UNKNOWN), left(false){}
1214  Pointbase(const Pointbase& pb);
1215 
1216  Pointbase(const double& xx, const double& yy)
1217  :id(0), x(xx), y(yy), type(UNKNOWN), left(false) { }
1218 
1219  Pointbase(const int& idd, const double& xx, const double& yy)
1220  :id(idd), x(xx), y(yy), type(UNKNOWN), left(false) { }
1221 
1222  Pointbase(const double& xx, const double& yy, const Type& ttype)
1223  :id(0), x(xx), y(yy), type(ttype), left(false) { }
1224 
1225  Pointbase(const int& idd, const double& xx, const double& yy, const Type& ttype)
1226  :id(idd),x(xx), y(yy), type(ttype), left(false) { }
1227 
1228  //operator overloading
1229  friend bool operator==(const Pointbase&, const Pointbase&);
1230  friend bool operator>(const Pointbase&, const Pointbase&);
1231  friend bool operator<(const Pointbase&, const Pointbase&);
1232  friend bool operator!=(const Pointbase&, const Pointbase&);
1233 
1234  //public data
1235  unsigned int id; //id of point;
1236  double x, y; //coordinates;
1237  Type type; //type of points;
1238  bool left; //left chain or not;
1239 
1240  Pointbase & operator= ( const Pointbase & pb )
1241  {
1242  if (this != &pb) {
1243  this->id=pb.id;
1244  this->x=pb.x;
1245  this->y=pb.y;
1246  this->type=pb.type;
1247  this->left=pb.left;
1248  }
1249  return *this;
1250  }
1251  };
1252 
1253  //base class for polygon boundary
1254  //Linebase class is a directed line segment with start/end point
1255  class Linebase
1256  {
1257  public:
1258  //constructors and destructor
1259  Linebase();
1260  Linebase(Pointbase* ep1, Pointbase* ep2, const Type& type,long int & l_id);
1261  Linebase(const Linebase& line);
1262  ~Linebase() {};
1263 
1264  unsigned int id() const { return m_id; }
1265 
1266  //two end points
1267  Pointbase* endPoint(const int& i) const { return m_endp[i]; }
1268  Type type() const { return m_type; }
1269  double keyValue() const { return m_key; }
1270  void setKeyValue(const double& y);
1271  //slightly increased the key to avoid duplicated key for searching tree.
1272  void increaseKeyValue(const double& diff) { m_key+=diff; }
1273  //reverse a directed line segment; reversable only for inserted diagonals
1274  void reverse();
1275 
1276  //set and return helper of a directed line segment;
1277  void setHelper(const unsigned int& i) { m_helper=i; }
1278  unsigned int helper() { return m_helper; }
1279 
1280  protected:
1281  unsigned int m_id; //id of a line segment;
1282  Pointbase* m_endp[2]; //two end points;
1283 
1284  Type m_type; //type of a line segement, input/insert
1285  double m_key; //key of a line segment for splay tree searching
1286  unsigned int m_helper; //helper of a line segemnt
1287  public:
1288  Linebase & operator= ( const Linebase & line )
1289  {
1290  if (this != &line) {
1291  this->m_id=line.m_id;
1292  this->m_endp[0]=line.m_endp[0];
1293  this->m_endp[1]=line.m_endp[1];
1294  this->m_type=line.m_type;
1295  this->m_key=line.m_key;
1296  this->m_helper=line.m_helper;
1297  }
1298  return *this;
1299  }
1300  };
1301 
1307 
1308  //-------------------------------------------------------------------------/
1309  //Copyright (C) 2003, 2004, 2005, ALL RIGHTS RESERVED.
1310  //Centre for Sys. Eng. & App. Mech. FEMAGSoft S.A.
1311  //Universite Cathalique de Louvain 4, Avenue Albert Einstein
1312  //Batiment Euler, Avenue Georges Lemaitre, 4 B-1348 Louvain-la-Neuve
1313  //B-1348, Louvain-la-Neuve Belgium
1314  //Belgium
1315  //-------------------------------------------------------------------------/
1316  //
1317  //Name: geometry.cc (all geometry primitive implementations related
1318  // to polygon triangulation by sweep line algorithm)
1319  //Author: Liang, Wu (wu@mema.ucl.ac.be, wuliang@femagsoft.com)
1320  //Created: 03/2001
1321  //Modified: 10/2005. Modified and simplified only for polygon triangul-
1322  // ation purpose.
1323  //-------------------------------------------------------------------------/
1324 
1325 
1326  //Jonathan schewchuk's exact arithmetic code, see predicates.cc for detais;
1327  extern double orient2d(double* pa, double* pb, double* pc);
1328 
1329  //----------------------------------------------------------------------------
1330  //square of the distance of two points;
1331  //----------------------------------------------------------------------------
1332  double dist_sqr(const Pointbase& sp, const Pointbase& ep)
1333  {
1334  return sqr(sp.x-ep.x)+sqr(sp.y-ep.y);
1335  }
1336 
1337  //----------------------------------------------------------------------------
1338  //square of the distance of two points;
1339  //----------------------------------------------------------------------------
1340  double dist_sqr(double *pa, double *pb)
1341  {
1342  return sqr(pa[0]-pb[0])+sqr(pa[1]-pb[1]);
1343  }
1344 
1345  void UpdateKey(BTreeNode<Linebase*,double>* node, double y)
1346  {
1347  node->data()->setKeyValue(y);
1348  }
1349 
1350  //----------------------------------------------------------------------------
1351  //copy constructor
1352  //----------------------------------------------------------------------------
1353  Pointbase::Pointbase(const Pointbase& pb)
1354  {
1355  this->id=pb.id;
1356  this->x=pb.x;
1357  this->y=pb.y;
1358  this->type=pb.type;
1359  this->left=pb.left;
1360  }
1361 
1362  //----------------------------------------------------------------------------
1363  //operator ( ==, >, < and != ) overloading for pointbase class
1364  //----------------------------------------------------------------------------
1365  bool operator==(const Pointbase& pa, const Pointbase& pb)
1366  {
1367  return (pa.x==pb.x && pa.y==pb.y);
1368  }
1369 
1370  //----------------------------------------------------------------------------
1371  bool operator>(const Pointbase& pa, const Pointbase& pb)
1372  {
1373  return( (pa.y > pb.y) || ( (pa.y==pb.y) && (pa.x < pb.x)) );
1374  }
1375 
1376  //----------------------------------------------------------------------------
1377  bool operator<(const Pointbase& pa, const Pointbase& pb)
1378  {
1379  return( (pa.y < pb.y) || ( (pa.y==pb.y) && (pa.x > pb.x)) );
1380  }
1381 
1382  //----------------------------------------------------------------------------
1383  bool operator!=(const Pointbase& pa, const Pointbase& pb)
1384  {
1385  return !(pa.x==pb.x && pa.y==pb.y);
1386  }
1387 
1388  //----------------------------------------------------------------------------
1389  //Linebase construct
1390  //----------------------------------------------------------------------------
1391  Linebase::Linebase():m_type(UNKNOWN),m_key(0.),m_helper(0)
1392  {
1393  for(int i=0; i<2; ++i) m_endp[i]=0;
1394  m_id=0;
1395  }
1396 
1397  //-----------------------------------------------------------------------------
1398  //Linebase construct
1399  //-----------------------------------------------------------------------------
1400  Linebase::Linebase(Pointbase* sp, Pointbase* ep, const Type& type, long int & l_id):m_type(type),m_key(0.),m_helper(0)
1401  {
1402  m_endp[0]=sp;
1403  m_endp[1]=ep;
1404  m_id=++l_id;
1405  }
1406 
1407  //----------------------------------------------------------------------------
1408  //copy constructor
1409  //----------------------------------------------------------------------------
1410  Linebase::Linebase(const Linebase& line)
1411  {
1412  this->m_id=line.m_id;
1413  this->m_endp[0]=line.m_endp[0];
1414  this->m_endp[1]=line.m_endp[1];
1415  this->m_type=line.m_type;
1416  this->m_key=line.m_key;
1417  this->m_helper=line.m_helper;
1418  }
1419 
1420 
1421  //----------------------------------------------------------------------------
1422  //reverse a directed line segment, reverseable only for insert diagonals
1423  //----------------------------------------------------------------------------
1424  void Linebase::reverse()
1425  {
1426  assert(m_type==INSERT);
1427  Pointbase* tmp=m_endp[0];
1428  m_endp[0]=m_endp[1];
1429  m_endp[1]=tmp;
1430  }
1431 
1432  void Linebase::setKeyValue(const double& y)
1433  {
1434  if( m_endp[1]->y==m_endp[0]->y )
1435  m_key=m_endp[0]->x < m_endp[1]->x ? m_endp[0]->x:m_endp[1]->x;
1436  else m_key=( y - m_endp[0]->y ) * ( m_endp[1]->x - m_endp[0]->x ) / (m_endp[1]->y - m_endp[0]->y ) + m_endp[0]->x;
1437  }
1438 
1439 }//end namespace internal_poltrig
1440 
1442 {
1443 public:
1444  //constructor and destructor
1445  Polygon(const std::vector<double>& x,const std::vector<double>& y);
1446  ~Polygon();
1447 
1448  // main member function for polygon triangulation;
1449  void partition2Monotone();
1450  void searchMonotones();
1451  void triangulation();
1452 
1453  //return all triangles
1454  const Triangles* triangles() { return &m_triangles; }
1455 
1456  internal_poltrig::PointbaseMap& points() { return m_points; }
1457  internal_poltrig::LineMap& edges() { return m_edges; }
1458 
1459  //private member functions.
1460 private:
1461  long int m_l_id;//previous a global, but that gives mem. crashes. Must be reinitted for every polygon.
1462 
1463  void set_contour (const std::vector<double>& x,const std::vector<double>& y);
1464  void initializate();
1465 
1466  //prev or next point/edge id for a given ith point/edge;
1467  unsigned int prev(const unsigned int& i);
1468  unsigned int next(const unsigned int& i);
1469 
1470  //handle event vertext according to vertex type;
1471  void handleStartVertex(const unsigned int& );
1472  void handleEndVertex(const unsigned int& );
1473  void handleSplitVertex(const unsigned int& );
1474  void handleMergeVertex(const unsigned int& );
1475  void handleRegularVertexUp(const unsigned int& );
1476  void handleRegularVertexDown(const unsigned int& );
1477 
1478  //add diagonal between two vertices;
1479  void addDiagonal(const unsigned int& i, const unsigned int& j);
1480 
1481 
1482  //angle ABC for three given points, for monotone polygon searching purpose;
1483  double angleCosb(double *A, double *B, double *C);
1484  //find the next edge, for monotone polygon searching purpose;
1485  unsigned int selectNextEdge(internal_poltrig::Linebase* edge);
1486 
1487  //triangulate a monotone polygon piece;
1488  void triangulateMonotone(internal_poltrig::Monopoly& mpoly);
1489 
1490  //private data memebers
1491  internal_poltrig::PQueue m_qpoints; //priority queue for event points
1492  internal_poltrig::EdgeBST m_edgebst; //edge binary searching tree (splaytree)
1493  internal_poltrig::Monopolys m_mpolys; //all monotone polygon piece list;
1494  Triangles m_triangles; //all triangle list;
1495 
1496  //data for monotone piece searching purpose;
1497  internal_poltrig::AdjEdgeMap m_startAdjEdgeMap; //all edges starting from given points (map)
1498  internal_poltrig::LineMap m_diagonals; //added diagonals to partition polygon to
1499  //monotont pieces, not all diagonals of
1500 
1501  void init_vertices_and_lines();
1502  unsigned int m_ncontours; //number of contours
1503  std::vector<unsigned int> m_nVertices; //
1504  internal_poltrig::PointbaseMap m_points; //all vertices
1505  internal_poltrig::LineMap m_edges; //all edges
1506  double m_xmin,m_xmax, m_ymin,m_ymax; //boundary box for polygon
1507 
1508 };
1509 
1510 
1511 void PolygonTriangulator::Polygon::init_vertices_and_lines()
1512 {
1513  int sid,eid;
1514  int num=0;
1515 
1516  internal_poltrig::Type type;
1517 
1518  for(unsigned j=0; j<m_ncontours; ++j)
1519  {
1520  for(unsigned i=1; i<=m_nVertices[j]; ++i)//fixme: 0-based?
1521  {
1522  sid=num+i;
1523  eid=(i==m_nVertices[j])?num+1:num+i+1;
1524  type = internal_poltrig::INPUT;
1525  internal_poltrig::Linebase* line=new internal_poltrig::Linebase(m_points[sid], m_points[eid], type,m_l_id);
1526  m_edges[m_l_id]=line;
1527  }
1528  num+=m_nVertices[j];
1529  }
1530 
1531  int sum=0;
1532  for(unsigned int i=0; i<m_ncontours; ++i)
1533  {
1534  sum+= m_nVertices[i];
1535  m_nVertices[i]=sum;
1536  }
1537 
1538 }
1539 
1540 
1541 //----------------------------------------------------------------------------
1542 //get input
1543 //----------------------------------------------------------------------------
1544 void PolygonTriangulator::Polygon::set_contour(const std::vector<double>& x,const std::vector<double>& y)
1545 {
1546  assert(x.size()==y.size());
1547 
1548  m_nVertices.push_back( x.size() );
1549  unsigned int i = m_points.size()+1/*1*/;//fixme: get rid of the +1 ?
1550  double xx,yy;
1551  internal_poltrig::Type type;
1552  for (unsigned int j = 0; j < m_nVertices[m_ncontours]; ++j, ++i)
1553  {
1554  xx=x.at(j);
1555  yy=y.at(j);
1556  type=internal_poltrig::INPUT;
1558  if(xx > m_xmax ) m_xmax=xx;
1559  if(xx < m_xmin ) m_xmin=xx;
1560  if(yy > m_ymax ) m_ymax=yy;
1561  if(yy < m_ymin ) m_ymin=yy;
1562  m_points[i]=point;
1563  }
1564 
1565  ++m_ncontours;
1566 
1567 }
1568 
1569 
1570 
1571 
1572 //----------------------------------------------------------------------------
1573 //polygon class constructor
1574 //----------------------------------------------------------------------------
1575 PolygonTriangulator::Polygon::Polygon(const std::vector<double>& x,const std::vector<double>& y)
1576 {
1577  m_l_id = 0;
1578  m_ncontours=0;
1579 
1580  m_xmin = m_ymin = std::numeric_limits<double>::infinity();
1581  m_xmax = m_ymax = - std::numeric_limits<double>::infinity();
1582 
1583 
1584  set_contour(x,y);
1585  init_vertices_and_lines();
1586  initializate();
1587 }
1588 
1589 //----------------------------------------------------------------------------
1590 //polygon destructor
1591 //----------------------------------------------------------------------------
1592 PolygonTriangulator::Polygon::~Polygon()
1593 {
1594  //clear all dynamic allocated memory
1595  internal_poltrig::PointbaseMap::iterator itp=m_points.begin();
1596  for(; itp!=m_points.end(); ++itp)
1597  {
1598  delete itp->second;
1599  }
1600 
1601  internal_poltrig::LineMap::iterator itl=m_edges.begin();
1602  for(; itl!=m_edges.end(); ++itl)
1603  {
1604  delete itl->second;
1605  }
1606 
1607 }
1608 
1609 //----------------------------------------------------------------------------
1610 //return the previous point (or edge) id for a given ith point (or edge);
1611 //----------------------------------------------------------------------------
1612 unsigned int PolygonTriangulator::Polygon::prev(const unsigned int& i)
1613 {
1614  unsigned int j(0),prevLoop(0),currentLoop(0);
1615 
1616  while ( i > m_nVertices[currentLoop] )
1617  {
1618  prevLoop=currentLoop;
1619  ++currentLoop;
1620  }
1621 
1622  if( i==1 || (i==m_nVertices[prevLoop]+1) ) j=m_nVertices[currentLoop];
1623  else if( i <= m_nVertices[currentLoop] ) j=i-1;
1624 
1625  return j;
1626 }
1627 
1628 //----------------------------------------------------------------------------
1629 //return the next point (or edge) id for a given ith point (or edge);
1630 //----------------------------------------------------------------------------
1631 unsigned int PolygonTriangulator::Polygon::next(const unsigned int& i)
1632 {
1633  unsigned int j(0),prevLoop(0),currentLoop(0);
1634 
1635  while ( i > m_nVertices[currentLoop] )
1636  {
1637  prevLoop=currentLoop;
1638  ++currentLoop;
1639  }
1640 
1641  if( i < m_nVertices[currentLoop] ) j=i+1;
1642  else if ( i==m_nVertices[currentLoop] )
1643  {
1644  if( currentLoop==0) j=1;
1645  else j=m_nVertices[prevLoop]+1;
1646  }
1647 
1648  return j;
1649 }
1650 
1651 //----------------------------------------------------------------------------
1652 //polygon initialization;
1653 //to find types of all polygon vertices;
1654 //create a priority queue for all vertices;
1655 //construct an edge set for each vertex (the set holds all edges starting from
1656 //the vertex, only for loop searching purpose).
1657 //----------------------------------------------------------------------------
1658 void PolygonTriangulator::Polygon::initializate()
1659 {
1660  internal_poltrig::PointbaseMap::iterator it=m_points.begin();
1661  for(; it!=m_points.end(); ++it)
1662  {
1663  int id=it->first;
1664  int idp=prev(id);
1665  int idn=next(id);
1666  internal_poltrig::Pointbase p=*m_points[id], pnext=*m_points[idn], pprev=*m_points[idp];
1667 
1668  if( p > pnext && pprev > p )
1669  m_points[id]->type=internal_poltrig::REGULAR_DOWN;
1670  else if (p > pprev && pnext > p)
1671  m_points[id]->type=internal_poltrig::REGULAR_UP;
1672  else
1673  {
1674  double pa[2], pb[2], pc[2];
1675 
1676  pa[0]=m_points[idp]->x;
1677  pa[1]=m_points[idp]->y;
1678 
1679  pb[0]=m_points[id]->x;
1680  pb[1]=m_points[id]->y;
1681 
1682  pc[0]=m_points[idn]->x;
1683  pc[1]=m_points[idn]->y;
1684 
1685  double area=internal_poltrig::orient2d(pa,pb,pc);
1686 
1687  if( pprev > p && pnext > p ) m_points[id]->type=(area >0) ? internal_poltrig::END: internal_poltrig::MERGE ;
1688  if( pprev < p && pnext < p ) m_points[id]->type=(area >0) ? internal_poltrig::START : internal_poltrig::SPLIT;
1689 
1690  }
1691 
1692  m_qpoints.push(*(it->second));
1693 
1694  m_startAdjEdgeMap[id].insert(id);
1695 
1696  }
1697 }
1698 
1699 //----------------------------------------------------------------------------
1700 //Add a diagonal from point id i to j
1701 //----------------------------------------------------------------------------
1702 void PolygonTriangulator::Polygon::addDiagonal(const unsigned int& i, const unsigned int& j)
1703 {
1704  internal_poltrig::Type type=internal_poltrig::INSERT;
1705  internal_poltrig::Linebase* diag=new internal_poltrig::Linebase(m_points[i], m_points[j], type,m_l_id);
1706  m_edges[diag->id()]=diag;
1707 
1708  m_startAdjEdgeMap[i].insert(diag->id());
1709  m_startAdjEdgeMap[j].insert(diag->id());
1710 
1711  m_diagonals[diag->id()]=diag;
1712 
1713 }
1714 
1715 //----------------------------------------------------------------------------
1716 //Handle start vertex
1717 //----------------------------------------------------------------------------
1718 void PolygonTriangulator::Polygon::handleStartVertex(const unsigned int& i)
1719 {
1720  double y=m_points[i]->y;
1721  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1722 
1723  m_edges[i]->setHelper(i);
1724  m_edges[i]->setKeyValue(y);
1725  m_edgebst.Insert(m_edges[i]);
1726 
1727 }
1728 
1729 //----------------------------------------------------------------------------
1730 //Handle end vertex
1731 //----------------------------------------------------------------------------
1732 void PolygonTriangulator::Polygon::handleEndVertex(const unsigned int& i)
1733 {
1734  double y=m_points[i]->y;
1735  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1736 
1737  unsigned int previ=prev(i);
1738  internal_poltrig::Linebase* edge=m_edges[previ];
1739  unsigned int helper=m_edges[previ]->helper();
1740 
1741 
1742  if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1743  m_edgebst.Delete(edge->keyValue());
1744 
1745 }
1746 
1747 //----------------------------------------------------------------------------
1748 //Handle split vertex
1749 //----------------------------------------------------------------------------
1750 void PolygonTriangulator::Polygon::handleSplitVertex(const unsigned int& i)
1751 {
1752  double x=m_points[i]->x, y=m_points[i]->y;
1753  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1754 
1756  m_edgebst.FindMaxSmallerThan(x, leftnode);
1757  internal_poltrig::Linebase* leftedge=leftnode->data();
1758 
1759  unsigned int helper=leftedge->helper();
1760  addDiagonal(i, helper);
1761 
1762  leftedge->setHelper(i);
1763  m_edges[i]->setHelper(i);
1764  m_edges[i]->setKeyValue(y);
1765  m_edgebst.Insert(m_edges[i]);
1766 }
1767 
1768 //----------------------------------------------------------------------------
1769 //Handle merge vertex
1770 //----------------------------------------------------------------------------
1771 void PolygonTriangulator::Polygon::handleMergeVertex(const unsigned int& i)
1772 {
1773  double x=m_points[i]->x, y=m_points[i]->y;
1774  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1775 
1776  unsigned int previ=prev(i);
1777  unsigned int helper=m_edges[previ]->helper();
1778  if (m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1779  m_edgebst.Delete(m_edges[previ]->keyValue());
1780 
1782  m_edgebst.FindMaxSmallerThan(x, leftnode);
1783  internal_poltrig::Linebase* leftedge=leftnode->data();
1784 
1785  helper=leftedge->helper();
1786  if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1787 
1788  leftedge->setHelper(i);
1789 }
1790 
1791 //----------------------------------------------------------------------------
1792 //Handle regular down vertex
1793 //----------------------------------------------------------------------------
1794 void PolygonTriangulator::Polygon::handleRegularVertexDown(const unsigned int& i)
1795 {
1796  double y=m_points[i]->y;
1797  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1798 
1799  unsigned int previ=prev(i);
1800  unsigned int helper=m_edges[previ]->helper();
1801  if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1802 
1803  m_edgebst.Delete(m_edges[previ]->keyValue());
1804  m_edges[i]->setHelper(i);
1805  m_edges[i]->setKeyValue(y);
1806  m_edgebst.Insert(m_edges[i]);
1807 
1808 }
1809 
1810 //----------------------------------------------------------------------------
1812 //----------------------------------------------------------------------------
1813 void PolygonTriangulator::Polygon::handleRegularVertexUp(const unsigned int& i)
1814 {
1815  double x=m_points[i]->x, y=m_points[i]->y;
1816  m_edgebst.InOrder(internal_poltrig::UpdateKey, y);
1817 
1819  m_edgebst.FindMaxSmallerThan(x, leftnode);
1820 
1821  internal_poltrig::Linebase* leftedge=leftnode->data();
1822 
1823  unsigned int helper=leftedge->helper();
1824  if(m_points[helper]->type==internal_poltrig::MERGE) addDiagonal(i, helper);
1825  leftedge->setHelper(i);
1826 
1827 }
1828 
1829 //----------------------------------------------------------------------------
1830 //partition polygon to monotone polygon pieces
1831 //----------------------------------------------------------------------------
1832 void PolygonTriangulator::Polygon::partition2Monotone()
1833 {
1834 
1835  if(m_qpoints.top().type!=internal_poltrig::START)
1836  {
1837  std::cout<<"Please check your input polygon:\n1)orientations?\n2)duplicated points?\n";
1838  exit(1);
1839  }
1840 
1841  while(!m_qpoints.empty())
1842  {
1843  internal_poltrig::Pointbase vertex=m_qpoints.top();
1844  m_qpoints.pop();
1845  unsigned int id=vertex.id;
1846 
1847  switch(vertex.type)
1848  {
1849  case internal_poltrig::START: handleStartVertex(id); break;
1850  case internal_poltrig::END: handleEndVertex(id); break;
1851  case internal_poltrig::MERGE: handleMergeVertex(id); break;
1852  case internal_poltrig::SPLIT: handleSplitVertex(id); break;
1853  case internal_poltrig::REGULAR_UP: handleRegularVertexUp(id); break;
1854  case internal_poltrig::REGULAR_DOWN: handleRegularVertexDown(id); break;
1855  default:
1856  std::cout<<"No duplicated points please!\n";
1857  exit(1); break;
1858  }
1859  }
1860 }
1861 
1862 
1863 //----------------------------------------------------------------------------
1864 //two Auxiliary functions to find monotone polygon pieces
1865 //----------------------------------------------------------------------------
1866 
1867 //----------------------------------------------------------------------------
1868 //calculate angle B for A, B, C three given points
1869 //----------------------------------------------------------------------------
1870 double PolygonTriangulator::Polygon::angleCosb(double *pa, double *pb, double *pc)
1871 {
1872  double dxab = pa[0] - pb[0];
1873  double dyab = pa[1] - pb[1];
1874 
1875  double dxcb = pc[0] - pb[0];
1876  double dycb = pc[1] - pb[1];
1877 
1878  double dxab2 = dxab * dxab;
1879  double dyab2 = dyab * dyab;
1880  double dxcb2 = dxcb * dxcb;
1881  double dycb2 = dycb * dycb;
1882  double ab = dxab2 + dyab2;
1883  double cb = dxcb2 + dycb2;
1884 
1885  double cosb = dxab * dxcb + dyab * dycb;
1886  double denom = sqrt( ab * cb);
1887 
1888  cosb/=denom;
1889 
1890  return cosb;
1891 }
1892 
1893 //----------------------------------------------------------------------------
1894 //for any given edge, find the next edge we should choose when searching for
1895 //monotone polygon pieces;
1896 //----------------------------------------------------------------------------
1897 unsigned int PolygonTriangulator::Polygon::selectNextEdge(internal_poltrig::Linebase* edge)
1898 {
1899 
1900  unsigned int eid= edge->endPoint(1)->id;
1901  std::set<unsigned int> edges=m_startAdjEdgeMap[eid];
1902  assert(!edges.empty());
1903 
1904  unsigned int nexte=0;
1905  if( edges.size() == 1 ) nexte=*(edges.begin());
1906  else if( edges.size() > 1 )
1907  {
1908  unsigned int nexte_ccw(0), nexte_cw(0);
1909  double max=-2.0,min=2.0;
1910 
1911 
1912  std::set<unsigned int>::iterator it=edges.begin();
1913  for(; it!=edges.end(); ++it)
1914  {
1915  if(*it==edge->id()) continue;
1916  double A[2], B[2], C[2];
1917  A[0]=edge->endPoint(0)->x; A[1]=edge->endPoint(0)->y;
1918  B[0]=edge->endPoint(1)->x; B[1]=edge->endPoint(1)->y;
1919 
1920  if(edge->endPoint(1)!=m_edges[*it]->endPoint(0)) m_edges[*it]->reverse();
1921  C[0]=m_edges[*it]->endPoint(1)->x; C[1]=m_edges[*it]->endPoint(1)->y;
1922 
1923  double area=internal_poltrig::orient2d(A, B, C);
1924  double cosb=angleCosb(A, B, C);
1925 
1926  if( area > 0 && max < cosb ) { nexte_ccw=*it; max=cosb; }
1927  else if( min > cosb ) { nexte_cw=*it; min=cosb; }
1928  }
1929 
1930  nexte = (nexte_ccw!=0) ? nexte_ccw : nexte_cw;
1931  }
1932 
1933  return nexte;
1934 }
1935 
1936 //----------------------------------------------------------------------------
1937 //searching all monotone pieces;
1938 //----------------------------------------------------------------------------
1939 void PolygonTriangulator::Polygon::searchMonotones()
1940 {
1941  int loop=0;
1942 
1943  internal_poltrig::LineMap edges=m_edges;
1944 
1945  while( edges.size() > m_diagonals.size() )
1946  {
1947  ++loop;
1948  internal_poltrig::Monopoly poly;
1949  internal_poltrig::LineMap::iterator it=edges.begin();
1950  internal_poltrig::Pointbase* startp=it->second->endPoint(0);
1952  internal_poltrig::Linebase* next=it->second;
1953 
1954  poly.push_back(startp->id);
1955 
1956  for(;;)
1957  {
1958  endp=next->endPoint(1);
1959  if(next->type()!=internal_poltrig::INSERT)
1960  {
1961  edges.erase(next->id());
1962  m_startAdjEdgeMap[next->endPoint(0)->id].erase(next->id());
1963  }
1964  if(endp==startp) break;
1965  poly.push_back(endp->id);
1966 
1967  unsigned int nexte=selectNextEdge(next);
1968 
1969  if(nexte==0)
1970  {
1971  std::cout<<"Please check your input polygon:\n";
1972  std::cout<<"1)orientations?\n2)with duplicated points?\n3)is a simple one?\n";
1973  exit(1);
1974  }
1975  //assert( nexte > 0);
1976  next=edges[nexte];
1977  if(next->endPoint(0) !=endp ) next->reverse();
1978  }
1979 
1980  m_mpolys.push_back(poly);
1981  }
1982 }
1983 
1984 
1985 //----------------------------------------------------------------------------
1986 //triangulate a monotone polygon;
1987 //----------------------------------------------------------------------------
1988 void PolygonTriangulator::Polygon::triangulateMonotone(internal_poltrig::Monopoly& mpoly)
1989 {
1990  internal_poltrig::PQueue qvertex;
1991  internal_poltrig::Monopoly::iterator it=mpoly.begin(), itnext;
1992  for(; itnext=it, it!=mpoly.end(); ++it)
1993  {
1994  ++itnext;
1995  if(itnext==mpoly.end()) itnext=mpoly.begin();
1996  internal_poltrig::Pointbase point=*m_points[*it], pointnext=*m_points[*itnext];
1997  point.left=(point > pointnext)? true:false;
1998  qvertex.push(point);
1999  }
2000 
2001  std::stack<internal_poltrig::Pointbase> spoint;
2002  for(int i=0; i<2; ++i) { spoint.push(qvertex.top()); qvertex.pop(); }
2003 
2004  while ( qvertex.size() > 1 )
2005  {
2006  internal_poltrig::Pointbase topQueuePoint=qvertex.top();
2007  internal_poltrig::Pointbase topStackPoint=spoint.top();
2008 
2009  if(topQueuePoint.left!=topStackPoint.left)
2010  {
2011  while ( spoint.size() > 1 )
2012  {
2013  internal_poltrig::Pointbase p1=spoint.top();
2014  spoint.pop();
2015  internal_poltrig::Pointbase p2=spoint.top();
2016  Triangle v(3);
2017  v[0]=topQueuePoint.id;
2018  v[1]=p1.id;
2019  v[2]=p2.id;
2020  sort(v.begin(),v.end());//TK
2021  m_triangles.push_back(v);
2022 
2023  }
2024  spoint.pop();
2025  spoint.push(topStackPoint);
2026  spoint.push(topQueuePoint);
2027  }
2028  else
2029  {
2030  while( spoint.size() > 1 )
2031  {
2032  internal_poltrig::Pointbase stack1Point=spoint.top();
2033  spoint.pop();
2034  internal_poltrig::Pointbase stack2Point=spoint.top();
2035  spoint.push(stack1Point);
2036  double pa[2], pb[2], pc[2];
2037  pa[0]=topQueuePoint.x; pa[1]=topQueuePoint.y;
2038  pb[0]=stack2Point.x; pb[1]=stack2Point.y;
2039  pc[0]=stack1Point.x; pc[1]=stack1Point.y;
2040 
2041  double area=internal_poltrig::orient2d(pa,pb,pc);
2042  bool left=stack1Point.left;
2043  if( (area > 0 && left) || (area < 0 && !left ) )
2044  {
2045  Triangle v(3);
2046  v[0]=topQueuePoint.id;
2047  v[1]=stack2Point.id;
2048  v[2]=stack1Point.id;
2049  sort(v.begin(),v.end());//TK
2050  m_triangles.push_back(v);
2051  spoint.pop();
2052  } else break;
2053  }
2054 
2055  spoint.push(topQueuePoint);
2056 
2057  }
2058 
2059  qvertex.pop();
2060 
2061  }
2062 
2063  internal_poltrig::Pointbase lastQueuePoint=qvertex.top();
2064  while( spoint.size() !=1 )
2065  {
2066  internal_poltrig::Pointbase topPoint=spoint.top();
2067  spoint.pop();
2068  internal_poltrig::Pointbase top2Point=spoint.top();
2069 
2070  Triangle v(3);
2071  v[0]=lastQueuePoint.id;
2072  v[1]=topPoint.id;
2073  v[2]=top2Point.id;
2074  sort(v.begin(),v.end());//TK
2075  m_triangles.push_back(v);
2076  }
2077 }
2078 
2079 //----------------------------------------------------------------------------
2080 //main triangulation function;
2082 void PolygonTriangulator::Polygon::triangulation()
2083 {
2084  partition2Monotone();
2085  searchMonotones();
2086  internal_poltrig::Monopolys::iterator it=m_mpolys.begin();
2087  for(; it!=m_mpolys.end(); ++it)
2088  triangulateMonotone(*it);
2089 }
2090 
2097 
2098 PolygonTriangulator::PolygonTriangulator(const std::vector<double>& polygon_xcoords,
2099  const std::vector<double>& polygon_ycoords)
2100  : m_polygon(new Polygon(polygon_xcoords,polygon_ycoords))
2101 {
2102  m_polygon->triangulation();
2103 }
2104 
2105 PolygonTriangulator::~PolygonTriangulator() { delete m_polygon; }
2106 
2107 const PolygonTriangulator::Triangles* PolygonTriangulator::triangles() const
2108 {
2109  return m_polygon->triangles();
2110 }
2111 
2112