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