1 /*****************************************************************************/
3 /* Routines for Arbitrary Precision Floating-point Arithmetic */
4 /* and Fast Robust Geometric Predicates */
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 */
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.) */
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 . */
30 /*****************************************************************************/
32 /*****************************************************************************/
34 /* Using this code: */
36 /* First, read the short or long version of the paper (from the Web page */
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. */
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 */
48 /* orient2d(pa, pb, pc) */
49 /* orient2dfast(pa, pb, pc) */
50 /* orient3d(pa, pb, pc, pd) */
51 /* orient3dfast(pa, pb, pc, pd) */
52 /* incircle(pa, pb, pc, pd) */
53 /* incirclefast(pa, pb, pc, pd) */
54 /* insphere(pa, pb, pc, pd, pe) */
55 /* inspherefast(pa, pb, pc, pd, pe) */
57 /* Those with suffix "fast" are approximate, non-robust versions. Those */
58 /* without the suffix are adaptive precision, robust versions. There */
59 /* are also versions with the suffices "exact" and "slow", which are */
60 /* non-adaptive, exact arithmetic versions, which I use only for timings */
61 /* in my arithmetic papers. */
64 /* An expansion is represented by an array of floating-point numbers, */
65 /* sorted from smallest to largest magnitude (possibly with interspersed */
66 /* zeros). The length of each expansion is stored as a separate integer, */
67 /* and each arithmetic function returns an integer which is the length */
68 /* of the expansion it created. */
70 /* Several arithmetic functions are defined. Their parameters are */
72 /* e, f Input expansions */
73 /* elen, flen Lengths of input expansions (must be >= 1) */
74 /* h Output expansion */
77 /* The arithmetic functions are */
79 /* grow_expansion(elen, e, b, h) */
80 /* grow_expansion_zeroelim(elen, e, b, h) */
81 /* expansion_sum(elen, e, flen, f, h) */
82 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */
83 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */
84 /* fast_expansion_sum(elen, e, flen, f, h) */
85 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
86 /* linear_expansion_sum(elen, e, flen, f, h) */
87 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
88 /* scale_expansion(elen, e, b, h) */
89 /* scale_expansion_zeroelim(elen, e, b, h) */
90 /* compress(elen, e, h) */
92 /* All of these are described in the long version of the paper; some are */
93 /* described in the short version. All return an integer that is the */
94 /* length of h. Those with suffix _zeroelim perform zero elimination, */
95 /* and are recommended over their counterparts. The procedure */
96 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
97 /* processors that do not use the round-to-even tiebreaking rule) is */
98 /* recommended over expansion_sum_zeroelim(). Each procedure has a */
99 /* little note next to it (in the code below) that tells you whether or */
100 /* not the output expansion may be the same array as one of the input */
104 /* If you look around below, you'll also find macros for a bunch of */
105 /* simple unrolled arithmetic operations, and procedures for printing */
106 /* expansions (commented out because they don't work with all C */
107 /* compilers) and for generating random floating-point numbers whose */
108 /* significand bits are all random. Most of the macros have undocumented */
109 /* requirements that certain of their parameters should not be the same */
110 /* variable; for safety, better to make sure all the parameters are */
111 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
112 /* have questions. */
114 /*****************************************************************************/
119 #include "predicates.h"
121 /* Use header file generated automatically by predicates_init. */
122 //#define USE_PREDICATES_INIT
124 #ifdef USE_PREDICATES_INIT
125 #include "predicates_init.h"
126 #endif /* USE_PREDICATES_INIT */
128 /* FPU control. We MUST have only double precision (not extended precision) */
129 #include "rounding.h"
131 /* On some machines, the exact arithmetic routines might be defeated by the */
132 /* use of internal extended precision floating-point registers. Sometimes */
133 /* this problem can be fixed by defining certain values to be volatile, */
134 /* thus forcing them to be stored to memory and rounded off. This isn't */
135 /* a great solution, though, as it slows the arithmetic down. */
137 /* To try this out, write "#define INEXACT volatile" below. Normally, */
138 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
140 #define INEXACT /* Nothing */
141 /* #define INEXACT volatile */
143 #define REAL double /* float or double */
144 #define REALPRINT doubleprint
145 #define REALRAND doublerand
146 #define NARROWRAND narrowdoublerand
147 #define UNIFORMRAND uniformdoublerand
149 /* Which of the following two methods of finding the absolute values is */
150 /* fastest is compiler-dependent. A few compilers can inline and optimize */
151 /* the fabs() call; but most will incur the overhead of a function call, */
152 /* which is disastrously slow. A faster way on IEEE machines might be to */
153 /* mask the appropriate bit, but that's difficult to do in C. */
155 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
156 /* #define Absolute(a) fabs(a) */
158 /* Many of the operations are broken up into two pieces, a main part that */
159 /* performs an approximate operation, and a "tail" that computes the */
160 /* roundoff error of that operation. */
162 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
163 /* Split(), and Two_Product() are all implemented as described in the */
164 /* reference. Each of these macros requires certain variables to be */
165 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
166 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
167 /* they store the result of an operation that may incur roundoff error. */
168 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
169 /* also be declared `INEXACT'. */
171 #define Fast_Two_Sum_Tail(a, b, x, y) \
175 #define Fast_Two_Sum(a, b, x, y) \
176 x = (REAL) (a + b); \
177 Fast_Two_Sum_Tail(a, b, x, y)
179 #define Fast_Two_Diff_Tail(a, b, x, y) \
183 #define Fast_Two_Diff(a, b, x, y) \
184 x = (REAL) (a - b); \
185 Fast_Two_Diff_Tail(a, b, x, y)
187 #define Two_Sum_Tail(a, b, x, y) \
188 bvirt = (REAL) (x - a); \
190 bround = b - bvirt; \
191 around = a - avirt; \
194 #define Two_Sum(a, b, x, y) \
195 x = (REAL) (a + b); \
196 Two_Sum_Tail(a, b, x, y)
198 #define Two_Diff_Tail(a, b, x, y) \
199 bvirt = (REAL) (a - x); \
201 bround = bvirt - b; \
202 around = a - avirt; \
205 #define Two_Diff(a, b, x, y) \
206 x = (REAL) (a - b); \
207 Two_Diff_Tail(a, b, x, y)
209 #define Split(a, ahi, alo) \
210 c = (REAL) (splitter * a); \
211 abig = (REAL) (c - a); \
215 #define Two_Product_Tail(a, b, x, y) \
216 Split(a, ahi, alo); \
217 Split(b, bhi, blo); \
218 err1 = x - (ahi * bhi); \
219 err2 = err1 - (alo * bhi); \
220 err3 = err2 - (ahi * blo); \
221 y = (alo * blo) - err3
223 #define Two_Product(a, b, x, y) \
224 x = (REAL) (a * b); \
225 Two_Product_Tail(a, b, x, y)
227 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
228 /* already been split. Avoids redundant splitting. */
230 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
231 x = (REAL) (a * b); \
232 Split(a, ahi, alo); \
233 err1 = x - (ahi * bhi); \
234 err2 = err1 - (alo * bhi); \
235 err3 = err2 - (ahi * blo); \
236 y = (alo * blo) - err3
238 /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
239 /* already been split. Avoids redundant splitting. */
241 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
242 x = (REAL) (a * b); \
243 err1 = x - (ahi * bhi); \
244 err2 = err1 - (alo * bhi); \
245 err3 = err2 - (ahi * blo); \
246 y = (alo * blo) - err3
248 /* Square() can be done more quickly than Two_Product(). */
250 #define Square_Tail(a, x, y) \
251 Split(a, ahi, alo); \
252 err1 = x - (ahi * ahi); \
253 err3 = err1 - ((ahi + ahi) * alo); \
254 y = (alo * alo) - err3
256 #define Square(a, x, y) \
257 x = (REAL) (a * a); \
260 /* Macros for summing expansions of various fixed lengths. These are all */
261 /* unrolled versions of Expansion_Sum(). */
263 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
264 Two_Sum(a0, b , _i, x0); \
265 Two_Sum(a1, _i, x2, x1)
267 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
268 Two_Diff(a0, b , _i, x0); \
269 Two_Sum( a1, _i, x2, x1)
271 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
272 Two_One_Sum(a1, a0, b0, _j, _0, x0); \
273 Two_One_Sum(_j, _0, b1, x3, x2, x1)
275 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
276 Two_One_Diff(a1, a0, b0, _j, _0, x0); \
277 Two_One_Diff(_j, _0, b1, x3, x2, x1)
279 #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
280 Two_One_Sum(a1, a0, b , _j, x1, x0); \
281 Two_One_Sum(a3, a2, _j, x4, x3, x2)
283 #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
284 Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
285 Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
287 #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
289 Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
290 Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
292 #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
294 Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
295 Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
297 #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
298 x6, x5, x4, x3, x2, x1, x0) \
299 Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
301 Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
304 #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
305 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
306 Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
307 _2, _1, _0, x1, x0); \
308 Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
309 x7, x6, x5, x4, x3, x2)
311 /* Macros for multiplying expansions of various fixed lengths. */
313 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
314 Split(b, bhi, blo); \
315 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
316 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
317 Two_Sum(_i, _0, _k, x1); \
318 Fast_Two_Sum(_j, _k, x3, x2)
320 #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
321 Split(b, bhi, blo); \
322 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
323 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
324 Two_Sum(_i, _0, _k, x1); \
325 Fast_Two_Sum(_j, _k, _i, x2); \
326 Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
327 Two_Sum(_i, _0, _k, x3); \
328 Fast_Two_Sum(_j, _k, _i, x4); \
329 Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
330 Two_Sum(_i, _0, _k, x5); \
331 Fast_Two_Sum(_j, _k, x7, x6)
333 #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
334 Split(a0, a0hi, a0lo); \
335 Split(b0, bhi, blo); \
336 Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
337 Split(a1, a1hi, a1lo); \
338 Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
339 Two_Sum(_i, _0, _k, _1); \
340 Fast_Two_Sum(_j, _k, _l, _2); \
341 Split(b1, bhi, blo); \
342 Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
343 Two_Sum(_1, _0, _k, x1); \
344 Two_Sum(_2, _k, _j, _1); \
345 Two_Sum(_l, _j, _m, _2); \
346 Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
347 Two_Sum(_i, _0, _n, _0); \
348 Two_Sum(_1, _0, _i, x2); \
349 Two_Sum(_2, _i, _k, _1); \
350 Two_Sum(_m, _k, _l, _2); \
351 Two_Sum(_j, _n, _k, _0); \
352 Two_Sum(_1, _0, _j, x3); \
353 Two_Sum(_2, _j, _i, _1); \
354 Two_Sum(_l, _i, _m, _2); \
355 Two_Sum(_1, _k, _i, x4); \
356 Two_Sum(_2, _i, _k, x5); \
357 Two_Sum(_m, _k, x7, x6)
359 /* An expansion of length two can be squared more quickly than finding the */
360 /* product of two different expansions of length two, and the result is */
361 /* guaranteed to have no more than six (rather than eight) components. */
363 #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
364 Square(a0, _j, x0); \
366 Two_Product(a1, _0, _k, _1); \
367 Two_One_Sum(_k, _1, _j, _l, _2, x1); \
368 Square(a1, _j, _1); \
369 Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
371 #ifndef USE_PREDICATES_INIT
373 static REAL splitter
; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
374 /* A set of coefficients used to calculate maximum roundoff errors. */
375 static REAL resulterrbound
;
376 static REAL ccwerrboundA
, ccwerrboundB
, ccwerrboundC
;
377 static REAL o3derrboundA
, o3derrboundB
, o3derrboundC
;
378 static REAL iccerrboundA
, iccerrboundB
, iccerrboundC
;
379 static REAL isperrboundA
, isperrboundB
, isperrboundC
;
382 gts_predicates_init()
385 double check
= 1.0, lastcheck
;
387 /* epsilon = 2^(-p). Used to estimate roundoff errors. */
388 double epsilon
= 1.0;
394 /* Repeatedly divide `epsilon' by two until it is too small to add to */
395 /* one without causing roundoff. (Also check if the sum is equal to */
396 /* the previous sum, for machines that round up instead of using exact */
397 /* rounding. Not that this library will work on such machines anyway). */
404 every_other
= !every_other
;
405 check
= 1.0 + epsilon
;
406 } while ((check
!= 1.0) && (check
!= lastcheck
));
408 /* Error bounds for orientation and incircle tests. */
409 resulterrbound
= (3.0 + 8.0 * epsilon
) * epsilon
;
410 ccwerrboundA
= (3.0 + 16.0 * epsilon
) * epsilon
;
411 ccwerrboundB
= (2.0 + 12.0 * epsilon
) * epsilon
;
412 ccwerrboundC
= (9.0 + 64.0 * epsilon
) * epsilon
* epsilon
;
413 o3derrboundA
= (7.0 + 56.0 * epsilon
) * epsilon
;
414 o3derrboundB
= (3.0 + 28.0 * epsilon
) * epsilon
;
415 o3derrboundC
= (26.0 + 288.0 * epsilon
) * epsilon
* epsilon
;
416 iccerrboundA
= (10.0 + 96.0 * epsilon
) * epsilon
;
417 iccerrboundB
= (4.0 + 48.0 * epsilon
) * epsilon
;
418 iccerrboundC
= (44.0 + 576.0 * epsilon
) * epsilon
* epsilon
;
419 isperrboundA
= (16.0 + 224.0 * epsilon
) * epsilon
;
420 isperrboundB
= (5.0 + 72.0 * epsilon
) * epsilon
;
421 isperrboundC
= (71.0 + 1408.0 * epsilon
) * epsilon
* epsilon
;
427 #endif /* USE_PREDICATES_INIT */
429 /*****************************************************************************/
431 /* doubleprint() Print the bit representation of a double. */
433 /* Useful for debugging exact arithmetic routines. */
435 /*****************************************************************************/
438 void doubleprint(number)
441 unsigned long long no;
442 unsigned long long sign, expo;
446 no = *(unsigned long long *) &number;
447 sign = no & 0x8000000000000000ll;
448 expo = (no >> 52) & 0x7ffll;
449 exponent = (int) expo;
450 exponent = exponent - 1023;
456 if (exponent == -1023) {
458 "0.0000000000000000000000000000000000000000000000000000_ ( )");
462 for (i = 0; i < 52; i++) {
463 if (no & 0x0008000000000000ll) {
471 printf("_%d (%d)", exponent, exponent - 1 - bottomi);
476 /*****************************************************************************/
478 /* floatprint() Print the bit representation of a float. */
480 /* Useful for debugging exact arithmetic routines. */
482 /*****************************************************************************/
485 void floatprint(number)
493 no = *(unsigned *) &number;
494 sign = no & 0x80000000;
495 expo = (no >> 23) & 0xff;
496 exponent = (int) expo;
497 exponent = exponent - 127;
503 if (exponent == -127) {
504 printf("0.00000000000000000000000_ ( )");
508 for (i = 0; i < 23; i++) {
509 if (no & 0x00400000) {
517 printf("_%3d (%3d)", exponent, exponent - 1 - bottomi);
522 /*****************************************************************************/
524 /* expansion_print() Print the bit representation of an expansion. */
526 /* Useful for debugging exact arithmetic routines. */
528 /*****************************************************************************/
531 void expansion_print(elen, e)
537 for (i = elen - 1; i >= 0; i--) {
548 /*****************************************************************************/
550 /* doublerand() Generate a double with random 53-bit significand and a */
551 /* random exponent in [0, 511]. */
553 /*****************************************************************************/
556 static double doublerand()
566 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
567 for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) {
576 /*****************************************************************************/
578 /* narrowdoublerand() Generate a double with random 53-bit significand */
579 /* and a random exponent in [0, 7]. */
581 /*****************************************************************************/
584 static double narrowdoublerand()
594 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
595 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
604 /*****************************************************************************/
606 /* uniformdoublerand() Generate a double with random 53-bit significand. */
608 /*****************************************************************************/
611 static double uniformdoublerand()
618 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
623 /*****************************************************************************/
625 /* floatrand() Generate a float with random 24-bit significand and a */
626 /* random exponent in [0, 63]. */
628 /*****************************************************************************/
631 static float floatrand()
640 result = (float) ((a - 1073741824) >> 6);
641 for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) {
650 /*****************************************************************************/
652 /* narrowfloatrand() Generate a float with random 24-bit significand and */
653 /* a random exponent in [0, 7]. */
655 /*****************************************************************************/
658 static float narrowfloatrand()
667 result = (float) ((a - 1073741824) >> 6);
668 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
677 /*****************************************************************************/
679 /* uniformfloatrand() Generate a float with random 24-bit significand. */
681 /*****************************************************************************/
684 static float uniformfloatrand()
690 result = (float) ((a - 1073741824) >> 6);
695 /*****************************************************************************/
697 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
698 /* components from the output expansion. */
700 /* Sets h = e + f. See the long version of my paper for details. */
702 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
703 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
704 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
707 /*****************************************************************************/
709 static int fast_expansion_sum_zeroelim(int elen
, REAL
*e
,
710 int flen
, REAL
*f
, REAL
*h
)
711 /* h cannot be e or f. */
717 REAL avirt
, bround
, around
;
718 int eindex
, findex
, hindex
;
724 if ((fnow
> enow
) == (fnow
> -enow
)) {
732 if ((eindex
< elen
) && (findex
< flen
)) {
733 if ((fnow
> enow
) == (fnow
> -enow
)) {
734 Fast_Two_Sum(enow
, Q
, Qnew
, hh
);
737 Fast_Two_Sum(fnow
, Q
, Qnew
, hh
);
744 while ((eindex
< elen
) && (findex
< flen
)) {
745 if ((fnow
> enow
) == (fnow
> -enow
)) {
746 Two_Sum(Q
, enow
, Qnew
, hh
);
749 Two_Sum(Q
, fnow
, Qnew
, hh
);
758 while (eindex
< elen
) {
759 Two_Sum(Q
, enow
, Qnew
, hh
);
766 while (findex
< flen
) {
767 Two_Sum(Q
, fnow
, Qnew
, hh
);
774 if ((Q
!= 0.0) || (hindex
== 0)) {
780 /*****************************************************************************/
782 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
783 /* eliminating zero components from the */
784 /* output expansion. */
786 /* Sets h = be. See either version of my paper for details. */
788 /* Maintains the nonoverlapping property. If round-to-even is used (as */
789 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
790 /* properties as well. (That is, if e has one of these properties, so */
793 /*****************************************************************************/
795 static int scale_expansion_zeroelim(int elen
, REAL
*e
, REAL b
, REAL
*h
)
796 /* e and h cannot be the same. */
800 INEXACT REAL product1
;
805 REAL avirt
, bround
, around
;
808 REAL ahi
, alo
, bhi
, blo
;
809 REAL err1
, err2
, err3
;
812 Two_Product_Presplit(e
[0], b
, bhi
, blo
, Q
, hh
);
817 for (eindex
= 1; eindex
< elen
; eindex
++) {
819 Two_Product_Presplit(enow
, b
, bhi
, blo
, product1
, product0
);
820 Two_Sum(Q
, product0
, sum
, hh
);
824 Fast_Two_Sum(product1
, sum
, Q
, hh
);
829 if ((Q
!= 0.0) || (hindex
== 0)) {
835 /*****************************************************************************/
837 /* estimate() Produce a one-word estimate of an expansion's value. */
839 /* See either version of my paper for details. */
841 /*****************************************************************************/
843 static REAL
estimate(int elen
, REAL
*e
)
849 for (eindex
= 1; eindex
< elen
; eindex
++) {
855 /*****************************************************************************/
857 /* orient2dfast() Approximate 2D orientation test. Nonrobust. */
858 /* orient2dexact() Exact 2D orientation test. Robust. */
859 /* orient2dslow() Another exact 2D orientation test. Robust. */
860 /* orient2d() Adaptive exact 2D orientation test. Robust. */
862 /* Return a positive value if the points pa, pb, and pc occur */
863 /* in counterclockwise order; a negative value if they occur */
864 /* in clockwise order; and zero if they are collinear. The */
865 /* result is also a rough approximation of twice the signed */
866 /* area of the triangle defined by the three points. */
868 /* Only the first and last routine should be used; the middle two are for */
871 /* The last three use exact arithmetic to ensure a correct answer. The */
872 /* result returned is the determinant of a matrix. In orient2d() only, */
873 /* this determinant is computed adaptively, in the sense that exact */
874 /* arithmetic is used only to the degree it is needed to ensure that the */
875 /* returned value has the correct sign. Hence, orient2d() is usually quite */
876 /* fast, but will run more slowly when the input points are collinear or */
879 /*****************************************************************************/
881 static REAL
orient2dadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL detsum
)
883 INEXACT REAL acx
, acy
, bcx
, bcy
;
884 REAL acxtail
, acytail
, bcxtail
, bcytail
;
885 INEXACT REAL detleft
, detright
;
886 REAL detlefttail
, detrighttail
;
888 REAL B
[4], C1
[8], C2
[12], D
[16];
890 int C1length
, C2length
, Dlength
;
897 REAL avirt
, bround
, around
;
900 REAL ahi
, alo
, bhi
, blo
;
901 REAL err1
, err2
, err3
;
905 acx
= (REAL
) (pa
[0] - pc
[0]);
906 bcx
= (REAL
) (pb
[0] - pc
[0]);
907 acy
= (REAL
) (pa
[1] - pc
[1]);
908 bcy
= (REAL
) (pb
[1] - pc
[1]);
910 Two_Product(acx
, bcy
, detleft
, detlefttail
);
911 Two_Product(acy
, bcx
, detright
, detrighttail
);
913 Two_Two_Diff(detleft
, detlefttail
, detright
, detrighttail
,
914 B3
, B
[2], B
[1], B
[0]);
917 det
= estimate(4, B
);
918 errbound
= ccwerrboundB
* detsum
;
919 if ((det
>= errbound
) || (-det
>= errbound
)) {
923 Two_Diff_Tail(pa
[0], pc
[0], acx
, acxtail
);
924 Two_Diff_Tail(pb
[0], pc
[0], bcx
, bcxtail
);
925 Two_Diff_Tail(pa
[1], pc
[1], acy
, acytail
);
926 Two_Diff_Tail(pb
[1], pc
[1], bcy
, bcytail
);
928 if ((acxtail
== 0.0) && (acytail
== 0.0)
929 && (bcxtail
== 0.0) && (bcytail
== 0.0)) {
933 errbound
= ccwerrboundC
* detsum
+ resulterrbound
* Absolute(det
);
934 det
+= (acx
* bcytail
+ bcy
* acxtail
)
935 - (acy
* bcxtail
+ bcx
* acytail
);
936 if ((det
>= errbound
) || (-det
>= errbound
)) {
940 Two_Product(acxtail
, bcy
, s1
, s0
);
941 Two_Product(acytail
, bcx
, t1
, t0
);
942 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
944 C1length
= fast_expansion_sum_zeroelim(4, B
, 4, u
, C1
);
946 Two_Product(acx
, bcytail
, s1
, s0
);
947 Two_Product(acy
, bcxtail
, t1
, t0
);
948 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
950 C2length
= fast_expansion_sum_zeroelim(C1length
, C1
, 4, u
, C2
);
952 Two_Product(acxtail
, bcytail
, s1
, s0
);
953 Two_Product(acytail
, bcxtail
, t1
, t0
);
954 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
956 Dlength
= fast_expansion_sum_zeroelim(C2length
, C2
, 4, u
, D
);
958 return(D
[Dlength
- 1]);
961 REAL
orient2d(pa
, pb
, pc
)
966 REAL detleft
, detright
, det
;
967 REAL detsum
, errbound
;
972 detleft
= (pa
[0] - pc
[0]) * (pb
[1] - pc
[1]);
973 detright
= (pa
[1] - pc
[1]) * (pb
[0] - pc
[0]);
974 det
= detleft
- detright
;
977 if (detright
<= 0.0) {
981 detsum
= detleft
+ detright
;
983 } else if (detleft
< 0.0) {
984 if (detright
>= 0.0) {
988 detsum
= -detleft
- detright
;
995 errbound
= ccwerrboundA
* detsum
;
996 if ((det
>= errbound
) || (-det
>= errbound
)) {
1001 orient
= orient2dadapt(pa
, pb
, pc
, detsum
);
1006 /*****************************************************************************/
1008 /* orient3dfast() Approximate 3D orientation test. Nonrobust. */
1009 /* orient3dexact() Exact 3D orientation test. Robust. */
1010 /* orient3dslow() Another exact 3D orientation test. Robust. */
1011 /* orient3d() Adaptive exact 3D orientation test. Robust. */
1013 /* Return a positive value if the point pd lies below the */
1014 /* plane passing through pa, pb, and pc; "below" is defined so */
1015 /* that pa, pb, and pc appear in counterclockwise order when */
1016 /* viewed from above the plane. Returns a negative value if */
1017 /* pd lies above the plane. Returns zero if the points are */
1018 /* coplanar. The result is also a rough approximation of six */
1019 /* times the signed volume of the tetrahedron defined by the */
1022 /* Only the first and last routine should be used; the middle two are for */
1025 /* The last three use exact arithmetic to ensure a correct answer. The */
1026 /* result returned is the determinant of a matrix. In orient3d() only, */
1027 /* this determinant is computed adaptively, in the sense that exact */
1028 /* arithmetic is used only to the degree it is needed to ensure that the */
1029 /* returned value has the correct sign. Hence, orient3d() is usually quite */
1030 /* fast, but will run more slowly when the input points are coplanar or */
1033 /*****************************************************************************/
1035 static REAL
orient3dadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
,
1038 INEXACT REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
, adz
, bdz
, cdz
;
1041 INEXACT REAL bdxcdy1
, cdxbdy1
, cdxady1
, adxcdy1
, adxbdy1
, bdxady1
;
1042 REAL bdxcdy0
, cdxbdy0
, cdxady0
, adxcdy0
, adxbdy0
, bdxady0
;
1043 REAL bc
[4], ca
[4], ab
[4];
1044 INEXACT REAL bc3
, ca3
, ab3
;
1045 REAL adet
[8], bdet
[8], cdet
[8];
1046 int alen
, blen
, clen
;
1049 REAL
*finnow
, *finother
, *finswap
;
1050 REAL fin1
[192], fin2
[192];
1053 REAL adxtail
, bdxtail
, cdxtail
;
1054 REAL adytail
, bdytail
, cdytail
;
1055 REAL adztail
, bdztail
, cdztail
;
1056 INEXACT REAL at_blarge
, at_clarge
;
1057 INEXACT REAL bt_clarge
, bt_alarge
;
1058 INEXACT REAL ct_alarge
, ct_blarge
;
1059 REAL at_b
[4], at_c
[4], bt_c
[4], bt_a
[4], ct_a
[4], ct_b
[4];
1060 int at_blen
, at_clen
, bt_clen
, bt_alen
, ct_alen
, ct_blen
;
1061 INEXACT REAL bdxt_cdy1
, cdxt_bdy1
, cdxt_ady1
;
1062 INEXACT REAL adxt_cdy1
, adxt_bdy1
, bdxt_ady1
;
1063 REAL bdxt_cdy0
, cdxt_bdy0
, cdxt_ady0
;
1064 REAL adxt_cdy0
, adxt_bdy0
, bdxt_ady0
;
1065 INEXACT REAL bdyt_cdx1
, cdyt_bdx1
, cdyt_adx1
;
1066 INEXACT REAL adyt_cdx1
, adyt_bdx1
, bdyt_adx1
;
1067 REAL bdyt_cdx0
, cdyt_bdx0
, cdyt_adx0
;
1068 REAL adyt_cdx0
, adyt_bdx0
, bdyt_adx0
;
1069 REAL bct
[8], cat
[8], abt
[8];
1070 int bctlen
, catlen
, abtlen
;
1071 INEXACT REAL bdxt_cdyt1
, cdxt_bdyt1
, cdxt_adyt1
;
1072 INEXACT REAL adxt_cdyt1
, adxt_bdyt1
, bdxt_adyt1
;
1073 REAL bdxt_cdyt0
, cdxt_bdyt0
, cdxt_adyt0
;
1074 REAL adxt_cdyt0
, adxt_bdyt0
, bdxt_adyt0
;
1075 REAL u
[4], v
[12], w
[16];
1077 int vlength
, wlength
;
1081 REAL avirt
, bround
, around
;
1084 REAL ahi
, alo
, bhi
, blo
;
1085 REAL err1
, err2
, err3
;
1086 INEXACT REAL _i
, _j
, _k
;
1089 adx
= (REAL
) (pa
[0] - pd
[0]);
1090 bdx
= (REAL
) (pb
[0] - pd
[0]);
1091 cdx
= (REAL
) (pc
[0] - pd
[0]);
1092 ady
= (REAL
) (pa
[1] - pd
[1]);
1093 bdy
= (REAL
) (pb
[1] - pd
[1]);
1094 cdy
= (REAL
) (pc
[1] - pd
[1]);
1095 adz
= (REAL
) (pa
[2] - pd
[2]);
1096 bdz
= (REAL
) (pb
[2] - pd
[2]);
1097 cdz
= (REAL
) (pc
[2] - pd
[2]);
1099 Two_Product(bdx
, cdy
, bdxcdy1
, bdxcdy0
);
1100 Two_Product(cdx
, bdy
, cdxbdy1
, cdxbdy0
);
1101 Two_Two_Diff(bdxcdy1
, bdxcdy0
, cdxbdy1
, cdxbdy0
, bc3
, bc
[2], bc
[1], bc
[0]);
1103 alen
= scale_expansion_zeroelim(4, bc
, adz
, adet
);
1105 Two_Product(cdx
, ady
, cdxady1
, cdxady0
);
1106 Two_Product(adx
, cdy
, adxcdy1
, adxcdy0
);
1107 Two_Two_Diff(cdxady1
, cdxady0
, adxcdy1
, adxcdy0
, ca3
, ca
[2], ca
[1], ca
[0]);
1109 blen
= scale_expansion_zeroelim(4, ca
, bdz
, bdet
);
1111 Two_Product(adx
, bdy
, adxbdy1
, adxbdy0
);
1112 Two_Product(bdx
, ady
, bdxady1
, bdxady0
);
1113 Two_Two_Diff(adxbdy1
, adxbdy0
, bdxady1
, bdxady0
, ab3
, ab
[2], ab
[1], ab
[0]);
1115 clen
= scale_expansion_zeroelim(4, ab
, cdz
, cdet
);
1117 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
1118 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, fin1
);
1120 det
= estimate(finlength
, fin1
);
1121 errbound
= o3derrboundB
* permanent
;
1122 if ((det
>= errbound
) || (-det
>= errbound
)) {
1126 Two_Diff_Tail(pa
[0], pd
[0], adx
, adxtail
);
1127 Two_Diff_Tail(pb
[0], pd
[0], bdx
, bdxtail
);
1128 Two_Diff_Tail(pc
[0], pd
[0], cdx
, cdxtail
);
1129 Two_Diff_Tail(pa
[1], pd
[1], ady
, adytail
);
1130 Two_Diff_Tail(pb
[1], pd
[1], bdy
, bdytail
);
1131 Two_Diff_Tail(pc
[1], pd
[1], cdy
, cdytail
);
1132 Two_Diff_Tail(pa
[2], pd
[2], adz
, adztail
);
1133 Two_Diff_Tail(pb
[2], pd
[2], bdz
, bdztail
);
1134 Two_Diff_Tail(pc
[2], pd
[2], cdz
, cdztail
);
1136 if ((adxtail
== 0.0) && (bdxtail
== 0.0) && (cdxtail
== 0.0)
1137 && (adytail
== 0.0) && (bdytail
== 0.0) && (cdytail
== 0.0)
1138 && (adztail
== 0.0) && (bdztail
== 0.0) && (cdztail
== 0.0)) {
1142 errbound
= o3derrboundC
* permanent
+ resulterrbound
* Absolute(det
);
1143 det
+= (adz
* ((bdx
* cdytail
+ cdy
* bdxtail
)
1144 - (bdy
* cdxtail
+ cdx
* bdytail
))
1145 + adztail
* (bdx
* cdy
- bdy
* cdx
))
1146 + (bdz
* ((cdx
* adytail
+ ady
* cdxtail
)
1147 - (cdy
* adxtail
+ adx
* cdytail
))
1148 + bdztail
* (cdx
* ady
- cdy
* adx
))
1149 + (cdz
* ((adx
* bdytail
+ bdy
* adxtail
)
1150 - (ady
* bdxtail
+ bdx
* adytail
))
1151 + cdztail
* (adx
* bdy
- ady
* bdx
));
1152 if ((det
>= errbound
) || (-det
>= errbound
)) {
1159 if (adxtail
== 0.0) {
1160 if (adytail
== 0.0) {
1167 Two_Product(negate
, bdx
, at_blarge
, at_b
[0]);
1168 at_b
[1] = at_blarge
;
1170 Two_Product(adytail
, cdx
, at_clarge
, at_c
[0]);
1171 at_c
[1] = at_clarge
;
1175 if (adytail
== 0.0) {
1176 Two_Product(adxtail
, bdy
, at_blarge
, at_b
[0]);
1177 at_b
[1] = at_blarge
;
1180 Two_Product(negate
, cdy
, at_clarge
, at_c
[0]);
1181 at_c
[1] = at_clarge
;
1184 Two_Product(adxtail
, bdy
, adxt_bdy1
, adxt_bdy0
);
1185 Two_Product(adytail
, bdx
, adyt_bdx1
, adyt_bdx0
);
1186 Two_Two_Diff(adxt_bdy1
, adxt_bdy0
, adyt_bdx1
, adyt_bdx0
,
1187 at_blarge
, at_b
[2], at_b
[1], at_b
[0]);
1188 at_b
[3] = at_blarge
;
1190 Two_Product(adytail
, cdx
, adyt_cdx1
, adyt_cdx0
);
1191 Two_Product(adxtail
, cdy
, adxt_cdy1
, adxt_cdy0
);
1192 Two_Two_Diff(adyt_cdx1
, adyt_cdx0
, adxt_cdy1
, adxt_cdy0
,
1193 at_clarge
, at_c
[2], at_c
[1], at_c
[0]);
1194 at_c
[3] = at_clarge
;
1198 if (bdxtail
== 0.0) {
1199 if (bdytail
== 0.0) {
1206 Two_Product(negate
, cdx
, bt_clarge
, bt_c
[0]);
1207 bt_c
[1] = bt_clarge
;
1209 Two_Product(bdytail
, adx
, bt_alarge
, bt_a
[0]);
1210 bt_a
[1] = bt_alarge
;
1214 if (bdytail
== 0.0) {
1215 Two_Product(bdxtail
, cdy
, bt_clarge
, bt_c
[0]);
1216 bt_c
[1] = bt_clarge
;
1219 Two_Product(negate
, ady
, bt_alarge
, bt_a
[0]);
1220 bt_a
[1] = bt_alarge
;
1223 Two_Product(bdxtail
, cdy
, bdxt_cdy1
, bdxt_cdy0
);
1224 Two_Product(bdytail
, cdx
, bdyt_cdx1
, bdyt_cdx0
);
1225 Two_Two_Diff(bdxt_cdy1
, bdxt_cdy0
, bdyt_cdx1
, bdyt_cdx0
,
1226 bt_clarge
, bt_c
[2], bt_c
[1], bt_c
[0]);
1227 bt_c
[3] = bt_clarge
;
1229 Two_Product(bdytail
, adx
, bdyt_adx1
, bdyt_adx0
);
1230 Two_Product(bdxtail
, ady
, bdxt_ady1
, bdxt_ady0
);
1231 Two_Two_Diff(bdyt_adx1
, bdyt_adx0
, bdxt_ady1
, bdxt_ady0
,
1232 bt_alarge
, bt_a
[2], bt_a
[1], bt_a
[0]);
1233 bt_a
[3] = bt_alarge
;
1237 if (cdxtail
== 0.0) {
1238 if (cdytail
== 0.0) {
1245 Two_Product(negate
, adx
, ct_alarge
, ct_a
[0]);
1246 ct_a
[1] = ct_alarge
;
1248 Two_Product(cdytail
, bdx
, ct_blarge
, ct_b
[0]);
1249 ct_b
[1] = ct_blarge
;
1253 if (cdytail
== 0.0) {
1254 Two_Product(cdxtail
, ady
, ct_alarge
, ct_a
[0]);
1255 ct_a
[1] = ct_alarge
;
1258 Two_Product(negate
, bdy
, ct_blarge
, ct_b
[0]);
1259 ct_b
[1] = ct_blarge
;
1262 Two_Product(cdxtail
, ady
, cdxt_ady1
, cdxt_ady0
);
1263 Two_Product(cdytail
, adx
, cdyt_adx1
, cdyt_adx0
);
1264 Two_Two_Diff(cdxt_ady1
, cdxt_ady0
, cdyt_adx1
, cdyt_adx0
,
1265 ct_alarge
, ct_a
[2], ct_a
[1], ct_a
[0]);
1266 ct_a
[3] = ct_alarge
;
1268 Two_Product(cdytail
, bdx
, cdyt_bdx1
, cdyt_bdx0
);
1269 Two_Product(cdxtail
, bdy
, cdxt_bdy1
, cdxt_bdy0
);
1270 Two_Two_Diff(cdyt_bdx1
, cdyt_bdx0
, cdxt_bdy1
, cdxt_bdy0
,
1271 ct_blarge
, ct_b
[2], ct_b
[1], ct_b
[0]);
1272 ct_b
[3] = ct_blarge
;
1277 bctlen
= fast_expansion_sum_zeroelim(bt_clen
, bt_c
, ct_blen
, ct_b
, bct
);
1278 wlength
= scale_expansion_zeroelim(bctlen
, bct
, adz
, w
);
1279 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1281 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1283 catlen
= fast_expansion_sum_zeroelim(ct_alen
, ct_a
, at_clen
, at_c
, cat
);
1284 wlength
= scale_expansion_zeroelim(catlen
, cat
, bdz
, w
);
1285 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1287 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1289 abtlen
= fast_expansion_sum_zeroelim(at_blen
, at_b
, bt_alen
, bt_a
, abt
);
1290 wlength
= scale_expansion_zeroelim(abtlen
, abt
, cdz
, w
);
1291 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1293 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1295 if (adztail
!= 0.0) {
1296 vlength
= scale_expansion_zeroelim(4, bc
, adztail
, v
);
1297 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
1299 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1301 if (bdztail
!= 0.0) {
1302 vlength
= scale_expansion_zeroelim(4, ca
, bdztail
, v
);
1303 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
1305 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1307 if (cdztail
!= 0.0) {
1308 vlength
= scale_expansion_zeroelim(4, ab
, cdztail
, v
);
1309 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
1311 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1314 if (adxtail
!= 0.0) {
1315 if (bdytail
!= 0.0) {
1316 Two_Product(adxtail
, bdytail
, adxt_bdyt1
, adxt_bdyt0
);
1317 Two_One_Product(adxt_bdyt1
, adxt_bdyt0
, cdz
, u3
, u
[2], u
[1], u
[0]);
1319 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1321 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1322 if (cdztail
!= 0.0) {
1323 Two_One_Product(adxt_bdyt1
, adxt_bdyt0
, cdztail
, u3
, u
[2], u
[1], u
[0]);
1325 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1327 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1330 if (cdytail
!= 0.0) {
1332 Two_Product(negate
, cdytail
, adxt_cdyt1
, adxt_cdyt0
);
1333 Two_One_Product(adxt_cdyt1
, adxt_cdyt0
, bdz
, u3
, u
[2], u
[1], u
[0]);
1335 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1337 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1338 if (bdztail
!= 0.0) {
1339 Two_One_Product(adxt_cdyt1
, adxt_cdyt0
, bdztail
, u3
, u
[2], u
[1], u
[0]);
1341 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1343 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1347 if (bdxtail
!= 0.0) {
1348 if (cdytail
!= 0.0) {
1349 Two_Product(bdxtail
, cdytail
, bdxt_cdyt1
, bdxt_cdyt0
);
1350 Two_One_Product(bdxt_cdyt1
, bdxt_cdyt0
, adz
, u3
, u
[2], u
[1], u
[0]);
1352 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1354 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1355 if (adztail
!= 0.0) {
1356 Two_One_Product(bdxt_cdyt1
, bdxt_cdyt0
, adztail
, u3
, u
[2], u
[1], u
[0]);
1358 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1360 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1363 if (adytail
!= 0.0) {
1365 Two_Product(negate
, adytail
, bdxt_adyt1
, bdxt_adyt0
);
1366 Two_One_Product(bdxt_adyt1
, bdxt_adyt0
, cdz
, u3
, u
[2], u
[1], u
[0]);
1368 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1370 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1371 if (cdztail
!= 0.0) {
1372 Two_One_Product(bdxt_adyt1
, bdxt_adyt0
, cdztail
, u3
, u
[2], u
[1], u
[0]);
1374 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1376 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1380 if (cdxtail
!= 0.0) {
1381 if (adytail
!= 0.0) {
1382 Two_Product(cdxtail
, adytail
, cdxt_adyt1
, cdxt_adyt0
);
1383 Two_One_Product(cdxt_adyt1
, cdxt_adyt0
, bdz
, u3
, u
[2], u
[1], u
[0]);
1385 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1387 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1388 if (bdztail
!= 0.0) {
1389 Two_One_Product(cdxt_adyt1
, cdxt_adyt0
, bdztail
, u3
, u
[2], u
[1], u
[0]);
1391 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1393 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1396 if (bdytail
!= 0.0) {
1398 Two_Product(negate
, bdytail
, cdxt_bdyt1
, cdxt_bdyt0
);
1399 Two_One_Product(cdxt_bdyt1
, cdxt_bdyt0
, adz
, u3
, u
[2], u
[1], u
[0]);
1401 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1403 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1404 if (adztail
!= 0.0) {
1405 Two_One_Product(cdxt_bdyt1
, cdxt_bdyt0
, adztail
, u3
, u
[2], u
[1], u
[0]);
1407 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
1409 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1414 if (adztail
!= 0.0) {
1415 wlength
= scale_expansion_zeroelim(bctlen
, bct
, adztail
, w
);
1416 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1418 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1420 if (bdztail
!= 0.0) {
1421 wlength
= scale_expansion_zeroelim(catlen
, cat
, bdztail
, w
);
1422 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1424 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1426 if (cdztail
!= 0.0) {
1427 wlength
= scale_expansion_zeroelim(abtlen
, abt
, cdztail
, w
);
1428 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
1430 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1433 return finnow
[finlength
- 1];
1436 REAL
orient3d(pa
, pb
, pc
, pd
)
1442 REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
, adz
, bdz
, cdz
;
1443 REAL bdxcdy
, cdxbdy
, cdxady
, adxcdy
, adxbdy
, bdxady
;
1445 REAL permanent
, errbound
;
1450 adx
= pa
[0] - pd
[0];
1451 bdx
= pb
[0] - pd
[0];
1452 cdx
= pc
[0] - pd
[0];
1453 ady
= pa
[1] - pd
[1];
1454 bdy
= pb
[1] - pd
[1];
1455 cdy
= pc
[1] - pd
[1];
1456 adz
= pa
[2] - pd
[2];
1457 bdz
= pb
[2] - pd
[2];
1458 cdz
= pc
[2] - pd
[2];
1469 det
= adz
* (bdxcdy
- cdxbdy
)
1470 + bdz
* (cdxady
- adxcdy
)
1471 + cdz
* (adxbdy
- bdxady
);
1473 permanent
= (Absolute(bdxcdy
) + Absolute(cdxbdy
)) * Absolute(adz
)
1474 + (Absolute(cdxady
) + Absolute(adxcdy
)) * Absolute(bdz
)
1475 + (Absolute(adxbdy
) + Absolute(bdxady
)) * Absolute(cdz
);
1476 errbound
= o3derrboundA
* permanent
;
1477 if ((det
> errbound
) || (-det
> errbound
)) {
1482 orient
= orient3dadapt(pa
, pb
, pc
, pd
, permanent
);
1487 /*****************************************************************************/
1489 /* incirclefast() Approximate 2D incircle test. Nonrobust. */
1490 /* incircleexact() Exact 2D incircle test. Robust. */
1491 /* incircleslow() Another exact 2D incircle test. Robust. */
1492 /* incircle() Adaptive exact 2D incircle test. Robust. */
1494 /* Return a positive value if the point pd lies inside the */
1495 /* circle passing through pa, pb, and pc; a negative value if */
1496 /* it lies outside; and zero if the four points are cocircular.*/
1497 /* The points pa, pb, and pc must be in counterclockwise */
1498 /* order, or the sign of the result will be reversed. */
1500 /* Only the first and last routine should be used; the middle two are for */
1503 /* The last three use exact arithmetic to ensure a correct answer. The */
1504 /* result returned is the determinant of a matrix. In incircle() only, */
1505 /* this determinant is computed adaptively, in the sense that exact */
1506 /* arithmetic is used only to the degree it is needed to ensure that the */
1507 /* returned value has the correct sign. Hence, incircle() is usually quite */
1508 /* fast, but will run more slowly when the input points are cocircular or */
1511 /*****************************************************************************/
1513 static REAL
incircleadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
,
1516 INEXACT REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
;
1519 INEXACT REAL bdxcdy1
, cdxbdy1
, cdxady1
, adxcdy1
, adxbdy1
, bdxady1
;
1520 REAL bdxcdy0
, cdxbdy0
, cdxady0
, adxcdy0
, adxbdy0
, bdxady0
;
1521 REAL bc
[4], ca
[4], ab
[4];
1522 INEXACT REAL bc3
, ca3
, ab3
;
1523 REAL axbc
[8], axxbc
[16], aybc
[8], ayybc
[16], adet
[32];
1524 int axbclen
, axxbclen
, aybclen
, ayybclen
, alen
;
1525 REAL bxca
[8], bxxca
[16], byca
[8], byyca
[16], bdet
[32];
1526 int bxcalen
, bxxcalen
, bycalen
, byycalen
, blen
;
1527 REAL cxab
[8], cxxab
[16], cyab
[8], cyyab
[16], cdet
[32];
1528 int cxablen
, cxxablen
, cyablen
, cyyablen
, clen
;
1531 REAL fin1
[1152], fin2
[1152];
1532 REAL
*finnow
, *finother
, *finswap
;
1535 REAL adxtail
, bdxtail
, cdxtail
, adytail
, bdytail
, cdytail
;
1536 INEXACT REAL adxadx1
, adyady1
, bdxbdx1
, bdybdy1
, cdxcdx1
, cdycdy1
;
1537 REAL adxadx0
, adyady0
, bdxbdx0
, bdybdy0
, cdxcdx0
, cdycdy0
;
1538 REAL aa
[4], bb
[4], cc
[4];
1539 INEXACT REAL aa3
, bb3
, cc3
;
1540 INEXACT REAL ti1
, tj1
;
1543 INEXACT REAL u3
, v3
;
1544 REAL temp8
[8], temp16a
[16], temp16b
[16], temp16c
[16];
1545 REAL temp32a
[32], temp32b
[32], temp48
[48], temp64
[64];
1546 int temp8len
, temp16alen
, temp16blen
, temp16clen
;
1547 int temp32alen
, temp32blen
, temp48len
, temp64len
;
1548 REAL axtbb
[8], axtcc
[8], aytbb
[8], aytcc
[8];
1549 int axtbblen
, axtcclen
, aytbblen
, aytcclen
;
1550 REAL bxtaa
[8], bxtcc
[8], bytaa
[8], bytcc
[8];
1551 int bxtaalen
, bxtcclen
, bytaalen
, bytcclen
;
1552 REAL cxtaa
[8], cxtbb
[8], cytaa
[8], cytbb
[8];
1553 int cxtaalen
, cxtbblen
, cytaalen
, cytbblen
;
1554 REAL axtbc
[8], aytbc
[8], bxtca
[8], bytca
[8], cxtab
[8], cytab
[8];
1555 int axtbclen
= 0, aytbclen
= 0;
1556 int bxtcalen
= 0, bytcalen
= 0;
1557 int cxtablen
= 0, cytablen
= 0;
1558 REAL axtbct
[16], aytbct
[16], bxtcat
[16], bytcat
[16], cxtabt
[16], cytabt
[16];
1559 int axtbctlen
, aytbctlen
, bxtcatlen
, bytcatlen
, cxtabtlen
, cytabtlen
;
1560 REAL axtbctt
[8], aytbctt
[8], bxtcatt
[8];
1561 REAL bytcatt
[8], cxtabtt
[8], cytabtt
[8];
1562 int axtbcttlen
, aytbcttlen
, bxtcattlen
, bytcattlen
, cxtabttlen
, cytabttlen
;
1563 REAL abt
[8], bct
[8], cat
[8];
1564 int abtlen
, bctlen
, catlen
;
1565 REAL abtt
[4], bctt
[4], catt
[4];
1566 int abttlen
, bcttlen
, cattlen
;
1567 INEXACT REAL abtt3
, bctt3
, catt3
;
1571 REAL avirt
, bround
, around
;
1574 REAL ahi
, alo
, bhi
, blo
;
1575 REAL err1
, err2
, err3
;
1576 INEXACT REAL _i
, _j
;
1579 adx
= (REAL
) (pa
[0] - pd
[0]);
1580 bdx
= (REAL
) (pb
[0] - pd
[0]);
1581 cdx
= (REAL
) (pc
[0] - pd
[0]);
1582 ady
= (REAL
) (pa
[1] - pd
[1]);
1583 bdy
= (REAL
) (pb
[1] - pd
[1]);
1584 cdy
= (REAL
) (pc
[1] - pd
[1]);
1586 Two_Product(bdx
, cdy
, bdxcdy1
, bdxcdy0
);
1587 Two_Product(cdx
, bdy
, cdxbdy1
, cdxbdy0
);
1588 Two_Two_Diff(bdxcdy1
, bdxcdy0
, cdxbdy1
, cdxbdy0
, bc3
, bc
[2], bc
[1], bc
[0]);
1590 axbclen
= scale_expansion_zeroelim(4, bc
, adx
, axbc
);
1591 axxbclen
= scale_expansion_zeroelim(axbclen
, axbc
, adx
, axxbc
);
1592 aybclen
= scale_expansion_zeroelim(4, bc
, ady
, aybc
);
1593 ayybclen
= scale_expansion_zeroelim(aybclen
, aybc
, ady
, ayybc
);
1594 alen
= fast_expansion_sum_zeroelim(axxbclen
, axxbc
, ayybclen
, ayybc
, adet
);
1596 Two_Product(cdx
, ady
, cdxady1
, cdxady0
);
1597 Two_Product(adx
, cdy
, adxcdy1
, adxcdy0
);
1598 Two_Two_Diff(cdxady1
, cdxady0
, adxcdy1
, adxcdy0
, ca3
, ca
[2], ca
[1], ca
[0]);
1600 bxcalen
= scale_expansion_zeroelim(4, ca
, bdx
, bxca
);
1601 bxxcalen
= scale_expansion_zeroelim(bxcalen
, bxca
, bdx
, bxxca
);
1602 bycalen
= scale_expansion_zeroelim(4, ca
, bdy
, byca
);
1603 byycalen
= scale_expansion_zeroelim(bycalen
, byca
, bdy
, byyca
);
1604 blen
= fast_expansion_sum_zeroelim(bxxcalen
, bxxca
, byycalen
, byyca
, bdet
);
1606 Two_Product(adx
, bdy
, adxbdy1
, adxbdy0
);
1607 Two_Product(bdx
, ady
, bdxady1
, bdxady0
);
1608 Two_Two_Diff(adxbdy1
, adxbdy0
, bdxady1
, bdxady0
, ab3
, ab
[2], ab
[1], ab
[0]);
1610 cxablen
= scale_expansion_zeroelim(4, ab
, cdx
, cxab
);
1611 cxxablen
= scale_expansion_zeroelim(cxablen
, cxab
, cdx
, cxxab
);
1612 cyablen
= scale_expansion_zeroelim(4, ab
, cdy
, cyab
);
1613 cyyablen
= scale_expansion_zeroelim(cyablen
, cyab
, cdy
, cyyab
);
1614 clen
= fast_expansion_sum_zeroelim(cxxablen
, cxxab
, cyyablen
, cyyab
, cdet
);
1616 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
1617 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, fin1
);
1619 det
= estimate(finlength
, fin1
);
1620 errbound
= iccerrboundB
* permanent
;
1621 if ((det
>= errbound
) || (-det
>= errbound
)) {
1625 Two_Diff_Tail(pa
[0], pd
[0], adx
, adxtail
);
1626 Two_Diff_Tail(pa
[1], pd
[1], ady
, adytail
);
1627 Two_Diff_Tail(pb
[0], pd
[0], bdx
, bdxtail
);
1628 Two_Diff_Tail(pb
[1], pd
[1], bdy
, bdytail
);
1629 Two_Diff_Tail(pc
[0], pd
[0], cdx
, cdxtail
);
1630 Two_Diff_Tail(pc
[1], pd
[1], cdy
, cdytail
);
1631 if ((adxtail
== 0.0) && (bdxtail
== 0.0) && (cdxtail
== 0.0)
1632 && (adytail
== 0.0) && (bdytail
== 0.0) && (cdytail
== 0.0)) {
1636 errbound
= iccerrboundC
* permanent
+ resulterrbound
* Absolute(det
);
1637 det
+= ((adx
* adx
+ ady
* ady
) * ((bdx
* cdytail
+ cdy
* bdxtail
)
1638 - (bdy
* cdxtail
+ cdx
* bdytail
))
1639 + 2.0 * (adx
* adxtail
+ ady
* adytail
) * (bdx
* cdy
- bdy
* cdx
))
1640 + ((bdx
* bdx
+ bdy
* bdy
) * ((cdx
* adytail
+ ady
* cdxtail
)
1641 - (cdy
* adxtail
+ adx
* cdytail
))
1642 + 2.0 * (bdx
* bdxtail
+ bdy
* bdytail
) * (cdx
* ady
- cdy
* adx
))
1643 + ((cdx
* cdx
+ cdy
* cdy
) * ((adx
* bdytail
+ bdy
* adxtail
)
1644 - (ady
* bdxtail
+ bdx
* adytail
))
1645 + 2.0 * (cdx
* cdxtail
+ cdy
* cdytail
) * (adx
* bdy
- ady
* bdx
));
1646 if ((det
>= errbound
) || (-det
>= errbound
)) {
1653 if ((bdxtail
!= 0.0) || (bdytail
!= 0.0)
1654 || (cdxtail
!= 0.0) || (cdytail
!= 0.0)) {
1655 Square(adx
, adxadx1
, adxadx0
);
1656 Square(ady
, adyady1
, adyady0
);
1657 Two_Two_Sum(adxadx1
, adxadx0
, adyady1
, adyady0
, aa3
, aa
[2], aa
[1], aa
[0]);
1660 if ((cdxtail
!= 0.0) || (cdytail
!= 0.0)
1661 || (adxtail
!= 0.0) || (adytail
!= 0.0)) {
1662 Square(bdx
, bdxbdx1
, bdxbdx0
);
1663 Square(bdy
, bdybdy1
, bdybdy0
);
1664 Two_Two_Sum(bdxbdx1
, bdxbdx0
, bdybdy1
, bdybdy0
, bb3
, bb
[2], bb
[1], bb
[0]);
1667 if ((adxtail
!= 0.0) || (adytail
!= 0.0)
1668 || (bdxtail
!= 0.0) || (bdytail
!= 0.0)) {
1669 Square(cdx
, cdxcdx1
, cdxcdx0
);
1670 Square(cdy
, cdycdy1
, cdycdy0
);
1671 Two_Two_Sum(cdxcdx1
, cdxcdx0
, cdycdy1
, cdycdy0
, cc3
, cc
[2], cc
[1], cc
[0]);
1675 if (adxtail
!= 0.0) {
1676 axtbclen
= scale_expansion_zeroelim(4, bc
, adxtail
, axtbc
);
1677 temp16alen
= scale_expansion_zeroelim(axtbclen
, axtbc
, 2.0 * adx
,
1680 axtcclen
= scale_expansion_zeroelim(4, cc
, adxtail
, axtcc
);
1681 temp16blen
= scale_expansion_zeroelim(axtcclen
, axtcc
, bdy
, temp16b
);
1683 axtbblen
= scale_expansion_zeroelim(4, bb
, adxtail
, axtbb
);
1684 temp16clen
= scale_expansion_zeroelim(axtbblen
, axtbb
, -cdy
, temp16c
);
1686 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1687 temp16blen
, temp16b
, temp32a
);
1688 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1689 temp32alen
, temp32a
, temp48
);
1690 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1692 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1694 if (adytail
!= 0.0) {
1695 aytbclen
= scale_expansion_zeroelim(4, bc
, adytail
, aytbc
);
1696 temp16alen
= scale_expansion_zeroelim(aytbclen
, aytbc
, 2.0 * ady
,
1699 aytbblen
= scale_expansion_zeroelim(4, bb
, adytail
, aytbb
);
1700 temp16blen
= scale_expansion_zeroelim(aytbblen
, aytbb
, cdx
, temp16b
);
1702 aytcclen
= scale_expansion_zeroelim(4, cc
, adytail
, aytcc
);
1703 temp16clen
= scale_expansion_zeroelim(aytcclen
, aytcc
, -bdx
, temp16c
);
1705 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1706 temp16blen
, temp16b
, temp32a
);
1707 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1708 temp32alen
, temp32a
, temp48
);
1709 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1711 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1713 if (bdxtail
!= 0.0) {
1714 bxtcalen
= scale_expansion_zeroelim(4, ca
, bdxtail
, bxtca
);
1715 temp16alen
= scale_expansion_zeroelim(bxtcalen
, bxtca
, 2.0 * bdx
,
1718 bxtaalen
= scale_expansion_zeroelim(4, aa
, bdxtail
, bxtaa
);
1719 temp16blen
= scale_expansion_zeroelim(bxtaalen
, bxtaa
, cdy
, temp16b
);
1721 bxtcclen
= scale_expansion_zeroelim(4, cc
, bdxtail
, bxtcc
);
1722 temp16clen
= scale_expansion_zeroelim(bxtcclen
, bxtcc
, -ady
, temp16c
);
1724 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1725 temp16blen
, temp16b
, temp32a
);
1726 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1727 temp32alen
, temp32a
, temp48
);
1728 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1730 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1732 if (bdytail
!= 0.0) {
1733 bytcalen
= scale_expansion_zeroelim(4, ca
, bdytail
, bytca
);
1734 temp16alen
= scale_expansion_zeroelim(bytcalen
, bytca
, 2.0 * bdy
,
1737 bytcclen
= scale_expansion_zeroelim(4, cc
, bdytail
, bytcc
);
1738 temp16blen
= scale_expansion_zeroelim(bytcclen
, bytcc
, adx
, temp16b
);
1740 bytaalen
= scale_expansion_zeroelim(4, aa
, bdytail
, bytaa
);
1741 temp16clen
= scale_expansion_zeroelim(bytaalen
, bytaa
, -cdx
, temp16c
);
1743 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1744 temp16blen
, temp16b
, temp32a
);
1745 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1746 temp32alen
, temp32a
, temp48
);
1747 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1749 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1751 if (cdxtail
!= 0.0) {
1752 cxtablen
= scale_expansion_zeroelim(4, ab
, cdxtail
, cxtab
);
1753 temp16alen
= scale_expansion_zeroelim(cxtablen
, cxtab
, 2.0 * cdx
,
1756 cxtbblen
= scale_expansion_zeroelim(4, bb
, cdxtail
, cxtbb
);
1757 temp16blen
= scale_expansion_zeroelim(cxtbblen
, cxtbb
, ady
, temp16b
);
1759 cxtaalen
= scale_expansion_zeroelim(4, aa
, cdxtail
, cxtaa
);
1760 temp16clen
= scale_expansion_zeroelim(cxtaalen
, cxtaa
, -bdy
, temp16c
);
1762 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1763 temp16blen
, temp16b
, temp32a
);
1764 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1765 temp32alen
, temp32a
, temp48
);
1766 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1768 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1770 if (cdytail
!= 0.0) {
1771 cytablen
= scale_expansion_zeroelim(4, ab
, cdytail
, cytab
);
1772 temp16alen
= scale_expansion_zeroelim(cytablen
, cytab
, 2.0 * cdy
,
1775 cytaalen
= scale_expansion_zeroelim(4, aa
, cdytail
, cytaa
);
1776 temp16blen
= scale_expansion_zeroelim(cytaalen
, cytaa
, bdx
, temp16b
);
1778 cytbblen
= scale_expansion_zeroelim(4, bb
, cdytail
, cytbb
);
1779 temp16clen
= scale_expansion_zeroelim(cytbblen
, cytbb
, -adx
, temp16c
);
1781 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1782 temp16blen
, temp16b
, temp32a
);
1783 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
1784 temp32alen
, temp32a
, temp48
);
1785 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1787 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1790 if ((adxtail
!= 0.0) || (adytail
!= 0.0)) {
1791 if ((bdxtail
!= 0.0) || (bdytail
!= 0.0)
1792 || (cdxtail
!= 0.0) || (cdytail
!= 0.0)) {
1793 Two_Product(bdxtail
, cdy
, ti1
, ti0
);
1794 Two_Product(bdx
, cdytail
, tj1
, tj0
);
1795 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
1798 Two_Product(cdxtail
, negate
, ti1
, ti0
);
1800 Two_Product(cdx
, negate
, tj1
, tj0
);
1801 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
1803 bctlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, bct
);
1805 Two_Product(bdxtail
, cdytail
, ti1
, ti0
);
1806 Two_Product(cdxtail
, bdytail
, tj1
, tj0
);
1807 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, bctt3
, bctt
[2], bctt
[1], bctt
[0]);
1817 if (adxtail
!= 0.0) {
1818 temp16alen
= scale_expansion_zeroelim(axtbclen
, axtbc
, adxtail
, temp16a
);
1819 axtbctlen
= scale_expansion_zeroelim(bctlen
, bct
, adxtail
, axtbct
);
1820 temp32alen
= scale_expansion_zeroelim(axtbctlen
, axtbct
, 2.0 * adx
,
1822 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1823 temp32alen
, temp32a
, temp48
);
1824 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1826 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1827 if (bdytail
!= 0.0) {
1828 temp8len
= scale_expansion_zeroelim(4, cc
, adxtail
, temp8
);
1829 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, bdytail
,
1831 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
1833 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1835 if (cdytail
!= 0.0) {
1836 temp8len
= scale_expansion_zeroelim(4, bb
, -adxtail
, temp8
);
1837 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, cdytail
,
1839 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
1841 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1844 temp32alen
= scale_expansion_zeroelim(axtbctlen
, axtbct
, adxtail
,
1846 axtbcttlen
= scale_expansion_zeroelim(bcttlen
, bctt
, adxtail
, axtbctt
);
1847 temp16alen
= scale_expansion_zeroelim(axtbcttlen
, axtbctt
, 2.0 * adx
,
1849 temp16blen
= scale_expansion_zeroelim(axtbcttlen
, axtbctt
, adxtail
,
1851 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1852 temp16blen
, temp16b
, temp32b
);
1853 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
1854 temp32blen
, temp32b
, temp64
);
1855 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
1857 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1859 if (adytail
!= 0.0) {
1860 temp16alen
= scale_expansion_zeroelim(aytbclen
, aytbc
, adytail
, temp16a
);
1861 aytbctlen
= scale_expansion_zeroelim(bctlen
, bct
, adytail
, aytbct
);
1862 temp32alen
= scale_expansion_zeroelim(aytbctlen
, aytbct
, 2.0 * ady
,
1864 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1865 temp32alen
, temp32a
, temp48
);
1866 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1868 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1871 temp32alen
= scale_expansion_zeroelim(aytbctlen
, aytbct
, adytail
,
1873 aytbcttlen
= scale_expansion_zeroelim(bcttlen
, bctt
, adytail
, aytbctt
);
1874 temp16alen
= scale_expansion_zeroelim(aytbcttlen
, aytbctt
, 2.0 * ady
,
1876 temp16blen
= scale_expansion_zeroelim(aytbcttlen
, aytbctt
, adytail
,
1878 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1879 temp16blen
, temp16b
, temp32b
);
1880 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
1881 temp32blen
, temp32b
, temp64
);
1882 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
1884 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1887 if ((bdxtail
!= 0.0) || (bdytail
!= 0.0)) {
1888 if ((cdxtail
!= 0.0) || (cdytail
!= 0.0)
1889 || (adxtail
!= 0.0) || (adytail
!= 0.0)) {
1890 Two_Product(cdxtail
, ady
, ti1
, ti0
);
1891 Two_Product(cdx
, adytail
, tj1
, tj0
);
1892 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
1895 Two_Product(adxtail
, negate
, ti1
, ti0
);
1897 Two_Product(adx
, negate
, tj1
, tj0
);
1898 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
1900 catlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, cat
);
1902 Two_Product(cdxtail
, adytail
, ti1
, ti0
);
1903 Two_Product(adxtail
, cdytail
, tj1
, tj0
);
1904 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, catt3
, catt
[2], catt
[1], catt
[0]);
1914 if (bdxtail
!= 0.0) {
1915 temp16alen
= scale_expansion_zeroelim(bxtcalen
, bxtca
, bdxtail
, temp16a
);
1916 bxtcatlen
= scale_expansion_zeroelim(catlen
, cat
, bdxtail
, bxtcat
);
1917 temp32alen
= scale_expansion_zeroelim(bxtcatlen
, bxtcat
, 2.0 * bdx
,
1919 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1920 temp32alen
, temp32a
, temp48
);
1921 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1923 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1924 if (cdytail
!= 0.0) {
1925 temp8len
= scale_expansion_zeroelim(4, aa
, bdxtail
, temp8
);
1926 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, cdytail
,
1928 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
1930 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1932 if (adytail
!= 0.0) {
1933 temp8len
= scale_expansion_zeroelim(4, cc
, -bdxtail
, temp8
);
1934 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, adytail
,
1936 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
1938 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1941 temp32alen
= scale_expansion_zeroelim(bxtcatlen
, bxtcat
, bdxtail
,
1943 bxtcattlen
= scale_expansion_zeroelim(cattlen
, catt
, bdxtail
, bxtcatt
);
1944 temp16alen
= scale_expansion_zeroelim(bxtcattlen
, bxtcatt
, 2.0 * bdx
,
1946 temp16blen
= scale_expansion_zeroelim(bxtcattlen
, bxtcatt
, bdxtail
,
1948 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1949 temp16blen
, temp16b
, temp32b
);
1950 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
1951 temp32blen
, temp32b
, temp64
);
1952 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
1954 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1956 if (bdytail
!= 0.0) {
1957 temp16alen
= scale_expansion_zeroelim(bytcalen
, bytca
, bdytail
, temp16a
);
1958 bytcatlen
= scale_expansion_zeroelim(catlen
, cat
, bdytail
, bytcat
);
1959 temp32alen
= scale_expansion_zeroelim(bytcatlen
, bytcat
, 2.0 * bdy
,
1961 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1962 temp32alen
, temp32a
, temp48
);
1963 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
1965 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1968 temp32alen
= scale_expansion_zeroelim(bytcatlen
, bytcat
, bdytail
,
1970 bytcattlen
= scale_expansion_zeroelim(cattlen
, catt
, bdytail
, bytcatt
);
1971 temp16alen
= scale_expansion_zeroelim(bytcattlen
, bytcatt
, 2.0 * bdy
,
1973 temp16blen
= scale_expansion_zeroelim(bytcattlen
, bytcatt
, bdytail
,
1975 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
1976 temp16blen
, temp16b
, temp32b
);
1977 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
1978 temp32blen
, temp32b
, temp64
);
1979 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
1981 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
1984 if ((cdxtail
!= 0.0) || (cdytail
!= 0.0)) {
1985 if ((adxtail
!= 0.0) || (adytail
!= 0.0)
1986 || (bdxtail
!= 0.0) || (bdytail
!= 0.0)) {
1987 Two_Product(adxtail
, bdy
, ti1
, ti0
);
1988 Two_Product(adx
, bdytail
, tj1
, tj0
);
1989 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
1992 Two_Product(bdxtail
, negate
, ti1
, ti0
);
1994 Two_Product(bdx
, negate
, tj1
, tj0
);
1995 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
1997 abtlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, abt
);
1999 Two_Product(adxtail
, bdytail
, ti1
, ti0
);
2000 Two_Product(bdxtail
, adytail
, tj1
, tj0
);
2001 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, abtt3
, abtt
[2], abtt
[1], abtt
[0]);
2011 if (cdxtail
!= 0.0) {
2012 temp16alen
= scale_expansion_zeroelim(cxtablen
, cxtab
, cdxtail
, temp16a
);
2013 cxtabtlen
= scale_expansion_zeroelim(abtlen
, abt
, cdxtail
, cxtabt
);
2014 temp32alen
= scale_expansion_zeroelim(cxtabtlen
, cxtabt
, 2.0 * cdx
,
2016 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
2017 temp32alen
, temp32a
, temp48
);
2018 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
2020 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2021 if (adytail
!= 0.0) {
2022 temp8len
= scale_expansion_zeroelim(4, bb
, cdxtail
, temp8
);
2023 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, adytail
,
2025 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
2027 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2029 if (bdytail
!= 0.0) {
2030 temp8len
= scale_expansion_zeroelim(4, aa
, -cdxtail
, temp8
);
2031 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, bdytail
,
2033 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
2035 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2038 temp32alen
= scale_expansion_zeroelim(cxtabtlen
, cxtabt
, cdxtail
,
2040 cxtabttlen
= scale_expansion_zeroelim(abttlen
, abtt
, cdxtail
, cxtabtt
);
2041 temp16alen
= scale_expansion_zeroelim(cxtabttlen
, cxtabtt
, 2.0 * cdx
,
2043 temp16blen
= scale_expansion_zeroelim(cxtabttlen
, cxtabtt
, cdxtail
,
2045 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
2046 temp16blen
, temp16b
, temp32b
);
2047 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
2048 temp32blen
, temp32b
, temp64
);
2049 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
2051 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2053 if (cdytail
!= 0.0) {
2054 temp16alen
= scale_expansion_zeroelim(cytablen
, cytab
, cdytail
, temp16a
);
2055 cytabtlen
= scale_expansion_zeroelim(abtlen
, abt
, cdytail
, cytabt
);
2056 temp32alen
= scale_expansion_zeroelim(cytabtlen
, cytabt
, 2.0 * cdy
,
2058 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
2059 temp32alen
, temp32a
, temp48
);
2060 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
2062 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2065 temp32alen
= scale_expansion_zeroelim(cytabtlen
, cytabt
, cdytail
,
2067 cytabttlen
= scale_expansion_zeroelim(abttlen
, abtt
, cdytail
, cytabtt
);
2068 temp16alen
= scale_expansion_zeroelim(cytabttlen
, cytabtt
, 2.0 * cdy
,
2070 temp16blen
= scale_expansion_zeroelim(cytabttlen
, cytabtt
, cdytail
,
2072 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
2073 temp16blen
, temp16b
, temp32b
);
2074 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
2075 temp32blen
, temp32b
, temp64
);
2076 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
2078 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2082 return finnow
[finlength
- 1];
2085 REAL
incircle(pa
, pb
, pc
, pd
)
2091 REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
;
2092 REAL bdxcdy
, cdxbdy
, cdxady
, adxcdy
, adxbdy
, bdxady
;
2093 REAL alift
, blift
, clift
;
2095 REAL permanent
, errbound
;
2100 adx
= pa
[0] - pd
[0];
2101 bdx
= pb
[0] - pd
[0];
2102 cdx
= pc
[0] - pd
[0];
2103 ady
= pa
[1] - pd
[1];
2104 bdy
= pb
[1] - pd
[1];
2105 cdy
= pc
[1] - pd
[1];
2109 alift
= adx
* adx
+ ady
* ady
;
2113 blift
= bdx
* bdx
+ bdy
* bdy
;
2117 clift
= cdx
* cdx
+ cdy
* cdy
;
2119 det
= alift
* (bdxcdy
- cdxbdy
)
2120 + blift
* (cdxady
- adxcdy
)
2121 + clift
* (adxbdy
- bdxady
);
2123 permanent
= (Absolute(bdxcdy
) + Absolute(cdxbdy
)) * alift
2124 + (Absolute(cdxady
) + Absolute(adxcdy
)) * blift
2125 + (Absolute(adxbdy
) + Absolute(bdxady
)) * clift
;
2126 errbound
= iccerrboundA
* permanent
;
2127 if ((det
> errbound
) || (-det
> errbound
)) {
2132 inc
= incircleadapt(pa
, pb
, pc
, pd
, permanent
);
2137 /*****************************************************************************/
2139 /* inspherefast() Approximate 3D insphere test. Nonrobust. */
2140 /* insphereexact() Exact 3D insphere test. Robust. */
2141 /* insphereslow() Another exact 3D insphere test. Robust. */
2142 /* insphere() Adaptive exact 3D insphere test. Robust. */
2144 /* Return a positive value if the point pe lies inside the */
2145 /* sphere passing through pa, pb, pc, and pd; a negative value */
2146 /* if it lies outside; and zero if the five points are */
2147 /* cospherical. The points pa, pb, pc, and pd must be ordered */
2148 /* so that they have a positive orientation (as defined by */
2149 /* orient3d()), or the sign of the result will be reversed. */
2151 /* Only the first and last routine should be used; the middle two are for */
2154 /* The last three use exact arithmetic to ensure a correct answer. The */
2155 /* result returned is the determinant of a matrix. In insphere() only, */
2156 /* this determinant is computed adaptively, in the sense that exact */
2157 /* arithmetic is used only to the degree it is needed to ensure that the */
2158 /* returned value has the correct sign. Hence, insphere() is usually quite */
2159 /* fast, but will run more slowly when the input points are cospherical or */
2162 /*****************************************************************************/
2164 static REAL
insphereexact(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
)
2166 INEXACT REAL axby1
, bxcy1
, cxdy1
, dxey1
, exay1
;
2167 INEXACT REAL bxay1
, cxby1
, dxcy1
, exdy1
, axey1
;
2168 INEXACT REAL axcy1
, bxdy1
, cxey1
, dxay1
, exby1
;
2169 INEXACT REAL cxay1
, dxby1
, excy1
, axdy1
, bxey1
;
2170 REAL axby0
, bxcy0
, cxdy0
, dxey0
, exay0
;
2171 REAL bxay0
, cxby0
, dxcy0
, exdy0
, axey0
;
2172 REAL axcy0
, bxdy0
, cxey0
, dxay0
, exby0
;
2173 REAL cxay0
, dxby0
, excy0
, axdy0
, bxey0
;
2174 REAL ab
[4], bc
[4], cd
[4], de
[4], ea
[4];
2175 REAL ac
[4], bd
[4], ce
[4], da
[4], eb
[4];
2176 REAL temp8a
[8], temp8b
[8], temp16
[16];
2177 int temp8alen
, temp8blen
, temp16len
;
2178 REAL abc
[24], bcd
[24], cde
[24], dea
[24], eab
[24];
2179 REAL abd
[24], bce
[24], cda
[24], deb
[24], eac
[24];
2180 int abclen
, bcdlen
, cdelen
, dealen
, eablen
;
2181 int abdlen
, bcelen
, cdalen
, deblen
, eaclen
;
2182 REAL temp48a
[48], temp48b
[48];
2183 int temp48alen
, temp48blen
;
2184 REAL abcd
[96], bcde
[96], cdea
[96], deab
[96], eabc
[96];
2185 int abcdlen
, bcdelen
, cdealen
, deablen
, eabclen
;
2187 REAL det384x
[384], det384y
[384], det384z
[384];
2188 int xlen
, ylen
, zlen
;
2191 REAL adet
[1152], bdet
[1152], cdet
[1152], ddet
[1152], edet
[1152];
2192 int alen
, blen
, clen
, dlen
, elen
;
2193 REAL abdet
[2304], cddet
[2304], cdedet
[3456];
2200 REAL avirt
, bround
, around
;
2203 REAL ahi
, alo
, bhi
, blo
;
2204 REAL err1
, err2
, err3
;
2205 INEXACT REAL _i
, _j
;
2208 Two_Product(pa
[0], pb
[1], axby1
, axby0
);
2209 Two_Product(pb
[0], pa
[1], bxay1
, bxay0
);
2210 Two_Two_Diff(axby1
, axby0
, bxay1
, bxay0
, ab
[3], ab
[2], ab
[1], ab
[0]);
2212 Two_Product(pb
[0], pc
[1], bxcy1
, bxcy0
);
2213 Two_Product(pc
[0], pb
[1], cxby1
, cxby0
);
2214 Two_Two_Diff(bxcy1
, bxcy0
, cxby1
, cxby0
, bc
[3], bc
[2], bc
[1], bc
[0]);
2216 Two_Product(pc
[0], pd
[1], cxdy1
, cxdy0
);
2217 Two_Product(pd
[0], pc
[1], dxcy1
, dxcy0
);
2218 Two_Two_Diff(cxdy1
, cxdy0
, dxcy1
, dxcy0
, cd
[3], cd
[2], cd
[1], cd
[0]);
2220 Two_Product(pd
[0], pe
[1], dxey1
, dxey0
);
2221 Two_Product(pe
[0], pd
[1], exdy1
, exdy0
);
2222 Two_Two_Diff(dxey1
, dxey0
, exdy1
, exdy0
, de
[3], de
[2], de
[1], de
[0]);
2224 Two_Product(pe
[0], pa
[1], exay1
, exay0
);
2225 Two_Product(pa
[0], pe
[1], axey1
, axey0
);
2226 Two_Two_Diff(exay1
, exay0
, axey1
, axey0
, ea
[3], ea
[2], ea
[1], ea
[0]);
2228 Two_Product(pa
[0], pc
[1], axcy1
, axcy0
);
2229 Two_Product(pc
[0], pa
[1], cxay1
, cxay0
);
2230 Two_Two_Diff(axcy1
, axcy0
, cxay1
, cxay0
, ac
[3], ac
[2], ac
[1], ac
[0]);
2232 Two_Product(pb
[0], pd
[1], bxdy1
, bxdy0
);
2233 Two_Product(pd
[0], pb
[1], dxby1
, dxby0
);
2234 Two_Two_Diff(bxdy1
, bxdy0
, dxby1
, dxby0
, bd
[3], bd
[2], bd
[1], bd
[0]);
2236 Two_Product(pc
[0], pe
[1], cxey1
, cxey0
);
2237 Two_Product(pe
[0], pc
[1], excy1
, excy0
);
2238 Two_Two_Diff(cxey1
, cxey0
, excy1
, excy0
, ce
[3], ce
[2], ce
[1], ce
[0]);
2240 Two_Product(pd
[0], pa
[1], dxay1
, dxay0
);
2241 Two_Product(pa
[0], pd
[1], axdy1
, axdy0
);
2242 Two_Two_Diff(dxay1
, dxay0
, axdy1
, axdy0
, da
[3], da
[2], da
[1], da
[0]);
2244 Two_Product(pe
[0], pb
[1], exby1
, exby0
);
2245 Two_Product(pb
[0], pe
[1], bxey1
, bxey0
);
2246 Two_Two_Diff(exby1
, exby0
, bxey1
, bxey0
, eb
[3], eb
[2], eb
[1], eb
[0]);
2248 temp8alen
= scale_expansion_zeroelim(4, bc
, pa
[2], temp8a
);
2249 temp8blen
= scale_expansion_zeroelim(4, ac
, -pb
[2], temp8b
);
2250 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2252 temp8alen
= scale_expansion_zeroelim(4, ab
, pc
[2], temp8a
);
2253 abclen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2256 temp8alen
= scale_expansion_zeroelim(4, cd
, pb
[2], temp8a
);
2257 temp8blen
= scale_expansion_zeroelim(4, bd
, -pc
[2], temp8b
);
2258 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2260 temp8alen
= scale_expansion_zeroelim(4, bc
, pd
[2], temp8a
);
2261 bcdlen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2264 temp8alen
= scale_expansion_zeroelim(4, de
, pc
[2], temp8a
);
2265 temp8blen
= scale_expansion_zeroelim(4, ce
, -pd
[2], temp8b
);
2266 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2268 temp8alen
= scale_expansion_zeroelim(4, cd
, pe
[2], temp8a
);
2269 cdelen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2272 temp8alen
= scale_expansion_zeroelim(4, ea
, pd
[2], temp8a
);
2273 temp8blen
= scale_expansion_zeroelim(4, da
, -pe
[2], temp8b
);
2274 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2276 temp8alen
= scale_expansion_zeroelim(4, de
, pa
[2], temp8a
);
2277 dealen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2280 temp8alen
= scale_expansion_zeroelim(4, ab
, pe
[2], temp8a
);
2281 temp8blen
= scale_expansion_zeroelim(4, eb
, -pa
[2], temp8b
);
2282 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2284 temp8alen
= scale_expansion_zeroelim(4, ea
, pb
[2], temp8a
);
2285 eablen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2288 temp8alen
= scale_expansion_zeroelim(4, bd
, pa
[2], temp8a
);
2289 temp8blen
= scale_expansion_zeroelim(4, da
, pb
[2], temp8b
);
2290 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2292 temp8alen
= scale_expansion_zeroelim(4, ab
, pd
[2], temp8a
);
2293 abdlen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2296 temp8alen
= scale_expansion_zeroelim(4, ce
, pb
[2], temp8a
);
2297 temp8blen
= scale_expansion_zeroelim(4, eb
, pc
[2], temp8b
);
2298 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2300 temp8alen
= scale_expansion_zeroelim(4, bc
, pe
[2], temp8a
);
2301 bcelen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2304 temp8alen
= scale_expansion_zeroelim(4, da
, pc
[2], temp8a
);
2305 temp8blen
= scale_expansion_zeroelim(4, ac
, pd
[2], temp8b
);
2306 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2308 temp8alen
= scale_expansion_zeroelim(4, cd
, pa
[2], temp8a
);
2309 cdalen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2312 temp8alen
= scale_expansion_zeroelim(4, eb
, pd
[2], temp8a
);
2313 temp8blen
= scale_expansion_zeroelim(4, bd
, pe
[2], temp8b
);
2314 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2316 temp8alen
= scale_expansion_zeroelim(4, de
, pb
[2], temp8a
);
2317 deblen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2320 temp8alen
= scale_expansion_zeroelim(4, ac
, pe
[2], temp8a
);
2321 temp8blen
= scale_expansion_zeroelim(4, ce
, pa
[2], temp8b
);
2322 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
2324 temp8alen
= scale_expansion_zeroelim(4, ea
, pc
[2], temp8a
);
2325 eaclen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
2328 temp48alen
= fast_expansion_sum_zeroelim(cdelen
, cde
, bcelen
, bce
, temp48a
);
2329 temp48blen
= fast_expansion_sum_zeroelim(deblen
, deb
, bcdlen
, bcd
, temp48b
);
2330 for (i
= 0; i
< temp48blen
; i
++) {
2331 temp48b
[i
] = -temp48b
[i
];
2333 bcdelen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
2334 temp48blen
, temp48b
, bcde
);
2335 xlen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[0], temp192
);
2336 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pa
[0], det384x
);
2337 ylen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[1], temp192
);
2338 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pa
[1], det384y
);
2339 zlen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[2], temp192
);
2340 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pa
[2], det384z
);
2341 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
2342 alen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, adet
);
2344 temp48alen
= fast_expansion_sum_zeroelim(dealen
, dea
, cdalen
, cda
, temp48a
);
2345 temp48blen
= fast_expansion_sum_zeroelim(eaclen
, eac
, cdelen
, cde
, temp48b
);
2346 for (i
= 0; i
< temp48blen
; i
++) {
2347 temp48b
[i
] = -temp48b
[i
];
2349 cdealen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
2350 temp48blen
, temp48b
, cdea
);
2351 xlen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[0], temp192
);
2352 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pb
[0], det384x
);
2353 ylen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[1], temp192
);
2354 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pb
[1], det384y
);
2355 zlen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[2], temp192
);
2356 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pb
[2], det384z
);
2357 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
2358 blen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, bdet
);
2360 temp48alen
= fast_expansion_sum_zeroelim(eablen
, eab
, deblen
, deb
, temp48a
);
2361 temp48blen
= fast_expansion_sum_zeroelim(abdlen
, abd
, dealen
, dea
, temp48b
);
2362 for (i
= 0; i
< temp48blen
; i
++) {
2363 temp48b
[i
] = -temp48b
[i
];
2365 deablen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
2366 temp48blen
, temp48b
, deab
);
2367 xlen
= scale_expansion_zeroelim(deablen
, deab
, pc
[0], temp192
);
2368 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pc
[0], det384x
);
2369 ylen
= scale_expansion_zeroelim(deablen
, deab
, pc
[1], temp192
);
2370 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pc
[1], det384y
);
2371 zlen
= scale_expansion_zeroelim(deablen
, deab
, pc
[2], temp192
);
2372 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pc
[2], det384z
);
2373 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
2374 clen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, cdet
);
2376 temp48alen
= fast_expansion_sum_zeroelim(abclen
, abc
, eaclen
, eac
, temp48a
);
2377 temp48blen
= fast_expansion_sum_zeroelim(bcelen
, bce
, eablen
, eab
, temp48b
);
2378 for (i
= 0; i
< temp48blen
; i
++) {
2379 temp48b
[i
] = -temp48b
[i
];
2381 eabclen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
2382 temp48blen
, temp48b
, eabc
);
2383 xlen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[0], temp192
);
2384 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pd
[0], det384x
);
2385 ylen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[1], temp192
);
2386 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pd
[1], det384y
);
2387 zlen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[2], temp192
);
2388 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pd
[2], det384z
);
2389 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
2390 dlen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, ddet
);
2392 temp48alen
= fast_expansion_sum_zeroelim(bcdlen
, bcd
, abdlen
, abd
, temp48a
);
2393 temp48blen
= fast_expansion_sum_zeroelim(cdalen
, cda
, abclen
, abc
, temp48b
);
2394 for (i
= 0; i
< temp48blen
; i
++) {
2395 temp48b
[i
] = -temp48b
[i
];
2397 abcdlen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
2398 temp48blen
, temp48b
, abcd
);
2399 xlen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[0], temp192
);
2400 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pe
[0], det384x
);
2401 ylen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[1], temp192
);
2402 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pe
[1], det384y
);
2403 zlen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[2], temp192
);
2404 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pe
[2], det384z
);
2405 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
2406 elen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, edet
);
2408 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2409 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
2410 cdelen
= fast_expansion_sum_zeroelim(cdlen
, cddet
, elen
, edet
, cdedet
);
2411 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdelen
, cdedet
, deter
);
2413 return deter
[deterlen
- 1];
2416 static REAL
insphereadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
,
2419 INEXACT REAL aex
, bex
, cex
, dex
, aey
, bey
, cey
, dey
, aez
, bez
, cez
, dez
;
2422 INEXACT REAL aexbey1
, bexaey1
, bexcey1
, cexbey1
;
2423 INEXACT REAL cexdey1
, dexcey1
, dexaey1
, aexdey1
;
2424 INEXACT REAL aexcey1
, cexaey1
, bexdey1
, dexbey1
;
2425 REAL aexbey0
, bexaey0
, bexcey0
, cexbey0
;
2426 REAL cexdey0
, dexcey0
, dexaey0
, aexdey0
;
2427 REAL aexcey0
, cexaey0
, bexdey0
, dexbey0
;
2428 REAL ab
[4], bc
[4], cd
[4], da
[4], ac
[4], bd
[4];
2429 INEXACT REAL ab3
, bc3
, cd3
, da3
, ac3
, bd3
;
2430 REAL abeps
, bceps
, cdeps
, daeps
, aceps
, bdeps
;
2431 REAL temp8a
[8], temp8b
[8], temp8c
[8], temp16
[16], temp24
[24], temp48
[48];
2432 int temp8alen
, temp8blen
, temp8clen
, temp16len
, temp24len
, temp48len
;
2433 REAL xdet
[96], ydet
[96], zdet
[96], xydet
[192];
2434 int xlen
, ylen
, zlen
, xylen
;
2435 REAL adet
[288], bdet
[288], cdet
[288], ddet
[288];
2436 int alen
, blen
, clen
, dlen
;
2437 REAL abdet
[576], cddet
[576];
2442 REAL aextail
, bextail
, cextail
, dextail
;
2443 REAL aeytail
, beytail
, ceytail
, deytail
;
2444 REAL aeztail
, beztail
, ceztail
, deztail
;
2447 REAL avirt
, bround
, around
;
2450 REAL ahi
, alo
, bhi
, blo
;
2451 REAL err1
, err2
, err3
;
2452 INEXACT REAL _i
, _j
;
2455 aex
= (REAL
) (pa
[0] - pe
[0]);
2456 bex
= (REAL
) (pb
[0] - pe
[0]);
2457 cex
= (REAL
) (pc
[0] - pe
[0]);
2458 dex
= (REAL
) (pd
[0] - pe
[0]);
2459 aey
= (REAL
) (pa
[1] - pe
[1]);
2460 bey
= (REAL
) (pb
[1] - pe
[1]);
2461 cey
= (REAL
) (pc
[1] - pe
[1]);
2462 dey
= (REAL
) (pd
[1] - pe
[1]);
2463 aez
= (REAL
) (pa
[2] - pe
[2]);
2464 bez
= (REAL
) (pb
[2] - pe
[2]);
2465 cez
= (REAL
) (pc
[2] - pe
[2]);
2466 dez
= (REAL
) (pd
[2] - pe
[2]);
2468 Two_Product(aex
, bey
, aexbey1
, aexbey0
);
2469 Two_Product(bex
, aey
, bexaey1
, bexaey0
);
2470 Two_Two_Diff(aexbey1
, aexbey0
, bexaey1
, bexaey0
, ab3
, ab
[2], ab
[1], ab
[0]);
2473 Two_Product(bex
, cey
, bexcey1
, bexcey0
);
2474 Two_Product(cex
, bey
, cexbey1
, cexbey0
);
2475 Two_Two_Diff(bexcey1
, bexcey0
, cexbey1
, cexbey0
, bc3
, bc
[2], bc
[1], bc
[0]);
2478 Two_Product(cex
, dey
, cexdey1
, cexdey0
);
2479 Two_Product(dex
, cey
, dexcey1
, dexcey0
);
2480 Two_Two_Diff(cexdey1
, cexdey0
, dexcey1
, dexcey0
, cd3
, cd
[2], cd
[1], cd
[0]);
2483 Two_Product(dex
, aey
, dexaey1
, dexaey0
);
2484 Two_Product(aex
, dey
, aexdey1
, aexdey0
);
2485 Two_Two_Diff(dexaey1
, dexaey0
, aexdey1
, aexdey0
, da3
, da
[2], da
[1], da
[0]);
2488 Two_Product(aex
, cey
, aexcey1
, aexcey0
);
2489 Two_Product(cex
, aey
, cexaey1
, cexaey0
);
2490 Two_Two_Diff(aexcey1
, aexcey0
, cexaey1
, cexaey0
, ac3
, ac
[2], ac
[1], ac
[0]);
2493 Two_Product(bex
, dey
, bexdey1
, bexdey0
);
2494 Two_Product(dex
, bey
, dexbey1
, dexbey0
);
2495 Two_Two_Diff(bexdey1
, bexdey0
, dexbey1
, dexbey0
, bd3
, bd
[2], bd
[1], bd
[0]);
2498 temp8alen
= scale_expansion_zeroelim(4, cd
, bez
, temp8a
);
2499 temp8blen
= scale_expansion_zeroelim(4, bd
, -cez
, temp8b
);
2500 temp8clen
= scale_expansion_zeroelim(4, bc
, dez
, temp8c
);
2501 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
2502 temp8blen
, temp8b
, temp16
);
2503 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
2504 temp16len
, temp16
, temp24
);
2505 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aex
, temp48
);
2506 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, -aex
, xdet
);
2507 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aey
, temp48
);
2508 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, -aey
, ydet
);
2509 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aez
, temp48
);
2510 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, -aez
, zdet
);
2511 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
2512 alen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, adet
);
2514 temp8alen
= scale_expansion_zeroelim(4, da
, cez
, temp8a
);
2515 temp8blen
= scale_expansion_zeroelim(4, ac
, dez
, temp8b
);
2516 temp8clen
= scale_expansion_zeroelim(4, cd
, aez
, temp8c
);
2517 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
2518 temp8blen
, temp8b
, temp16
);
2519 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
2520 temp16len
, temp16
, temp24
);
2521 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bex
, temp48
);
2522 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, bex
, xdet
);
2523 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bey
, temp48
);
2524 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, bey
, ydet
);
2525 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bez
, temp48
);
2526 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, bez
, zdet
);
2527 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
2528 blen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, bdet
);
2530 temp8alen
= scale_expansion_zeroelim(4, ab
, dez
, temp8a
);
2531 temp8blen
= scale_expansion_zeroelim(4, bd
, aez
, temp8b
);
2532 temp8clen
= scale_expansion_zeroelim(4, da
, bez
, temp8c
);
2533 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
2534 temp8blen
, temp8b
, temp16
);
2535 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
2536 temp16len
, temp16
, temp24
);
2537 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cex
, temp48
);
2538 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, -cex
, xdet
);
2539 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cey
, temp48
);
2540 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, -cey
, ydet
);
2541 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cez
, temp48
);
2542 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, -cez
, zdet
);
2543 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
2544 clen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, cdet
);
2546 temp8alen
= scale_expansion_zeroelim(4, bc
, aez
, temp8a
);
2547 temp8blen
= scale_expansion_zeroelim(4, ac
, -bez
, temp8b
);
2548 temp8clen
= scale_expansion_zeroelim(4, ab
, cez
, temp8c
);
2549 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
2550 temp8blen
, temp8b
, temp16
);
2551 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
2552 temp16len
, temp16
, temp24
);
2553 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dex
, temp48
);
2554 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, dex
, xdet
);
2555 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dey
, temp48
);
2556 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, dey
, ydet
);
2557 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dez
, temp48
);
2558 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, dez
, zdet
);
2559 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
2560 dlen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, ddet
);
2562 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2563 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
2564 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdlen
, cddet
, fin1
);
2566 det
= estimate(finlength
, fin1
);
2567 errbound
= isperrboundB
* permanent
;
2568 if ((det
>= errbound
) || (-det
>= errbound
)) {
2572 Two_Diff_Tail(pa
[0], pe
[0], aex
, aextail
);
2573 Two_Diff_Tail(pa
[1], pe
[1], aey
, aeytail
);
2574 Two_Diff_Tail(pa
[2], pe
[2], aez
, aeztail
);
2575 Two_Diff_Tail(pb
[0], pe
[0], bex
, bextail
);
2576 Two_Diff_Tail(pb
[1], pe
[1], bey
, beytail
);
2577 Two_Diff_Tail(pb
[2], pe
[2], bez
, beztail
);
2578 Two_Diff_Tail(pc
[0], pe
[0], cex
, cextail
);
2579 Two_Diff_Tail(pc
[1], pe
[1], cey
, ceytail
);
2580 Two_Diff_Tail(pc
[2], pe
[2], cez
, ceztail
);
2581 Two_Diff_Tail(pd
[0], pe
[0], dex
, dextail
);
2582 Two_Diff_Tail(pd
[1], pe
[1], dey
, deytail
);
2583 Two_Diff_Tail(pd
[2], pe
[2], dez
, deztail
);
2584 if ((aextail
== 0.0) && (aeytail
== 0.0) && (aeztail
== 0.0)
2585 && (bextail
== 0.0) && (beytail
== 0.0) && (beztail
== 0.0)
2586 && (cextail
== 0.0) && (ceytail
== 0.0) && (ceztail
== 0.0)
2587 && (dextail
== 0.0) && (deytail
== 0.0) && (deztail
== 0.0)) {
2591 errbound
= isperrboundC
* permanent
+ resulterrbound
* Absolute(det
);
2592 abeps
= (aex
* beytail
+ bey
* aextail
)
2593 - (aey
* bextail
+ bex
* aeytail
);
2594 bceps
= (bex
* ceytail
+ cey
* bextail
)
2595 - (bey
* cextail
+ cex
* beytail
);
2596 cdeps
= (cex
* deytail
+ dey
* cextail
)
2597 - (cey
* dextail
+ dex
* ceytail
);
2598 daeps
= (dex
* aeytail
+ aey
* dextail
)
2599 - (dey
* aextail
+ aex
* deytail
);
2600 aceps
= (aex
* ceytail
+ cey
* aextail
)
2601 - (aey
* cextail
+ cex
* aeytail
);
2602 bdeps
= (bex
* deytail
+ dey
* bextail
)
2603 - (bey
* dextail
+ dex
* beytail
);
2604 det
+= (((bex
* bex
+ bey
* bey
+ bez
* bez
)
2605 * ((cez
* daeps
+ dez
* aceps
+ aez
* cdeps
)
2606 + (ceztail
* da3
+ deztail
* ac3
+ aeztail
* cd3
))
2607 + (dex
* dex
+ dey
* dey
+ dez
* dez
)
2608 * ((aez
* bceps
- bez
* aceps
+ cez
* abeps
)
2609 + (aeztail
* bc3
- beztail
* ac3
+ ceztail
* ab3
)))
2610 - ((aex
* aex
+ aey
* aey
+ aez
* aez
)
2611 * ((bez
* cdeps
- cez
* bdeps
+ dez
* bceps
)
2612 + (beztail
* cd3
- ceztail
* bd3
+ deztail
* bc3
))
2613 + (cex
* cex
+ cey
* cey
+ cez
* cez
)
2614 * ((dez
* abeps
+ aez
* bdeps
+ bez
* daeps
)
2615 + (deztail
* ab3
+ aeztail
* bd3
+ beztail
* da3
))))
2616 + 2.0 * (((bex
* bextail
+ bey
* beytail
+ bez
* beztail
)
2617 * (cez
* da3
+ dez
* ac3
+ aez
* cd3
)
2618 + (dex
* dextail
+ dey
* deytail
+ dez
* deztail
)
2619 * (aez
* bc3
- bez
* ac3
+ cez
* ab3
))
2620 - ((aex
* aextail
+ aey
* aeytail
+ aez
* aeztail
)
2621 * (bez
* cd3
- cez
* bd3
+ dez
* bc3
)
2622 + (cex
* cextail
+ cey
* ceytail
+ cez
* ceztail
)
2623 * (dez
* ab3
+ aez
* bd3
+ bez
* da3
)));
2624 if ((det
>= errbound
) || (-det
>= errbound
)) {
2628 return insphereexact(pa
, pb
, pc
, pd
, pe
);
2631 REAL
insphere(pa
, pb
, pc
, pd
, pe
)
2638 REAL aex
, bex
, cex
, dex
;
2639 REAL aey
, bey
, cey
, dey
;
2640 REAL aez
, bez
, cez
, dez
;
2641 REAL aexbey
, bexaey
, bexcey
, cexbey
, cexdey
, dexcey
, dexaey
, aexdey
;
2642 REAL aexcey
, cexaey
, bexdey
, dexbey
;
2643 REAL alift
, blift
, clift
, dlift
;
2644 REAL ab
, bc
, cd
, da
, ac
, bd
;
2645 REAL abc
, bcd
, cda
, dab
;
2646 REAL aezplus
, bezplus
, cezplus
, dezplus
;
2647 REAL aexbeyplus
, bexaeyplus
, bexceyplus
, cexbeyplus
;
2648 REAL cexdeyplus
, dexceyplus
, dexaeyplus
, aexdeyplus
;
2649 REAL aexceyplus
, cexaeyplus
, bexdeyplus
, dexbeyplus
;
2651 REAL permanent
, errbound
;
2656 aex
= pa
[0] - pe
[0];
2657 bex
= pb
[0] - pe
[0];
2658 cex
= pc
[0] - pe
[0];
2659 dex
= pd
[0] - pe
[0];
2660 aey
= pa
[1] - pe
[1];
2661 bey
= pb
[1] - pe
[1];
2662 cey
= pc
[1] - pe
[1];
2663 dey
= pd
[1] - pe
[1];
2664 aez
= pa
[2] - pe
[2];
2665 bez
= pb
[2] - pe
[2];
2666 cez
= pc
[2] - pe
[2];
2667 dez
= pd
[2] - pe
[2];
2671 ab
= aexbey
- bexaey
;
2674 bc
= bexcey
- cexbey
;
2677 cd
= cexdey
- dexcey
;
2680 da
= dexaey
- aexdey
;
2684 ac
= aexcey
- cexaey
;
2687 bd
= bexdey
- dexbey
;
2689 abc
= aez
* bc
- bez
* ac
+ cez
* ab
;
2690 bcd
= bez
* cd
- cez
* bd
+ dez
* bc
;
2691 cda
= cez
* da
+ dez
* ac
+ aez
* cd
;
2692 dab
= dez
* ab
+ aez
* bd
+ bez
* da
;
2694 alift
= aex
* aex
+ aey
* aey
+ aez
* aez
;
2695 blift
= bex
* bex
+ bey
* bey
+ bez
* bez
;
2696 clift
= cex
* cex
+ cey
* cey
+ cez
* cez
;
2697 dlift
= dex
* dex
+ dey
* dey
+ dez
* dez
;
2699 det
= (dlift
* abc
- clift
* dab
) + (blift
* cda
- alift
* bcd
);
2701 aezplus
= Absolute(aez
);
2702 bezplus
= Absolute(bez
);
2703 cezplus
= Absolute(cez
);
2704 dezplus
= Absolute(dez
);
2705 aexbeyplus
= Absolute(aexbey
);
2706 bexaeyplus
= Absolute(bexaey
);
2707 bexceyplus
= Absolute(bexcey
);
2708 cexbeyplus
= Absolute(cexbey
);
2709 cexdeyplus
= Absolute(cexdey
);
2710 dexceyplus
= Absolute(dexcey
);
2711 dexaeyplus
= Absolute(dexaey
);
2712 aexdeyplus
= Absolute(aexdey
);
2713 aexceyplus
= Absolute(aexcey
);
2714 cexaeyplus
= Absolute(cexaey
);
2715 bexdeyplus
= Absolute(bexdey
);
2716 dexbeyplus
= Absolute(dexbey
);
2717 permanent
= ((cexdeyplus
+ dexceyplus
) * bezplus
2718 + (dexbeyplus
+ bexdeyplus
) * cezplus
2719 + (bexceyplus
+ cexbeyplus
) * dezplus
)
2721 + ((dexaeyplus
+ aexdeyplus
) * cezplus
2722 + (aexceyplus
+ cexaeyplus
) * dezplus
2723 + (cexdeyplus
+ dexceyplus
) * aezplus
)
2725 + ((aexbeyplus
+ bexaeyplus
) * dezplus
2726 + (bexdeyplus
+ dexbeyplus
) * aezplus
2727 + (dexaeyplus
+ aexdeyplus
) * bezplus
)
2729 + ((bexceyplus
+ cexbeyplus
) * aezplus
2730 + (cexaeyplus
+ aexceyplus
) * bezplus
2731 + (aexbeyplus
+ bexaeyplus
) * cezplus
)
2733 errbound
= isperrboundA
* permanent
;
2734 if ((det
> errbound
) || (-det
> errbound
)) {
2739 ins
= insphereadapt(pa
, pb
, pc
, pd
, pe
, permanent
);