Seamly2D
Code documentation
predicates.cpp
Go to the documentation of this file.
1 /*****************************************************************************/
2 /* */
3 /* Routines for Arbitrary Precision Floating-point Arithmetic */
4 /* and Fast Robust Geometric Predicates */
5 /* (predicates.cpp) */
6 /* */
7 /* May 18, 1996 */
8 /* */
9 /* Placed in the public domain by */
10 /* Jonathan Richard Shewchuk */
11 /* School of Computer Science */
12 /* Carnegie Mellon University */
13 /* 5000 Forbes Avenue */
14 /* Pittsburgh, Pennsylvania 15213-3891 */
15 /* jrs@cs.cmu.edu */
16 /* */
17 /* This file contains C implementation of algorithms for exact addition */
18 /* and multiplication of floating-point numbers, and predicates for */
19 /* robustly performing the orientation and incircle tests used in */
20 /* computational geometry. The algorithms and underlying theory are */
21 /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
22 /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
23 /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
24 /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
25 /* Discrete & Computational Geometry.) */
26 /* */
27 /* This file, the paper listed above, and other information are available */
28 /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
29 /* */
30 /*****************************************************************************/
31 
32 /*****************************************************************************/
33 /* */
34 /* Using this code: */
35 /* */
36 /* First, read the short or long version of the paper (from the Web page */
37 /* above). */
38 /* */
39 /* Be sure to call exactinit() once, before calling any of the arithmetic */
40 /* functions or geometric predicates. Also be sure to turn on the */
41 /* optimizer when compiling this file. */
42 /* */
43 /* */
44 /* Several geometric predicates are defined. Their parameters are all */
45 /* points. Each point is an array of two or three floating-point */
46 /* numbers. The geometric predicates, described in the papers, are */
47 /* */
48 /* incircle(pa, pb, pc, pd) */
49 /* incirclefast(pa, pb, pc, pd) */
50 /* */
51 /* Those with suffix "fast" are approximate, non-robust versions. Those */
52 /* without the suffix are adaptive precision, robust versions. There */
53 /* are also versions with the suffices "exact" and "slow", which are */
54 /* non-adaptive, exact arithmetic versions, which I use only for timings */
55 /* in my arithmetic papers. */
56 /* */
57 /* */
58 /* An expansion is represented by an array of floating-point numbers, */
59 /* sorted from smallest to largest magnitude (possibly with interspersed */
60 /* zeros). The length of each expansion is stored as a separate integer, */
61 /* and each arithmetic function returns an integer which is the length */
62 /* of the expansion it created. */
63 /* */
64 /* Several arithmetic functions are defined. Their parameters are */
65 /* */
66 /* e, f Input expansions */
67 /* elen, flen Lengths of input expansions (must be >= 1) */
68 /* h Output expansion */
69 /* b Input scalar */
70 /* */
71 /* The arithmetic functions are */
72 /* */
73 /* expansion_sum(elen, e, flen, f, h) */
74 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */
75 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */
76 /* fast_expansion_sum(elen, e, flen, f, h) */
77 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
78 /* linear_expansion_sum(elen, e, flen, f, h) */
79 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
80 /* scale_expansion(elen, e, b, h) */
81 /* scale_expansion_zeroelim(elen, e, b, h) */
82 /* compress(elen, e, h) */
83 /* */
84 /* All of these are described in the long version of the paper; some are */
85 /* described in the short version. All return an integer that is the */
86 /* length of h. Those with suffix _zeroelim perform zero elimination, */
87 /* and are recommended over their counterparts. The procedure */
88 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
89 /* processors that do not use the round-to-even tiebreaking rule) is */
90 /* recommended over expansion_sum_zeroelim(). Each procedure has a */
91 /* little note next to it (in the code below) that tells you whether or */
92 /* not the output expansion may be the same array as one of the input */
93 /* expansions. */
94 /* */
95 /* */
96 /* If you look around below, you'll also find macros for a bunch of */
97 /* simple unrolled arithmetic operations, and procedures for printing */
98 /* expansions (commented out because they don't work with all C */
99 /* compilers) and for generating random floating-point numbers whose */
100 /* significand bits are all random. Most of the macros have undocumented */
101 /* requirements that certain of their parameters should not be the same */
102 /* variable; for safety, better to make sure all the parameters are */
103 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
104 /* have questions. */
105 /* */
106 /*****************************************************************************/
107 
108 #include <QtGlobal>
109 
110 #include "../vmisc/diagnostic.h"
111 
112 QT_WARNING_PUSH
113 QT_WARNING_DISABLE_MSVC(4701)
114 QT_WARNING_DISABLE_GCC("-Wold-style-cast")
115 QT_WARNING_DISABLE_GCC("-Wfloat-equal")
116 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
117 QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
118 #else
119 QT_WARNING_DISABLE_GCC("-Wuninitialized")
120 #endif
121 QT_WARNING_DISABLE_CLANG("-Wold-style-cast")
122 QT_WARNING_DISABLE_CLANG("-Wmissing-variable-declarations")
123 QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
124 QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
125 QT_WARNING_DISABLE_CLANG("-Wconditional-uninitialized")
126 
127 /* On some machines, the exact arithmetic routines might be defeated by the */
128 /* use of internal extended precision floating-point registers. Sometimes */
129 /* this problem can be fixed by defining certain values to be volatile, */
130 /* thus forcing them to be stored to memory and rounded off. This isn't */
131 /* a great solution, though, as it slows the arithmetic down. */
132 /* */
133 /* To try this out, write "#define INEXACT volatile" below. Normally, */
134 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
135 
136 #define INEXACT /* Nothing */
137 /* #define INEXACT volatile */
138 
139 #define REALPRINT doubleprint
140 #define REALRAND doublerand
141 #define NARROWRAND narrowdoublerand
142 #define UNIFORMRAND uniformdoublerand
143 
144 /* Which of the following two methods of finding the absolute values is */
145 /* fastest is compiler-dependent. A few compilers can inline and optimize */
146 /* the fabs() call; but most will incur the overhead of a function call, */
147 /* which is disastrously slow. A faster way on IEEE machines might be to */
148 /* mask the appropriate bit, but that's difficult to do in C. */
149 
150 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
151 /* #define Absolute(a) fabs(a) */
152 
153 
154 /* Many of the operations are broken up into two pieces, a main part that */
155 /* performs an approximate operation, and a "tail" that computes the */
156 /* roundoff error of that operation. */
157 /* */
158 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
159 /* Split(), and Two_Product() are all implemented as described in the */
160 /* reference. Each of these macros requires certain variables to be */
161 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
162 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
163 /* they store the result of an operation that may incur roundoff error. */
164 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
165 /* also be declared `INEXACT'. */
166 
167 #define Fast_Two_Sum_Tail(a, b, x, y) \
168  bvirt = x - a; \
169  y = b - bvirt
170 
171 #define Fast_Two_Sum(a, b, x, y) \
172  x = (qreal) (a + b); \
173  Fast_Two_Sum_Tail(a, b, x, y)
174 
175 #define Two_Sum_Tail(a, b, x, y) \
176  bvirt = (qreal) (x - a); \
177  avirt = x - bvirt; \
178  bround = b - bvirt; \
179  around = a - avirt; \
180  y = around + bround
181 
182 #define Two_Sum(a, b, x, y) \
183  x = (qreal) (a + b); \
184  Two_Sum_Tail(a, b, x, y)
185 
186 #define Two_Diff_Tail(a, b, x, y) \
187  bvirt = (qreal) (a - x); \
188  avirt = x + bvirt; \
189  bround = bvirt - b; \
190  around = a - avirt; \
191  y = around + bround
192 
193 #define Two_Diff(a, b, x, y) \
194  x = (qreal) (a - b); \
195  Two_Diff_Tail(a, b, x, y)
196 
197 #define Split(a, ahi, alo) \
198  c = (qreal) (splitter * a); \
199  abig = (qreal) (c - a); \
200  ahi = c - abig; \
201  alo = a - ahi
202 
203 #define Two_Product_Tail(a, b, x, y) \
204  Split(a, ahi, alo); \
205  Split(b, bhi, blo); \
206  err1 = x - (ahi * bhi); \
207  err2 = err1 - (alo * bhi); \
208  err3 = err2 - (ahi * blo); \
209  y = (alo * blo) - err3
210 
211 #define Two_Product(a, b, x, y) \
212  x = (qreal) (a * b); \
213  Two_Product_Tail(a, b, x, y)
214 
215 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
216 /* already been split. Avoids redundant splitting. */
217 
218 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
219  x = (qreal) (a * b); \
220  Split(a, ahi, alo); \
221  err1 = x - (ahi * bhi); \
222  err2 = err1 - (alo * bhi); \
223  err3 = err2 - (ahi * blo); \
224  y = (alo * blo) - err3
225 
226 /* Square() can be done more quickly than Two_Product(). */
227 
228 #define Square_Tail(a, x, y) \
229  Split(a, ahi, alo); \
230  err1 = x - (ahi * ahi); \
231  err3 = err1 - ((ahi + ahi) * alo); \
232  y = (alo * alo) - err3
233 
234 #define Square(a, x, y) \
235  x = (qreal) (a * a); \
236  Square_Tail(a, x, y)
237 
238 /* Macros for summing expansions of various fixed lengths. These are all */
239 /* unrolled versions of Expansion_Sum(). */
240 
241 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
242  Two_Sum(a0, b , _i, x0); \
243  Two_Sum(a1, _i, x2, x1)
244 
245 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
246  Two_Diff(a0, b , _i, x0); \
247  Two_Sum( a1, _i, x2, x1)
248 
249 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
250  Two_One_Sum(a1, a0, b0, _j, _0, x0); \
251  Two_One_Sum(_j, _0, b1, x3, x2, x1)
252 
253 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
254  Two_One_Diff(a1, a0, b0, _j, _0, x0); \
255  Two_One_Diff(_j, _0, b1, x3, x2, x1)
256 
257 qreal splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
258 qreal epsilon; /* = 2^(-p). Used to estimate roundoff errors. */
259 /* A set of coefficients used to calculate maximum roundoff errors. */
265 
266 /*****************************************************************************/
267 /* */
268 /* exactinit() Initialize the variables used for exact arithmetic. */
269 /* */
270 /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */
271 /* floating-point arithmetic. `epsilon' bounds the relative roundoff */
272 /* error. It is used for floating-point error analysis. */
273 /* */
274 /* `splitter' is used to split floating-point numbers into two half- */
275 /* length significands for exact multiplication. */
276 /* */
277 /* I imagine that a highly optimizing compiler might be too smart for its */
278 /* own good, and somehow cause this routine to fail, if it pretends that */
279 /* floating-point arithmetic is too much like real arithmetic. */
280 /* */
281 /* Don't change this routine unless you fully understand it. */
282 /* */
283 /*****************************************************************************/
284 
285 void exactinit()
286 {
287  qreal half;
288  qreal check, lastcheck;
289  int every_other;
290 
291  every_other = 1;
292  half = 0.5;
293  epsilon = 1.0;
294  splitter = 1.0;
295  check = 1.0;
296  /* Repeatedly divide `epsilon' by two until it is too small to add to */
297  /* one without causing roundoff. (Also check if the sum is equal to */
298  /* the previous sum, for machines that round up instead of using exact */
299  /* rounding. Not that this library will work on such machines anyway. */
300  do
301  {
302  lastcheck = check;
303  epsilon *= half;
304  if (every_other)
305  {
306  splitter *= 2.0;
307  }
308  every_other = !every_other;
309  check = 1.0 + epsilon;
310  } while ((check != 1.0) && (check != lastcheck));
311  splitter += 1.0;
312 
313  /* Error bounds for orientation and incircle tests. */
314  resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
315  ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
316  ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
317  ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
318  o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
319  o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
320  o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
321  iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
322  iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
323  iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
324  isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
325  isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
326  isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
327 }
328 
329 /*****************************************************************************/
330 /* */
331 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
332 /* components from the output expansion. */
333 /* */
334 /* Sets h = e + f. See the long version of my paper for details. */
335 /* */
336 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
337 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
338 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
339 /* properties. */
340 /* */
341 /*****************************************************************************/
342 
343 int fast_expansion_sum_zeroelim(int elen, qreal *e, int flen, qreal *f, qreal *h) /* h cannot be e or f. */
344 {
345  qreal Q;
346  INEXACT qreal Qnew;
347  INEXACT qreal hh;
348  INEXACT qreal bvirt;
349  qreal avirt, bround, around;
350  int eindex, findex, hindex;
351  qreal enow, fnow;
352 
353  enow = e[0];
354  fnow = f[0];
355  eindex = findex = 0;
356  if ((fnow > enow) == (fnow > -enow))
357  {
358  Q = enow;
359  enow = e[++eindex];
360  }
361  else
362  {
363  Q = fnow;
364  fnow = f[++findex];
365  }
366  hindex = 0;
367  if ((eindex < elen) && (findex < flen))
368  {
369  if ((fnow > enow) == (fnow > -enow))
370  {
371  Fast_Two_Sum(enow, Q, Qnew, hh);
372  enow = e[++eindex];
373  }
374  else
375  {
376  Fast_Two_Sum(fnow, Q, Qnew, hh);
377  fnow = f[++findex];
378  }
379  Q = Qnew;
380  if (hh != 0.0)
381  {
382  h[hindex++] = hh;
383  }
384  while ((eindex < elen) && (findex < flen))
385  {
386  if ((fnow > enow) == (fnow > -enow))
387  {
388  Two_Sum(Q, enow, Qnew, hh);
389  enow = e[++eindex];
390  }
391  else
392  {
393  Two_Sum(Q, fnow, Qnew, hh);
394  fnow = f[++findex];
395  }
396  Q = Qnew;
397  if (hh != 0.0)
398  {
399  h[hindex++] = hh;
400  }
401  }
402  }
403  while (eindex < elen)
404  {
405  Two_Sum(Q, enow, Qnew, hh);
406  enow = e[++eindex];
407  Q = Qnew;
408  if (hh != 0.0)
409  {
410  h[hindex++] = hh;
411  }
412  }
413  while (findex < flen)
414  {
415  Two_Sum(Q, fnow, Qnew, hh);
416  fnow = f[++findex];
417  Q = Qnew;
418  if (hh != 0.0)
419  {
420  h[hindex++] = hh;
421  }
422  }
423  if ((Q != 0.0) || (hindex == 0))
424  {
425  h[hindex++] = Q;
426  }
427  return hindex;
428 }
429 
430 /*****************************************************************************/
431 /* */
432 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
433 /* eliminating zero components from the */
434 /* output expansion. */
435 /* */
436 /* Sets h = be. See either version of my paper for details. */
437 /* */
438 /* Maintains the nonoverlapping property. If round-to-even is used (as */
439 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
440 /* properties as well. (That is, if e has one of these properties, so */
441 /* will h.) */
442 /* */
443 /*****************************************************************************/
444 
445 int scale_expansion_zeroelim(int elen, qreal *e, qreal b, qreal *h) /* e and h cannot be the same. */
446 {
447  INEXACT qreal Q, sum;
448  qreal hh;
449  INEXACT qreal product1;
450  qreal product0;
451  int eindex, hindex;
452  qreal enow;
453  INEXACT qreal bvirt;
454  qreal avirt, bround, around;
455  INEXACT qreal c;
456  INEXACT qreal abig;
457  qreal ahi, alo, bhi, blo;
458  qreal err1, err2, err3;
459 
460  Split(b, bhi, blo);
461  Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
462  hindex = 0;
463  if (hh != 0) {
464  h[hindex++] = hh;
465  }
466  for (eindex = 1; eindex < elen; eindex++)
467  {
468  enow = e[eindex];
469  Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
470  Two_Sum(Q, product0, sum, hh);
471  if (hh != 0)
472  {
473  h[hindex++] = hh;
474  }
475  Fast_Two_Sum(product1, sum, Q, hh);
476  if (hh != 0)
477  {
478  h[hindex++] = hh;
479  }
480  }
481  if ((Q != 0.0) || (hindex == 0))
482  {
483  h[hindex++] = Q;
484  }
485  return hindex;
486 }
487 
488 /*****************************************************************************/
489 /* */
490 /* estimate() Produce a one-word estimate of an expansion's value. */
491 /* */
492 /* See either version of my paper for details. */
493 /* */
494 /*****************************************************************************/
495 
496 qreal estimate(int elen, qreal *e)
497 {
498  qreal Q;
499  int eindex;
500 
501  Q = e[0];
502  for (eindex = 1; eindex < elen; eindex++)
503  {
504  Q += e[eindex];
505  }
506  return Q;
507 }
508 
509 qreal incircleadapt(qreal *pa, qreal *pb, qreal *pc, qreal *pd, qreal permanent)
510 {
511  INEXACT qreal adx, bdx, cdx, ady, bdy, cdy;
512  qreal det, errbound;
513 
514  INEXACT qreal bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
515  qreal bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
516  qreal bc[4], ca[4], ab[4];
517  INEXACT qreal bc3, ca3, ab3;
518  qreal axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
519  int axbclen, axxbclen, aybclen, ayybclen, alen;
520  qreal bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
521  int bxcalen, bxxcalen, bycalen, byycalen, blen;
522  qreal cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
523  int cxablen, cxxablen, cyablen, cyyablen, clen;
524  qreal abdet[64];
525  int ablen;
526  qreal fin1[1152], fin2[1152];
527  qreal *finnow, *finother, *finswap;
528  int finlength;
529 
530  qreal adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
531  INEXACT qreal adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
532  qreal adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
533  qreal aa[4], bb[4], cc[4];
534  INEXACT qreal aa3, bb3, cc3;
535  INEXACT qreal ti1, tj1;
536  qreal ti0, tj0;
537  qreal u[4], v[4];
538  INEXACT qreal u3, v3;
539  qreal temp8[8], temp16a[16], temp16b[16], temp16c[16];
540  qreal temp32a[32], temp32b[32], temp48[48], temp64[64];
541  int temp8len, temp16alen, temp16blen, temp16clen;
542  int temp32alen, temp32blen, temp48len, temp64len;
543  qreal axtbb[8], axtcc[8], aytbb[8], aytcc[8];
544  // cppcheck-suppress variableScope
545  int axtbblen, axtcclen, aytbblen, aytcclen;
546  qreal bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
547  // cppcheck-suppress variableScope
548  int bxtaalen, bxtcclen, bytaalen, bytcclen;
549  qreal cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
550  // cppcheck-suppress variableScope
551  int cxtaalen, cxtbblen, cytaalen, cytbblen;
552  qreal axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
553  int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;
554  qreal axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
555  // cppcheck-suppress variableScope
556  int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
557  qreal axtbctt[8], aytbctt[8], bxtcatt[8];
558  qreal bytcatt[8], cxtabtt[8], cytabtt[8];
559  // cppcheck-suppress variableScope
560  int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
561  qreal abt[8], bct[8], cat[8];
562  // cppcheck-suppress variableScope
563  int abtlen, bctlen, catlen;
564  qreal abtt[4], bctt[4], catt[4];
565  // cppcheck-suppress variableScope
566  int abttlen, bcttlen, cattlen;
567  INEXACT qreal abtt3, bctt3, catt3;
568  qreal negate;
569 
570  INEXACT qreal bvirt;
571  qreal avirt, bround, around;
572  INEXACT qreal c;
573  INEXACT qreal abig;
574  qreal ahi, alo, bhi, blo;
575  qreal err1, err2, err3;
576  INEXACT qreal _i, _j;
577  qreal _0;
578 
579  adx = (qreal) (pa[0] - pd[0]);
580  bdx = (qreal) (pb[0] - pd[0]);
581  cdx = (qreal) (pc[0] - pd[0]);
582  ady = (qreal) (pa[1] - pd[1]);
583  bdy = (qreal) (pb[1] - pd[1]);
584  cdy = (qreal) (pc[1] - pd[1]);
585 
586  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
587  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
588  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
589  bc[3] = bc3;
590  axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
591  axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
592  aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
593  ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
594  alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
595 
596  Two_Product(cdx, ady, cdxady1, cdxady0);
597  Two_Product(adx, cdy, adxcdy1, adxcdy0);
598  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
599  ca[3] = ca3;
600  bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
601  bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
602  bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
603  byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
604  blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
605 
606  Two_Product(adx, bdy, adxbdy1, adxbdy0);
607  Two_Product(bdx, ady, bdxady1, bdxady0);
608  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
609  ab[3] = ab3;
610  cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
611  cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
612  cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
613  cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
614  clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
615 
616  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
617  finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
618 
619  det = estimate(finlength, fin1);
620  errbound = iccerrboundB * permanent;
621  if ((det >= errbound) || (-det >= errbound))
622  {
623  return det;
624  }
625 
626  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
627  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
628  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
629  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
630  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
631  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
632  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
633  && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0))
634  {
635  return det;
636  }
637 
638  errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
639  det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail))
640  + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
641  + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail))
642  + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
643  + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail))
644  + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
645  if ((det >= errbound) || (-det >= errbound))
646  {
647  return det;
648  }
649 
650  finnow = fin1;
651  finother = fin2;
652 
653  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) || (cdytail != 0.0))
654  {
655  Square(adx, adxadx1, adxadx0);
656  Square(ady, adyady1, adyady0);
657  Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
658  aa[3] = aa3;
659  }
660  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) || (adytail != 0.0))
661  {
662  Square(bdx, bdxbdx1, bdxbdx0);
663  Square(bdy, bdybdy1, bdybdy0);
664  Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
665  bb[3] = bb3;
666  }
667  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) || (bdytail != 0.0))
668  {
669  Square(cdx, cdxcdx1, cdxcdx0);
670  Square(cdy, cdycdy1, cdycdy0);
671  Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
672  cc[3] = cc3;
673  }
674 
675  if (adxtail != 0.0)
676  {
677  axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
678  temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, temp16a);
679 
680  axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
681  temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
682 
683  axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
684  temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
685 
686  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
687  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, temp32alen, temp32a, temp48);
688  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
689  finswap = finnow; finnow = finother; finother = finswap;
690  }
691  if (adytail != 0.0)
692  {
693  aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
694  temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, temp16a);
695 
696  aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
697  temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
698 
699  aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
700  temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
701 
702  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
703  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, temp32alen, temp32a, temp48);
704  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
705  finswap = finnow; finnow = finother; finother = finswap;
706  }
707  if (bdxtail != 0.0)
708  {
709  bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
710  temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, temp16a);
711 
712  bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
713  temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
714 
715  bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
716  temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
717 
718  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
719  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, temp32alen, temp32a, temp48);
720  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
721  finswap = finnow; finnow = finother; finother = finswap;
722  }
723  if (bdytail != 0.0)
724  {
725  bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
726  temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, temp16a);
727 
728  bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
729  temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
730 
731  bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
732  temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
733 
734  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
735  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, temp32alen, temp32a, temp48);
736  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
737  finswap = finnow; finnow = finother; finother = finswap;
738  }
739  if (cdxtail != 0.0)
740  {
741  cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
742  temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, temp16a);
743 
744  cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
745  temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
746 
747  cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
748  temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
749 
750  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
751  temp16blen, temp16b, temp32a);
752  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
753  temp32alen, temp32a, temp48);
754  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
755  temp48, finother);
756  finswap = finnow; finnow = finother; finother = finswap;
757  }
758  if (cdytail != 0.0)
759  {
760  cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
761  temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, temp16a);
762 
763  cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
764  temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
765 
766  cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
767  temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
768 
769  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
770  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, temp32alen, temp32a, temp48);
771  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
772  finswap = finnow; finnow = finother; finother = finswap;
773  }
774 
775  if ((adxtail != 0.0) || (adytail != 0.0))
776  {
777  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) || (cdytail != 0.0))
778  {
779  Two_Product(bdxtail, cdy, ti1, ti0);
780  Two_Product(bdx, cdytail, tj1, tj0);
781  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
782  u[3] = u3;
783  negate = -bdy;
784  Two_Product(cdxtail, negate, ti1, ti0);
785  negate = -bdytail;
786  Two_Product(cdx, negate, tj1, tj0);
787  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
788  v[3] = v3;
789  bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
790 
791  Two_Product(bdxtail, cdytail, ti1, ti0);
792  Two_Product(cdxtail, bdytail, tj1, tj0);
793  Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
794  bctt[3] = bctt3;
795  bcttlen = 4;
796  }
797  else
798  {
799  bct[0] = 0.0;
800  bctlen = 1;
801  bctt[0] = 0.0;
802  bcttlen = 1;
803  }
804 
805  if (adxtail != 0.0)
806  {
807  temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
808  axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
809  temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, temp32a);
810  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
811  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
812  finswap = finnow; finnow = finother; finother = finswap;
813  if (bdytail != 0.0)
814  {
815  temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
816  temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, temp16a);
817  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
818  finswap = finnow; finnow = finother; finother = finswap;
819  }
820  if (cdytail != 0.0)
821  {
822  temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
823  temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, temp16a);
824  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
825  finswap = finnow; finnow = finother; finother = finswap;
826  }
827 
828  temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, temp32a);
829  axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
830  temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, temp16a);
831  temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, temp16b);
832  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
833  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
834  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
835  finswap = finnow; finnow = finother; finother = finswap;
836  }
837  if (adytail != 0.0)
838  {
839  temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
840  aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
841  temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, temp32a);
842  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
843  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
844  finswap = finnow; finnow = finother; finother = finswap;
845 
846 
847  temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, temp32a);
848  aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
849  temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, temp16a);
850  temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, temp16b);
851  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
852  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
853  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
854  finswap = finnow; finnow = finother; finother = finswap;
855  }
856  }
857  if ((bdxtail != 0.0) || (bdytail != 0.0))
858  {
859  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) || (adytail != 0.0))
860  {
861  Two_Product(cdxtail, ady, ti1, ti0);
862  Two_Product(cdx, adytail, tj1, tj0);
863  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
864  u[3] = u3;
865  negate = -cdy;
866  Two_Product(adxtail, negate, ti1, ti0);
867  negate = -cdytail;
868  Two_Product(adx, negate, tj1, tj0);
869  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
870  v[3] = v3;
871  catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
872 
873  Two_Product(cdxtail, adytail, ti1, ti0);
874  Two_Product(adxtail, cdytail, tj1, tj0);
875  Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
876  catt[3] = catt3;
877  cattlen = 4;
878  }
879  else
880  {
881  cat[0] = 0.0;
882  catlen = 1;
883  catt[0] = 0.0;
884  cattlen = 1;
885  }
886 
887  if (bdxtail != 0.0)
888  {
889  temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
890  bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
891  temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, temp32a);
892  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
893  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
894  finswap = finnow;
895  finnow = finother;
896  finother = finswap;
897  if (cdytail != 0.0)
898  {
899  temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
900  temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, temp16a);
901  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
902  finswap = finnow;
903  finnow = finother;
904  finother = finswap;
905  }
906  if (adytail != 0.0)
907  {
908  temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
909  temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, temp16a);
910  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
911  finswap = finnow;
912  finnow = finother;
913  finother = finswap;
914  }
915 
916  temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, temp32a);
917  bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
918  temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, temp16a);
919  temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, temp16b);
920  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
921  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
922  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
923  finswap = finnow; finnow = finother; finother = finswap;
924  }
925  if (bdytail != 0.0)
926  {
927  temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
928  bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
929  temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, temp32a);
930  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
931  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
932  finswap = finnow;
933  finnow = finother;
934  finother = finswap;
935 
936 
937  temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, temp32a);
938  bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
939  temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, temp16a);
940  temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, temp16b);
941  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
942  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
943  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
944  finswap = finnow;
945  finnow = finother;
946  finother = finswap;
947  }
948  }
949  if ((cdxtail != 0.0) || (cdytail != 0.0))
950  {
951  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) || (bdytail != 0.0))
952  {
953  Two_Product(adxtail, bdy, ti1, ti0);
954  Two_Product(adx, bdytail, tj1, tj0);
955  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
956  u[3] = u3;
957  negate = -ady;
958  Two_Product(bdxtail, negate, ti1, ti0);
959  negate = -adytail;
960  Two_Product(bdx, negate, tj1, tj0);
961  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
962  v[3] = v3;
963  abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
964 
965  Two_Product(adxtail, bdytail, ti1, ti0);
966  Two_Product(bdxtail, adytail, tj1, tj0);
967  Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
968  abtt[3] = abtt3;
969  abttlen = 4;
970  }
971  else
972  {
973  abt[0] = 0.0;
974  abtlen = 1;
975  abtt[0] = 0.0;
976  abttlen = 1;
977  }
978 
979  if (cdxtail != 0.0)
980  {
981  temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
982  cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
983  temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, temp32a);
984  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
985  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
986  finswap = finnow;
987  finnow = finother;
988  finother = finswap;
989  if (adytail != 0.0)
990  {
991  temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
992  temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, temp16a);
993  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
994  finswap = finnow;
995  finnow = finother;
996  finother = finswap;
997  }
998  if (bdytail != 0.0)
999  {
1000  temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
1001  temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, temp16a);
1002  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, temp16a, finother);
1003  finswap = finnow; finnow = finother; finother = finswap;
1004  }
1005 
1006  temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, temp32a);
1007  cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
1008  temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, temp16a);
1009  temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, temp16b);
1010  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
1011  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
1012  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
1013  finswap = finnow;
1014  finnow = finother;
1015  finother = finswap;
1016  }
1017  if (cdytail != 0.0)
1018  {
1019  temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
1020  cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
1021  temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, temp32a);
1022  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp32alen, temp32a, temp48);
1023  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, temp48, finother);
1024  finswap = finnow;
1025  finnow = finother;
1026  finother = finswap;
1027 
1028 
1029  temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, temp32a);
1030  cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
1031  temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, temp16a);
1032  temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, temp16b);
1033  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
1034  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, temp32blen, temp32b, temp64);
1035  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, temp64, finother);
1036  finswap = finnow; finnow = finother; finother = finswap;
1037  }
1038  }
1039 
1040  return finnow[finlength - 1];
1041 }
1042 
1043 
1044 qreal incircle(qreal *pa, qreal *pb, qreal *pc, qreal *pd)
1045 {
1046  qreal adx, bdx, cdx, ady, bdy, cdy;
1047  qreal bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
1048  qreal alift, blift, clift;
1049  qreal det;
1050  qreal permanent, errbound;
1051 
1052  adx = pa[0] - pd[0];
1053  bdx = pb[0] - pd[0];
1054  cdx = pc[0] - pd[0];
1055  ady = pa[1] - pd[1];
1056  bdy = pb[1] - pd[1];
1057  cdy = pc[1] - pd[1];
1058 
1059  bdxcdy = bdx * cdy;
1060  cdxbdy = cdx * bdy;
1061  alift = adx * adx + ady * ady;
1062 
1063  cdxady = cdx * ady;
1064  adxcdy = adx * cdy;
1065  blift = bdx * bdx + bdy * bdy;
1066 
1067  adxbdy = adx * bdy;
1068  bdxady = bdx * ady;
1069  clift = cdx * cdx + cdy * cdy;
1070 
1071  det = alift * (bdxcdy - cdxbdy)
1072  + blift * (cdxady - adxcdy)
1073  + clift * (adxbdy - bdxady);
1074 
1075  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
1076  + (Absolute(cdxady) + Absolute(adxcdy)) * blift
1077  + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
1078  errbound = iccerrboundA * permanent;
1079  if ((det > errbound) || (-det > errbound))
1080  {
1081  return det;
1082  }
1083 
1084  return incircleadapt(pa, pb, pc, pd, permanent);
1085 }
1086 
#define Square(a, x, y)
Definition: predicates.cpp:234
qreal ccwerrboundA
Definition: predicates.cpp:261
qreal ccwerrboundB
Definition: predicates.cpp:261
#define Two_Product(a, b, x, y)
Definition: predicates.cpp:211
qreal epsilon
Definition: predicates.cpp:258
qreal splitter
Definition: predicates.cpp:257
void exactinit()
Definition: predicates.cpp:285
qreal estimate(int elen, qreal *e)
Definition: predicates.cpp:496
qreal iccerrboundC
Definition: predicates.cpp:263
qreal incircle(qreal *pa, qreal *pb, qreal *pc, qreal *pd)
qreal o3derrboundC
Definition: predicates.cpp:262
#define Two_Product_Presplit(a, b, bhi, blo, x, y)
Definition: predicates.cpp:218
qreal o3derrboundB
Definition: predicates.cpp:262
int fast_expansion_sum_zeroelim(int elen, qreal *e, int flen, qreal *f, qreal *h)
Definition: predicates.cpp:343
#define Two_Diff_Tail(a, b, x, y)
Definition: predicates.cpp:186
qreal resulterrbound
Definition: predicates.cpp:260
int scale_expansion_zeroelim(int elen, qreal *e, qreal b, qreal *h)
Definition: predicates.cpp:445
qreal isperrboundC
Definition: predicates.cpp:264
qreal incircleadapt(qreal *pa, qreal *pb, qreal *pc, qreal *pd, qreal permanent)
Definition: predicates.cpp:509
qreal ccwerrboundC
Definition: predicates.cpp:261
qreal o3derrboundA
Definition: predicates.cpp:262
qreal isperrboundB
Definition: predicates.cpp:264
#define Two_Sum(a, b, x, y)
Definition: predicates.cpp:182
qreal isperrboundA
Definition: predicates.cpp:264
#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0)
Definition: predicates.cpp:253
#define INEXACT
Definition: predicates.cpp:136
#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0)
Definition: predicates.cpp:249
#define Fast_Two_Sum(a, b, x, y)
Definition: predicates.cpp:171
#define Split(a, ahi, alo)
Definition: predicates.cpp:197
#define Absolute(a)
Definition: predicates.cpp:150
qreal iccerrboundB
Definition: predicates.cpp:263
qreal iccerrboundA
Definition: predicates.cpp:263