2 # pragma warning (disable : 985)
5 /*****************************************************************************/
7 /* Routines for Arbitrary Precision Floating-point Arithmetic */
8 /* and Fast Robust Geometric Predicates */
13 /* Placed in the public domain by */
14 /* Jonathan Richard Shewchuk */
15 /* School of Computer Science */
16 /* Carnegie Mellon University */
17 /* 5000 Forbes Avenue */
18 /* Pittsburgh, Pennsylvania 15213-3891 */
21 /* This file contains C implementation of algorithms for exact addition */
22 /* and multiplication of floating-point numbers, and predicates for */
23 /* robustly performing the orientation and incircle tests used in */
24 /* computational geometry. The algorithms and underlying theory are */
25 /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
26 /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
27 /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
28 /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
29 /* Discrete & Computational Geometry.) */
31 /* This file, the paper listed above, and other information are available */
32 /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
34 /*****************************************************************************/
36 /*****************************************************************************/
38 /* Using this code: */
40 /* First, read the short or long version of the paper (from the Web page */
43 /* Be sure to call exactinit() once, before calling any of the arithmetic */
44 /* functions or geometric predicates. Also be sure to turn on the */
45 /* optimizer when compiling this file. */
48 /* Several geometric predicates are defined. Their parameters are all */
49 /* points. Each point is an array of two or three floating-point */
50 /* numbers. The geometric predicates, described in the papers, are */
52 /* orient2d(pa, pb, pc) */
53 /* orient2dfast(pa, pb, pc) */
54 /* orient3d(pa, pb, pc, pd) */
55 /* orient3dfast(pa, pb, pc, pd) */
56 /* incircle(pa, pb, pc, pd) */
57 /* incirclefast(pa, pb, pc, pd) */
58 /* insphere(pa, pb, pc, pd, pe) */
59 /* inspherefast(pa, pb, pc, pd, pe) */
61 /* Those with suffix "fast" are approximate, non-robust versions. Those */
62 /* without the suffix are adaptive precision, robust versions. There */
63 /* are also versions with the suffices "exact" and "slow", which are */
64 /* non-adaptive, exact arithmetic versions, which I use only for timings */
65 /* in my arithmetic papers. */
68 /* An expansion is represented by an array of floating-point numbers, */
69 /* sorted from smallest to largest magnitude (possibly with interspersed */
70 /* zeros). The length of each expansion is stored as a separate integer, */
71 /* and each arithmetic function returns an integer which is the length */
72 /* of the expansion it created. */
74 /* Several arithmetic functions are defined. Their parameters are */
76 /* e, f Input expansions */
77 /* elen, flen Lengths of input expansions (must be >= 1) */
78 /* h Output expansion */
81 /* The arithmetic functions are */
83 /* grow_expansion(elen, e, b, h) */
84 /* grow_expansion_zeroelim(elen, e, b, h) */
85 /* expansion_sum(elen, e, flen, f, h) */
86 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */
87 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */
88 /* fast_expansion_sum(elen, e, flen, f, h) */
89 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
90 /* linear_expansion_sum(elen, e, flen, f, h) */
91 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
92 /* scale_expansion(elen, e, b, h) */
93 /* scale_expansion_zeroelim(elen, e, b, h) */
94 /* compress(elen, e, h) */
96 /* All of these are described in the long version of the paper; some are */
97 /* described in the short version. All return an integer that is the */
98 /* length of h. Those with suffix _zeroelim perform zero elimination, */
99 /* and are recommended over their counterparts. The procedure */
100 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
101 /* processors that do not use the round-to-even tiebreaking rule) is */
102 /* recommended over expansion_sum_zeroelim(). Each procedure has a */
103 /* little note next to it (in the code below) that tells you whether or */
104 /* not the output expansion may be the same array as one of the input */
108 /* If you look around below, you'll also find macros for a bunch of */
109 /* simple unrolled arithmetic operations, and procedures for printing */
110 /* expansions (commented out because they don't work with all C */
111 /* compilers) and for generating random floating-point numbers whose */
112 /* significand bits are all random. Most of the macros have undocumented */
113 /* requirements that certain of their parameters should not be the same */
114 /* variable; for safety, better to make sure all the parameters are */
115 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
116 /* have questions. */
118 /*****************************************************************************/
120 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
121 #pragma GCC diagnostic warning "-Wunused-function"
131 # define random my_random
135 static unsigned int fpu_init
;
136 # define OSG_FPU_ROUND_DOUBLE (fpu_init = _controlfp(0, 0), \
137 _controlfp(_PC_53, _MCW_PC))
138 # define OSG_FPU_RESTORE (_controlfp(fpu_init, 0xfffff))
142 # include <sys/time.h>
144 #include "OSGpredicates.h"
148 /* Use header file generated automatically by predicates_init. */
149 //#define OSG_USE_PREDICATES_INIT
151 #ifdef OSG_USE_PREDICATES_INIT
152 #include "predicates_init.h"
153 #endif /* OSG_USE_PREDICATES_INIT */
155 /* FPU control. We MUST have only double precision (not extended precision) */
156 #include "OSGrounding.h"
158 /* On some machines, the exact arithmetic routines might be defeated by the */
159 /* use of internal extended precision floating-point registers. Sometimes */
160 /* this problem can be fixed by defining certain values to be volatile, */
161 /* thus forcing them to be stored to memory and rounded off. This isn't */
162 /* a great solution, though, as it slows the arithmetic down. */
164 /* To try this out, write "#define INEXACT volatile" below. Normally, */
165 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
167 #define INEXACT /* Nothing */
168 //#define INEXACT volatile
170 #define REAL double /* float or double */
171 #define REALPRINT doubleprint
172 #define REALRAND doublerand
173 #define NARROWRAND narrowdoublerand
174 #define UNIFORMRAND uniformdoublerand
176 /* Which of the following two methods of finding the absolute values is */
177 /* fastest is compiler-dependent. A few compilers can inline and optimize */
178 /* the fabs() call; but most will incur the overhead of a function call, */
179 /* which is disastrously slow. A faster way on IEEE machines might be to */
180 /* mask the appropriate bit, but that's difficult to do in C. */
182 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
183 /* #define Absolute(a) fabs(a) */
185 /* Many of the operations are broken up into two pieces, a main part that */
186 /* performs an approximate operation, and a "tail" that computes the */
187 /* roundoff error of that operation. */
189 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
190 /* Split(), and Two_Product() are all implemented as described in the */
191 /* reference. Each of these macros requires certain variables to be */
192 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
193 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
194 /* they store the result of an operation that may incur roundoff error. */
195 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
196 /* also be declared `INEXACT'. */
198 #define Fast_Two_Sum_Tail(a, b, x, y) \
202 #define Fast_Two_Sum(a, b, x, y) \
204 Fast_Two_Sum_Tail(a, b, x, y)
206 #define Fast_Two_Diff_Tail(a, b, x, y) \
210 #define Fast_Two_Diff(a, b, x, y) \
212 Fast_Two_Diff_Tail(a, b, x, y)
214 #define Two_Sum_Tail(a, b, x, y) \
215 bvirt = REAL(x - a); \
217 bround = b - bvirt; \
218 around = a - avirt; \
221 #define Two_Sum(a, b, x, y) \
223 Two_Sum_Tail(a, b, x, y)
225 #define Two_Diff_Tail(a, b, x, y) \
226 bvirt = REAL(a - x); \
228 bround = bvirt - b; \
229 around = a - avirt; \
232 #define Two_Diff(a, b, x, y) \
234 Two_Diff_Tail(a, b, x, y)
236 #define Split(a, ahi, alo) \
237 c = REAL(splitter * a); \
238 abig = REAL(c - a); \
242 #define Two_Product_Tail(a, b, x, y) \
243 Split(a, ahi, alo); \
244 Split(b, bhi, blo); \
245 err1 = x - (ahi * bhi); \
246 err2 = err1 - (alo * bhi); \
247 err3 = err2 - (ahi * blo); \
248 y = (alo * blo) - err3
250 #define Two_Product(a, b, x, y) \
252 Two_Product_Tail(a, b, x, y)
254 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
255 /* already been split. Avoids redundant splitting. */
257 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
259 Split(a, ahi, alo); \
260 err1 = x - (ahi * bhi); \
261 err2 = err1 - (alo * bhi); \
262 err3 = err2 - (ahi * blo); \
263 y = (alo * blo) - err3
265 /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
266 /* already been split. Avoids redundant splitting. */
268 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
270 err1 = x - (ahi * bhi); \
271 err2 = err1 - (alo * bhi); \
272 err3 = err2 - (ahi * blo); \
273 y = (alo * blo) - err3
275 /* Square() can be done more quickly than Two_Product(). */
277 #define Square_Tail(a, x, y) \
278 Split(a, ahi, alo); \
279 err1 = x - (ahi * ahi); \
280 err3 = err1 - ((ahi + ahi) * alo); \
281 y = (alo * alo) - err3
283 #define Square(a, x, y) \
287 /* Macros for summing expansions of various fixed lengths. These are all */
288 /* unrolled versions of Expansion_Sum(). */
290 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
291 Two_Sum(a0, b, _i, x0); \
292 Two_Sum(a1, _i, x2, x1)
294 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
295 Two_Diff(a0, b, _i, x0); \
296 Two_Sum(a1, _i, x2, x1)
298 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
299 Two_One_Sum(a1, a0, b0, _j, _0, x0); \
300 Two_One_Sum(_j, _0, b1, x3, x2, x1)
302 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
303 Two_One_Diff(a1, a0, b0, _j, _0, x0); \
304 Two_One_Diff(_j, _0, b1, x3, x2, x1)
306 #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
307 Two_One_Sum(a1, a0, b, _j, x1, x0); \
308 Two_One_Sum(a3, a2, _j, x4, x3, x2)
310 #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
311 Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
312 Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
314 #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
316 Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
317 Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
319 #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
321 Four_One_Sum(a3, a2, a1, a0, b, _j, x3, x2, x1, x0); \
322 Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
324 #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
325 x6, x5, x4, x3, x2, x1, x0) \
326 Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
328 Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
331 #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
332 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
333 Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
334 _2, _1, _0, x1, x0); \
335 Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
336 x7, x6, x5, x4, x3, x2)
338 /* Macros for multiplying expansions of various fixed lengths. */
340 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
341 Split(b, bhi, blo); \
342 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
343 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
344 Two_Sum(_i, _0, _k, x1); \
345 Fast_Two_Sum(_j, _k, x3, x2)
347 #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
348 Split(b, bhi, blo); \
349 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
350 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
351 Two_Sum(_i, _0, _k, x1); \
352 Fast_Two_Sum(_j, _k, _i, x2); \
353 Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
354 Two_Sum(_i, _0, _k, x3); \
355 Fast_Two_Sum(_j, _k, _i, x4); \
356 Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
357 Two_Sum(_i, _0, _k, x5); \
358 Fast_Two_Sum(_j, _k, x7, x6)
360 #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
361 Split(a0, a0hi, a0lo); \
362 Split(b0, bhi, blo); \
363 Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
364 Split(a1, a1hi, a1lo); \
365 Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
366 Two_Sum(_i, _0, _k, _1); \
367 Fast_Two_Sum(_j, _k, _l, _2); \
368 Split(b1, bhi, blo); \
369 Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
370 Two_Sum(_1, _0, _k, x1); \
371 Two_Sum(_2, _k, _j, _1); \
372 Two_Sum(_l, _j, _m, _2); \
373 Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
374 Two_Sum(_i, _0, _n, _0); \
375 Two_Sum(_1, _0, _i, x2); \
376 Two_Sum(_2, _i, _k, _1); \
377 Two_Sum(_m, _k, _l, _2); \
378 Two_Sum(_j, _n, _k, _0); \
379 Two_Sum(_1, _0, _j, x3); \
380 Two_Sum(_2, _j, _i, _1); \
381 Two_Sum(_l, _i, _m, _2); \
382 Two_Sum(_1, _k, _i, x4); \
383 Two_Sum(_2, _i, _k, x5); \
384 Two_Sum(_m, _k, x7, x6)
386 /* An expansion of length two can be squared more quickly than finding the */
387 /* product of two different expansions of length two, and the result is */
388 /* guaranteed to have no more than six (rather than eight) components. */
390 #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
391 Square(a0, _j, x0); \
393 Two_Product(a1, _0, _k, _1); \
394 Two_One_Sum(_k, _1, _j, _l, _2, x1); \
395 Square(a1, _j, _1); \
396 Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
398 #ifndef OSG_USE_PREDICATES_INIT
400 static REAL splitter
; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
401 /* A set of coefficients used to calculate maximum roundoff errors. */
402 static REAL resulterrbound
;
403 static REAL ccwerrboundA
, ccwerrboundB
, ccwerrboundC
;
404 static REAL o3derrboundA
, o3derrboundB
, o3derrboundC
;
405 static REAL iccerrboundA
, iccerrboundB
, iccerrboundC
;
406 static REAL isperrboundA
, isperrboundB
, isperrboundC
;
408 #endif /* OSG_USE_PREDICATES_INIT */
410 /*****************************************************************************/
412 /* doubleprint() Print the bit representation of a double. */
414 /* Useful for debugging exact arithmetic routines. */
416 /*****************************************************************************/
419 void doubleprint(number)
422 unsigned long long no;
423 unsigned long long sign, expo;
427 no = *(unsigned long long *) &number;
428 sign = no & 0x8000000000000000ll;
429 expo = (no >> 52) & 0x7ffll;
430 exponent = (int) expo;
431 exponent = exponent - 1023;
437 if (exponent == -1023) {
439 "0.0000000000000000000000000000000000000000000000000000_ ( )");
443 for (i = 0; i < 52; i++) {
444 if (no & 0x0008000000000000ll) {
452 printf("_%d (%d)", exponent, exponent - 1 - bottomi);
457 /*****************************************************************************/
459 /* floatprint() Print the bit representation of a float. */
461 /* Useful for debugging exact arithmetic routines. */
463 /*****************************************************************************/
466 void floatprint(number)
474 no = *(unsigned *) &number;
475 sign = no & 0x80000000;
476 expo = (no >> 23) & 0xff;
477 exponent = (int) expo;
478 exponent = exponent - 127;
484 if (exponent == -127) {
485 printf("0.00000000000000000000000_ ( )");
489 for (i = 0; i < 23; i++) {
490 if (no & 0x00400000) {
498 printf("_%3d (%3d)", exponent, exponent - 1 - bottomi);
503 /*****************************************************************************/
505 /* expansion_print() Print the bit representation of an expansion. */
507 /* Useful for debugging exact arithmetic routines. */
509 /*****************************************************************************/
512 void expansion_print(elen, e)
518 for (i = elen - 1; i >= 0; i--) {
531 /* computes a long random number for WIN32 */
537 char* res_addr
= (char*)&res
;
539 srand((unsigned)time(NULL
));
546 c
[2 * i
+ 1] = (char)r
;
550 *(res_addr
++) = c
[i
];
556 //#########################################################
557 #if 0 // NOT USED RIGHT NOW, TURNED OFF TO PREVENT WARNINGS
558 //#########################################################
560 /*****************************************************************************/
562 /* doublerand() Generate a double with random 53-bit significand and a */
563 /* random exponent in [0, 511]. */
565 /*****************************************************************************/
567 static double doublerand()
577 result
= double(a
- 1073741824) * 8388608.0 + double(b
>> 8);
579 for(i
= 512, expo
= 2; i
<= 131072; i
*= 2, expo
= expo
* expo
)
590 /*****************************************************************************/
592 /* narrowdoublerand() Generate a double with random 53-bit significand */
593 /* and a random exponent in [0, 7]. */
595 /*****************************************************************************/
597 static double narrowdoublerand()
607 result
= double(a
- 1073741824) * 8388608.0 + double(b
>> 8);
609 for(i
= 512, expo
= 2; i
<= 2048; i
*= 2, expo
= expo
* expo
)
620 /*****************************************************************************/
622 /* uniformdoublerand() Generate a double with random 53-bit significand. */
624 /*****************************************************************************/
626 static double uniformdoublerand()
633 result
= double(a
- 1073741824) * 8388608.0 + double(b
>> 8);
637 /*****************************************************************************/
639 /* floatrand() Generate a float with random 24-bit significand and a */
640 /* random exponent in [0, 63]. */
642 /*****************************************************************************/
644 static float floatrand()
653 result
= float((a
- 1073741824) >> 6);
655 for(i
= 512, expo
= 2; i
<= 16384; i
*= 2, expo
= expo
* expo
)
666 /*****************************************************************************/
668 /* narrowfloatrand() Generate a float with random 24-bit significand and */
669 /* a random exponent in [0, 7]. */
671 /*****************************************************************************/
673 static float narrowfloatrand()
682 result
= float((a
- 1073741824) >> 6);
684 for(i
= 512, expo
= 2; i
<= 2048; i
*= 2, expo
= expo
* expo
)
695 /*****************************************************************************/
697 /* uniformfloatrand() Generate a float with random 24-bit significand. */
699 /*****************************************************************************/
701 static float uniformfloatrand()
707 result
= float((a
- 1073741824) >> 6);
713 /*****************************************************************************/
715 /* exactinit() Initialize the variables used for exact arithmetic. */
717 /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */
718 /* floating-point arithmetic. `epsilon' bounds the relative roundoff */
719 /* error. It is used for floating-point error analysis. */
721 /* `splitter' is used to split floating-point numbers into two half- */
722 /* length significands for exact multiplication. */
724 /* I imagine that a highly optimizing compiler might be too smart for its */
725 /* own good, and somehow cause this routine to fail, if it pretends that */
726 /* floating-point arithmetic is too much like real arithmetic. */
728 /* Don't change this routine unless you fully understand it. */
730 /*****************************************************************************/
732 void OSG::exactinit()
735 REAL check
, lastcheck
;
737 REAL epsilon
= 1.0; /* = 2^(-p). Used to estimate roundoff errors. */
739 OSG_FPU_ROUND_DOUBLE
;
745 /* Repeatedly divide `epsilon' by two until it is too small to add to */
746 /* one without causing roundoff. (Also check if the sum is equal to */
747 /* the previous sum, for machines that round up instead of using exact */
748 /* rounding. Not that this library will work on such machines anyway. */
756 every_other
= !every_other
;
757 check
= 1.0 + epsilon
;
758 } while((check
!= 1.0) && (check
!= lastcheck
));
760 // fprintf (stderr, "check: %g\n", check - lastcheck);
761 // fprintf (stderr, "epsilon: %g %g\n", epsilon, DBL_EPSILON);
762 // fprintf (stderr, "epsilon: %g \n", epsilon);
763 /* Error bounds for orientation and incircle tests. */
764 resulterrbound
= ( 3.0 + 8.0 * epsilon
) * epsilon
;
765 ccwerrboundA
= ( 3.0 + 16.0 * epsilon
) * epsilon
;
766 ccwerrboundB
= ( 2.0 + 12.0 * epsilon
) * epsilon
;
767 ccwerrboundC
= ( 9.0 + 64.0 * epsilon
) * epsilon
* epsilon
;
768 o3derrboundA
= ( 7.0 + 56.0 * epsilon
) * epsilon
;
769 o3derrboundB
= ( 3.0 + 28.0 * epsilon
) * epsilon
;
770 o3derrboundC
= (26.0 + 288.0 * epsilon
) * epsilon
* epsilon
;
771 iccerrboundA
= (10.0 + 96.0 * epsilon
) * epsilon
;
772 iccerrboundB
= ( 4.0 + 48.0 * epsilon
) * epsilon
;
773 iccerrboundC
= (44.0 + 576.0 * epsilon
) * epsilon
* epsilon
;
774 isperrboundA
= (16.0 + 224.0 * epsilon
) * epsilon
;
775 isperrboundB
= ( 5.0 + 72.0 * epsilon
) * epsilon
;
776 isperrboundC
= (71.0 + 1408.0 * epsilon
) * epsilon
* epsilon
;
780 //#########################################################
781 #if 0 // NOT USED RIGHT NOW, TURNED OFF TO PREVENT WARNINGS
782 //#########################################################
784 /*****************************************************************************/
786 /* grow_expansion() Add a scalar to an expansion. */
788 /* Sets h = e + b. See the long version of my paper for details. */
790 /* Maintains the nonoverlapping property. If round-to-even is used (as */
791 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
792 /* properties as well. (That is, if e has one of these properties, so */
795 /*****************************************************************************/
797 static int grow_expansion(int elen
, REAL
*e
, REAL b
, REAL
*h
) /* e and h can be the same. */
808 REAL avirt
, bround
, around
;
812 for(eindex
= 0; eindex
< elen
; eindex
++)
815 Two_Sum(Q
, enow
, Qnew
, h
[eindex
]);
823 /*****************************************************************************/
825 /* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */
826 /* zero components from the output expansion. */
828 /* Sets h = e + b. See the long version of my paper for details. */
830 /* Maintains the nonoverlapping property. If round-to-even is used (as */
831 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
832 /* properties as well. (That is, if e has one of these properties, so */
835 /*****************************************************************************/
837 static int grow_expansion_zeroelim(int elen
, REAL
*e
, REAL b
, REAL
*h
) /* e and h can be the same. */
848 REAL avirt
, bround
, around
;
853 for(eindex
= 0; eindex
< elen
; eindex
++)
856 Two_Sum(Q
, enow
, Qnew
, hh
);
864 if((Q
!= 0.0) || (hindex
== 0))
871 /*****************************************************************************/
873 /* expansion_sum() Sum two expansions. */
875 /* Sets h = e + f. See the long version of my paper for details. */
877 /* Maintains the nonoverlapping property. If round-to-even is used (as */
878 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */
879 /* if e has one of these properties, so will h.) Does NOT maintain the */
880 /* strongly nonoverlapping property. */
882 /*****************************************************************************/
884 static int expansion_sum(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
)
885 /* e and h can be the same, but f and h cannot. */
894 int findex
, hindex
, hlast
;
897 REAL avirt
, bround
, around
;
901 for(hindex
= 0; hindex
< elen
; hindex
++)
904 Two_Sum(Q
, hnow
, Qnew
, h
[hindex
]);
911 for(findex
= 1; findex
< flen
; findex
++)
915 for(hindex
= findex
; hindex
<= hlast
; hindex
++)
918 Two_Sum(Q
, hnow
, Qnew
, h
[hindex
]);
928 /*****************************************************************************/
930 /* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */
931 /* components from the output expansion. */
933 /* Sets h = e + f. See the long version of my paper for details. */
935 /* Maintains the nonoverlapping property. If round-to-even is used (as */
936 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */
937 /* if e has one of these properties, so will h.) Does NOT maintain the */
938 /* strongly nonoverlapping property. */
940 /*****************************************************************************/
942 static int expansion_sum_zeroelim1(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
)
943 /* e and h can be the same, but f and h cannot. */
952 int index
, findex
, hindex
, hlast
;
955 REAL avirt
, bround
, around
;
959 for(hindex
= 0; hindex
< elen
; hindex
++)
962 Two_Sum(Q
, hnow
, Qnew
, h
[hindex
]);
969 for(findex
= 1; findex
< flen
; findex
++)
973 for(hindex
= findex
; hindex
<= hlast
; hindex
++)
976 Two_Sum(Q
, hnow
, Qnew
, h
[hindex
]);
985 for(index
= 0; index
<= hlast
; index
++)
1004 /*****************************************************************************/
1006 /* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */
1007 /* components from the output expansion. */
1009 /* Sets h = e + f. See the long version of my paper for details. */
1011 /* Maintains the nonoverlapping property. If round-to-even is used (as */
1012 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */
1013 /* if e has one of these properties, so will h.) Does NOT maintain the */
1014 /* strongly nonoverlapping property. */
1016 /*****************************************************************************/
1018 static int expansion_sum_zeroelim2(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
)
1019 /* e and h can be the same, but f and h cannot. */
1028 int eindex
, findex
, hindex
, hlast
;
1031 REAL avirt
, bround
, around
;
1036 for(eindex
= 0; eindex
< elen
; eindex
++)
1039 Two_Sum(Q
, enow
, Qnew
, hh
);
1050 for(findex
= 1; findex
< flen
; findex
++)
1055 for(eindex
= 0; eindex
<= hlast
; eindex
++)
1058 Two_Sum(Q
, enow
, Qnew
, hh
);
1073 /*****************************************************************************/
1075 /* fast_expansion_sum() Sum two expansions. */
1077 /* Sets h = e + f. See the long version of my paper for details. */
1079 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
1080 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
1081 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
1084 /*****************************************************************************/
1086 static int fast_expansion_sum(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
) /* h cannot be e or f. */
1096 REAL avirt
, bround
, around
;
1097 int eindex
, findex
, hindex
;
1102 eindex
= findex
= 0;
1103 if((fnow
> enow
) == (fnow
> -enow
))
1114 if((eindex
< elen
) && (findex
< flen
))
1116 if((fnow
> enow
) == (fnow
> -enow
))
1118 Fast_Two_Sum(enow
, Q
, Qnew
, h
[0]);
1123 Fast_Two_Sum(fnow
, Q
, Qnew
, h
[0]);
1128 while((eindex
< elen
) && (findex
< flen
))
1130 if((fnow
> enow
) == (fnow
> -enow
))
1132 Two_Sum(Q
, enow
, Qnew
, h
[hindex
]);
1137 Two_Sum(Q
, fnow
, Qnew
, h
[hindex
]);
1144 while(eindex
< elen
)
1146 Two_Sum(Q
, enow
, Qnew
, h
[hindex
]);
1151 while(findex
< flen
)
1153 Two_Sum(Q
, fnow
, Qnew
, h
[hindex
]);
1162 //#########################################################
1164 //#########################################################
1167 /*****************************************************************************/
1169 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
1170 /* components from the output expansion. */
1172 /* Sets h = e + f. See the long version of my paper for details. */
1174 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
1175 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
1176 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
1179 /*****************************************************************************/
1181 static int fast_expansion_sum_zeroelim(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
) /* h cannot be e or f. */
1192 REAL avirt
, bround
, around
;
1193 int eindex
, findex
, hindex
;
1198 eindex
= findex
= 0;
1199 if((fnow
> enow
) == (fnow
> -enow
))
1210 if((eindex
< elen
) && (findex
< flen
))
1212 if((fnow
> enow
) == (fnow
> -enow
))
1214 Fast_Two_Sum(enow
, Q
, Qnew
, hh
);
1219 Fast_Two_Sum(fnow
, Q
, Qnew
, hh
);
1227 while((eindex
< elen
) && (findex
< flen
))
1229 if((fnow
> enow
) == (fnow
> -enow
))
1231 Two_Sum(Q
, enow
, Qnew
, hh
);
1236 Two_Sum(Q
, fnow
, Qnew
, hh
);
1246 while(eindex
< elen
)
1248 Two_Sum(Q
, enow
, Qnew
, hh
);
1256 while(findex
< flen
)
1258 Two_Sum(Q
, fnow
, Qnew
, hh
);
1266 if((Q
!= 0.0) || (hindex
== 0))
1274 //#########################################################
1276 //#########################################################
1278 /*****************************************************************************/
1280 /* linear_expansion_sum() Sum two expansions. */
1282 /* Sets h = e + f. See either version of my paper for details. */
1284 /* Maintains the nonoverlapping property. (That is, if e is */
1285 /* nonoverlapping, h will be also.) */
1287 /*****************************************************************************/
1289 static int linear_expansion_sum(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
) /* h cannot be e or f. */
1300 REAL avirt
, bround
, around
;
1301 int eindex
, findex
, hindex
;
1307 eindex
= findex
= 0;
1308 if((fnow
> enow
) == (fnow
> -enow
))
1318 if((eindex
< elen
) && ((findex
>= flen
)
1319 || ((fnow
> enow
) == (fnow
> -enow
))))
1321 Fast_Two_Sum(enow
, g0
, Qnew
, q
);
1326 Fast_Two_Sum(fnow
, g0
, Qnew
, q
);
1331 for(hindex
= 0; hindex
< elen
+ flen
- 2; hindex
++)
1333 if((eindex
< elen
) && ((findex
>= flen
)
1334 || ((fnow
> enow
) == (fnow
> -enow
))))
1336 Fast_Two_Sum(enow
, q
, R
, h
[hindex
]);
1341 Fast_Two_Sum(fnow
, q
, R
, h
[hindex
]);
1344 Two_Sum(Q
, R
, Qnew
, q
);
1353 /*****************************************************************************/
1355 /* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
1356 /* components from the output expansion. */
1358 /* Sets h = e + f. See either version of my paper for details. */
1360 /* Maintains the nonoverlapping property. (That is, if e is */
1361 /* nonoverlapping, h will be also.) */
1363 /*****************************************************************************/
1365 static int linear_expansion_sum_zeroelim(int elen
, REAL
*e
, int flen
, REAL
*f
, REAL
*h
) /* h cannot be e or f. */
1376 REAL avirt
, bround
, around
;
1377 int eindex
, findex
, hindex
;
1384 eindex
= findex
= 0;
1386 if((fnow
> enow
) == (fnow
> -enow
))
1396 if((eindex
< elen
) && ((findex
>= flen
)
1397 || ((fnow
> enow
) == (fnow
> -enow
))))
1399 Fast_Two_Sum(enow
, g0
, Qnew
, q
);
1404 Fast_Two_Sum(fnow
, g0
, Qnew
, q
);
1409 for(count
= 2; count
< elen
+ flen
; count
++)
1411 if((eindex
< elen
) && ((findex
>= flen
)
1412 || ((fnow
> enow
) == (fnow
> -enow
))))
1414 Fast_Two_Sum(enow
, q
, R
, hh
);
1419 Fast_Two_Sum(fnow
, q
, R
, hh
);
1422 Two_Sum(Q
, R
, Qnew
, q
);
1434 if((Q
!= 0.0) || (hindex
== 0))
1441 /*****************************************************************************/
1443 /* scale_expansion() Multiply an expansion by a scalar. */
1445 /* Sets h = be. See either version of my paper for details. */
1447 /* Maintains the nonoverlapping property. If round-to-even is used (as */
1448 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
1449 /* properties as well. (That is, if e has one of these properties, so */
1452 /*****************************************************************************/
1454 static int scale_expansion(int elen
, REAL
*e
, REAL b
, REAL
*h
) /* e and h cannot be the same. */
1462 INEXACT REAL product1
;
1467 REAL avirt
, bround
, around
;
1470 REAL ahi
, alo
, bhi
, blo
;
1471 REAL err1
, err2
, err3
;
1474 Two_Product_Presplit(e
[0], b
, bhi
, blo
, Q
, h
[0]);
1477 for(eindex
= 1; eindex
< elen
; eindex
++)
1480 Two_Product_Presplit(enow
, b
, bhi
, blo
, product1
, product0
);
1481 Two_Sum(Q
, product0
, sum
, h
[hindex
]);
1483 Two_Sum(product1
, sum
, Q
, h
[hindex
]);
1491 //#########################################################
1493 //#########################################################
1495 /*****************************************************************************/
1497 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
1498 /* eliminating zero components from the */
1499 /* output expansion. */
1501 /* Sets h = be. See either version of my paper for details. */
1503 /* Maintains the nonoverlapping property. If round-to-even is used (as */
1504 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
1505 /* properties as well. (That is, if e has one of these properties, so */
1508 /*****************************************************************************/
1510 static int scale_expansion_zeroelim(int elen
, REAL
*e
, REAL b
, REAL
*h
) /* e and h cannot be the same. */
1516 INEXACT REAL Q
, sum
;
1518 INEXACT REAL product1
;
1523 REAL avirt
, bround
, around
;
1526 REAL ahi
, alo
, bhi
, blo
;
1527 REAL err1
, err2
, err3
;
1530 Two_Product_Presplit(e
[0], b
, bhi
, blo
, Q
, hh
);
1537 for(eindex
= 1; eindex
< elen
; eindex
++)
1540 Two_Product_Presplit(enow
, b
, bhi
, blo
, product1
, product0
);
1541 Two_Sum(Q
, product0
, sum
, hh
);
1546 Fast_Two_Sum(product1
, sum
, Q
, hh
);
1553 if((Q
!= 0.0) || (hindex
== 0))
1561 //#########################################################
1563 //#########################################################
1565 /*****************************************************************************/
1567 /* compress() Compress an expansion. */
1569 /* See the long version of my paper for details. */
1571 /* Maintains the nonoverlapping property. If round-to-even is used (as */
1572 /* with IEEE 754), then any nonoverlapping expansion is converted to a */
1573 /* nonadjacent expansion. */
1575 /*****************************************************************************/
1577 static int compress(int elen
, REAL
*e
, REAL
*h
) /* e and h may be the same. */
1592 for(eindex
= elen
- 2; eindex
>= 0; eindex
--)
1595 Fast_Two_Sum(Q
, enow
, Qnew
, q
);
1609 for(hindex
= bottom
+ 1; hindex
< elen
; hindex
++)
1612 Fast_Two_Sum(hnow
, Q
, Qnew
, q
);
1624 //#########################################################
1626 //#########################################################
1628 /*****************************************************************************/
1630 /* estimate() Produce a one-word estimate of an expansion's value. */
1632 /* See either version of my paper for details. */
1634 /*****************************************************************************/
1636 static REAL
estimate(int elen
, REAL
*e
)
1645 for(eindex
= 1; eindex
< elen
; eindex
++)
1653 /*****************************************************************************/
1655 /* orient2dfast() Approximate 2D orientation test. Nonrobust. */
1656 /* orient2dexact() Exact 2D orientation test. Robust. */
1657 /* orient2dslow() Another exact 2D orientation test. Robust. */
1658 /* orient2d() Adaptive exact 2D orientation test. Robust. */
1660 /* Return a positive value if the points pa, pb, and pc occur */
1661 /* in counterclockwise order; a negative value if they occur */
1662 /* in clockwise order; and zero if they are collinear. The */
1663 /* result is also a rough approximation of twice the signed */
1664 /* area of the triangle defined by the three points. */
1666 /* Only the first and last routine should be used; the middle two are for */
1669 /* The last three use exact arithmetic to ensure a correct answer. The */
1670 /* result returned is the determinant of a matrix. In orient2d() only, */
1671 /* this determinant is computed adaptively, in the sense that exact */
1672 /* arithmetic is used only to the degree it is needed to ensure that the */
1673 /* returned value has the correct sign. Hence, orient2d() is usually quite */
1674 /* fast, but will run more slowly when the input points are collinear or */
1677 /*****************************************************************************/
1679 REAL
orient2dfast(REAL
*pa
, REAL
*pb
, REAL
*pc
)
1684 REAL acx
, bcx
, acy
, bcy
;
1686 acx
= pa
[0] - pc
[0];
1687 bcx
= pb
[0] - pc
[0];
1688 acy
= pa
[1] - pc
[1];
1689 bcy
= pb
[1] - pc
[1];
1690 return acx
* bcy
- acy
* bcx
;
1693 REAL
orient2dexact(REAL
*pa
, REAL
*pb
, REAL
*pc
)
1698 INEXACT REAL axby1
, axcy1
, bxcy1
, bxay1
, cxay1
, cxby1
;
1699 REAL axby0
, axcy0
, bxcy0
, bxay0
, cxay0
, cxby0
;
1700 REAL aterms
[4], bterms
[4], cterms
[4];
1701 INEXACT REAL aterms3
, bterms3
, cterms3
;
1703 int vlength
, wlength
;
1706 REAL avirt
, bround
, around
;
1709 REAL ahi
, alo
, bhi
, blo
;
1710 REAL err1
, err2
, err3
;
1711 INEXACT REAL _i
, _j
;
1714 Two_Product(pa
[0], pb
[1], axby1
, axby0
);
1715 Two_Product(pa
[0], pc
[1], axcy1
, axcy0
);
1716 Two_Two_Diff(axby1
, axby0
, axcy1
, axcy0
,
1717 aterms3
, aterms
[2], aterms
[1], aterms
[0]);
1718 aterms
[3] = aterms3
;
1720 Two_Product(pb
[0], pc
[1], bxcy1
, bxcy0
);
1721 Two_Product(pb
[0], pa
[1], bxay1
, bxay0
);
1722 Two_Two_Diff(bxcy1
, bxcy0
, bxay1
, bxay0
,
1723 bterms3
, bterms
[2], bterms
[1], bterms
[0]);
1724 bterms
[3] = bterms3
;
1726 Two_Product(pc
[0], pa
[1], cxay1
, cxay0
);
1727 Two_Product(pc
[0], pb
[1], cxby1
, cxby0
);
1728 Two_Two_Diff(cxay1
, cxay0
, cxby1
, cxby0
,
1729 cterms3
, cterms
[2], cterms
[1], cterms
[0]);
1730 cterms
[3] = cterms3
;
1732 vlength
= fast_expansion_sum_zeroelim(4, aterms
, 4, bterms
, v
);
1733 wlength
= fast_expansion_sum_zeroelim(vlength
, v
, 4, cterms
, w
);
1735 return w
[wlength
- 1];
1738 REAL
orient2dslow(REAL
*pa
, REAL
*pb
, REAL
*pc
)
1743 INEXACT REAL acx
, acy
, bcx
, bcy
;
1744 REAL acxtail
, acytail
;
1745 REAL bcxtail
, bcytail
;
1746 REAL negate
, negatetail
;
1747 REAL axby
[8], bxay
[8];
1748 INEXACT REAL axby7
, bxay7
;
1753 REAL avirt
, bround
, around
;
1756 REAL a0hi
, a0lo
, a1hi
, a1lo
, bhi
, blo
;
1757 REAL err1
, err2
, err3
;
1758 INEXACT REAL _i
, _j
, _k
, _l
, _m
, _n
;
1761 Two_Diff(pa
[0], pc
[0], acx
, acxtail
);
1762 Two_Diff(pa
[1], pc
[1], acy
, acytail
);
1763 Two_Diff(pb
[0], pc
[0], bcx
, bcxtail
);
1764 Two_Diff(pb
[1], pc
[1], bcy
, bcytail
);
1766 Two_Two_Product(acx
, acxtail
, bcy
, bcytail
,
1767 axby7
, axby
[6], axby
[5], axby
[4],
1768 axby
[3], axby
[2], axby
[1], axby
[0]);
1771 negatetail
= -acytail
;
1772 Two_Two_Product(bcx
, bcxtail
, negate
, negatetail
,
1773 bxay7
, bxay
[6], bxay
[5], bxay
[4],
1774 bxay
[3], bxay
[2], bxay
[1], bxay
[0]);
1777 deterlen
= fast_expansion_sum_zeroelim(8, axby
, 8, bxay
, deter
);
1779 return deter
[deterlen
- 1];
1782 REAL
orient2dadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL detsum
)
1788 INEXACT REAL acx
, acy
, bcx
, bcy
;
1789 REAL acxtail
, acytail
, bcxtail
, bcytail
;
1790 INEXACT REAL detleft
, detright
;
1791 REAL detlefttail
, detrighttail
;
1793 REAL B
[4], C1
[8], C2
[12], D
[16];
1795 int C1length
, C2length
, Dlength
;
1798 INEXACT REAL s1
, t1
;
1802 REAL avirt
, bround
, around
;
1805 REAL ahi
, alo
, bhi
, blo
;
1806 REAL err1
, err2
, err3
;
1807 INEXACT REAL _i
, _j
;
1810 acx
= REAL(pa
[0] - pc
[0]);
1811 bcx
= REAL(pb
[0] - pc
[0]);
1812 acy
= REAL(pa
[1] - pc
[1]);
1813 bcy
= REAL(pb
[1] - pc
[1]);
1815 Two_Product(acx
, bcy
, detleft
, detlefttail
);
1816 Two_Product(acy
, bcx
, detright
, detrighttail
);
1818 Two_Two_Diff(detleft
, detlefttail
, detright
, detrighttail
,
1819 B3
, B
[2], B
[1], B
[0]);
1822 det
= estimate(4, B
);
1823 errbound
= ccwerrboundB
* detsum
;
1824 // fprintf (stderr, "det: %g (%g)\n", det, errbound);
1825 if((det
>= errbound
) || (-det
>= errbound
))
1830 Two_Diff_Tail(pa
[0], pc
[0], acx
, acxtail
);
1831 Two_Diff_Tail(pb
[0], pc
[0], bcx
, bcxtail
);
1832 Two_Diff_Tail(pa
[1], pc
[1], acy
, acytail
);
1833 Two_Diff_Tail(pb
[1], pc
[1], bcy
, bcytail
);
1835 if((acxtail
== 0.0) && (acytail
== 0.0)
1836 && (bcxtail
== 0.0) && (bcytail
== 0.0))
1841 errbound
= ccwerrboundC
* detsum
+ resulterrbound
* Absolute(det
);
1842 det
+= (acx
* bcytail
+ bcy
* acxtail
)
1843 - (acy
* bcxtail
+ bcx
* acytail
);
1844 // fprintf (stderr, "det: %g (%g)\n", det, errbound);
1845 if((det
>= errbound
) || (-det
>= errbound
))
1850 Two_Product(acxtail
, bcy
, s1
, s0
);
1851 Two_Product(acytail
, bcx
, t1
, t0
);
1852 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
1854 C1length
= fast_expansion_sum_zeroelim(4, B
, 4, u
, C1
);
1856 Two_Product(acx
, bcytail
, s1
, s0
);
1857 Two_Product(acy
, bcxtail
, t1
, t0
);
1858 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
1860 C2length
= fast_expansion_sum_zeroelim(C1length
, C1
, 4, u
, C2
);
1862 Two_Product(acxtail
, bcytail
, s1
, s0
);
1863 Two_Product(acytail
, bcxtail
, t1
, t0
);
1864 Two_Two_Diff(s1
, s0
, t1
, t0
, u3
, u
[2], u
[1], u
[0]);
1866 Dlength
= fast_expansion_sum_zeroelim(C2length
, C2
, 4, u
, D
);
1868 return(D
[Dlength
- 1]);
1871 REAL
OSG::orient2d(REAL
*pa
, REAL
*pb
, REAL
*pc
)
1876 REAL detleft
, detright
, det
;
1877 REAL detsum
, errbound
;
1882 OSG_FPU_ROUND_DOUBLE
;
1884 // fprintf (stderr, "orient2d\n");
1886 detleft
= (pa
[0] - pc
[0]) * (pb
[1] - pc
[1]);
1887 detright
= (pa
[1] - pc
[1]) * (pb
[0] - pc
[0]);
1888 det
= detleft
- detright
;
1899 detsum
= detleft
+ detright
;
1902 else if(detleft
< 0.0)
1911 detsum
= -detleft
- detright
;
1920 errbound
= ccwerrboundA
* detsum
;
1922 // fprintf (stderr, "det: %g (%g)\n", det, errbound);
1924 if((det
>= errbound
) || (-det
>= errbound
))
1930 // fprintf (stderr, "orient2dadapt\n");
1932 orient
= orient2dadapt(pa
, pb
, pc
, detsum
);
1935 // fprintf (stderr, "det: %g\n", orient);
1942 /*****************************************************************************/
1944 /* orient3dfast() Approximate 3D orientation test. Nonrobust. */
1945 /* orient3dexact() Exact 3D orientation test. Robust. */
1946 /* orient3dslow() Another exact 3D orientation test. Robust. */
1947 /* orient3d() Adaptive exact 3D orientation test. Robust. */
1949 /* Return a positive value if the point pd lies below the */
1950 /* plane passing through pa, pb, and pc; "below" is defined so */
1951 /* that pa, pb, and pc appear in counterclockwise order when */
1952 /* viewed from above the plane. Returns a negative value if */
1953 /* pd lies above the plane. Returns zero if the points are */
1954 /* coplanar. The result is also a rough approximation of six */
1955 /* times the signed volume of the tetrahedron defined by the */
1958 /* Only the first and last routine should be used; the middle two are for */
1961 /* The last three use exact arithmetic to ensure a correct answer. The */
1962 /* result returned is the determinant of a matrix. In orient3d() only, */
1963 /* this determinant is computed adaptively, in the sense that exact */
1964 /* arithmetic is used only to the degree it is needed to ensure that the */
1965 /* returned value has the correct sign. Hence, orient3d() is usually quite */
1966 /* fast, but will run more slowly when the input points are coplanar or */
1969 /*****************************************************************************/
1971 REAL
orient3dfast(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
1981 adx
= pa
[0] - pd
[0];
1982 bdx
= pb
[0] - pd
[0];
1983 cdx
= pc
[0] - pd
[0];
1984 ady
= pa
[1] - pd
[1];
1985 bdy
= pb
[1] - pd
[1];
1986 cdy
= pc
[1] - pd
[1];
1987 adz
= pa
[2] - pd
[2];
1988 bdz
= pb
[2] - pd
[2];
1989 cdz
= pc
[2] - pd
[2];
1991 return adx
* (bdy
* cdz
- bdz
* cdy
)
1992 + bdx
* (cdy
* adz
- cdz
* ady
)
1993 + cdx
* (ady
* bdz
- adz
* bdy
);
1996 REAL
orient3dexact(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2002 INEXACT REAL axby1
, bxcy1
, cxdy1
, dxay1
, axcy1
, bxdy1
;
2003 INEXACT REAL bxay1
, cxby1
, dxcy1
, axdy1
, cxay1
, dxby1
;
2004 REAL axby0
, bxcy0
, cxdy0
, dxay0
, axcy0
, bxdy0
;
2005 REAL bxay0
, cxby0
, dxcy0
, axdy0
, cxay0
, dxby0
;
2006 REAL ab
[4], bc
[4], cd
[4], da
[4], ac
[4], bd
[4];
2009 REAL abc
[12], bcd
[12], cda
[12], dab
[12];
2010 int abclen
, bcdlen
, cdalen
, dablen
;
2011 REAL adet
[24], bdet
[24], cdet
[24], ddet
[24];
2012 int alen
, blen
, clen
, dlen
;
2013 REAL abdet
[48], cddet
[48];
2020 REAL avirt
, bround
, around
;
2023 REAL ahi
, alo
, bhi
, blo
;
2024 REAL err1
, err2
, err3
;
2025 INEXACT REAL _i
, _j
;
2028 Two_Product(pa
[0], pb
[1], axby1
, axby0
);
2029 Two_Product(pb
[0], pa
[1], bxay1
, bxay0
);
2030 Two_Two_Diff(axby1
, axby0
, bxay1
, bxay0
, ab
[3], ab
[2], ab
[1], ab
[0]);
2032 Two_Product(pb
[0], pc
[1], bxcy1
, bxcy0
);
2033 Two_Product(pc
[0], pb
[1], cxby1
, cxby0
);
2034 Two_Two_Diff(bxcy1
, bxcy0
, cxby1
, cxby0
, bc
[3], bc
[2], bc
[1], bc
[0]);
2036 Two_Product(pc
[0], pd
[1], cxdy1
, cxdy0
);
2037 Two_Product(pd
[0], pc
[1], dxcy1
, dxcy0
);
2038 Two_Two_Diff(cxdy1
, cxdy0
, dxcy1
, dxcy0
, cd
[3], cd
[2], cd
[1], cd
[0]);
2040 Two_Product(pd
[0], pa
[1], dxay1
, dxay0
);
2041 Two_Product(pa
[0], pd
[1], axdy1
, axdy0
);
2042 Two_Two_Diff(dxay1
, dxay0
, axdy1
, axdy0
, da
[3], da
[2], da
[1], da
[0]);
2044 Two_Product(pa
[0], pc
[1], axcy1
, axcy0
);
2045 Two_Product(pc
[0], pa
[1], cxay1
, cxay0
);
2046 Two_Two_Diff(axcy1
, axcy0
, cxay1
, cxay0
, ac
[3], ac
[2], ac
[1], ac
[0]);
2048 Two_Product(pb
[0], pd
[1], bxdy1
, bxdy0
);
2049 Two_Product(pd
[0], pb
[1], dxby1
, dxby0
);
2050 Two_Two_Diff(bxdy1
, bxdy0
, dxby1
, dxby0
, bd
[3], bd
[2], bd
[1], bd
[0]);
2052 templen
= fast_expansion_sum_zeroelim(4, cd
, 4, da
, temp8
);
2053 cdalen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, ac
, cda
);
2054 templen
= fast_expansion_sum_zeroelim(4, da
, 4, ab
, temp8
);
2055 dablen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, bd
, dab
);
2057 for(i
= 0; i
< 4; i
++)
2063 templen
= fast_expansion_sum_zeroelim(4, ab
, 4, bc
, temp8
);
2064 abclen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, ac
, abc
);
2065 templen
= fast_expansion_sum_zeroelim(4, bc
, 4, cd
, temp8
);
2066 bcdlen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, bd
, bcd
);
2068 alen
= scale_expansion_zeroelim(bcdlen
, bcd
, pa
[2], adet
);
2069 blen
= scale_expansion_zeroelim(cdalen
, cda
, -pb
[2], bdet
);
2070 clen
= scale_expansion_zeroelim(dablen
, dab
, pc
[2], cdet
);
2071 dlen
= scale_expansion_zeroelim(abclen
, abc
, -pd
[2], ddet
);
2073 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2074 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
2075 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdlen
, cddet
, deter
);
2077 return deter
[deterlen
- 1];
2080 REAL
orient3dslow(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2086 INEXACT REAL adx
, ady
, adz
, bdx
, bdy
, bdz
, cdx
, cdy
, cdz
;
2087 REAL adxtail
, adytail
, adztail
;
2088 REAL bdxtail
, bdytail
, bdztail
;
2089 REAL cdxtail
, cdytail
, cdztail
;
2090 REAL negate
, negatetail
;
2091 INEXACT REAL axby7
, bxcy7
, axcy7
, bxay7
, cxby7
, cxay7
;
2092 REAL axby
[8], bxcy
[8], axcy
[8], bxay
[8], cxby
[8], cxay
[8];
2093 REAL temp16
[16], temp32
[32], temp32t
[32];
2094 int temp16len
, temp32len
, temp32tlen
;
2095 REAL adet
[64], bdet
[64], cdet
[64];
2096 int alen
, blen
, clen
;
2103 REAL avirt
, bround
, around
;
2106 REAL a0hi
, a0lo
, a1hi
, a1lo
, bhi
, blo
;
2107 REAL err1
, err2
, err3
;
2108 INEXACT REAL _i
, _j
, _k
, _l
, _m
, _n
;
2111 Two_Diff(pa
[0], pd
[0], adx
, adxtail
);
2112 Two_Diff(pa
[1], pd
[1], ady
, adytail
);
2113 Two_Diff(pa
[2], pd
[2], adz
, adztail
);
2114 Two_Diff(pb
[0], pd
[0], bdx
, bdxtail
);
2115 Two_Diff(pb
[1], pd
[1], bdy
, bdytail
);
2116 Two_Diff(pb
[2], pd
[2], bdz
, bdztail
);
2117 Two_Diff(pc
[0], pd
[0], cdx
, cdxtail
);
2118 Two_Diff(pc
[1], pd
[1], cdy
, cdytail
);
2119 Two_Diff(pc
[2], pd
[2], cdz
, cdztail
);
2121 Two_Two_Product(adx
, adxtail
, bdy
, bdytail
,
2122 axby7
, axby
[6], axby
[5], axby
[4],
2123 axby
[3], axby
[2], axby
[1], axby
[0]);
2126 negatetail
= -adytail
;
2127 Two_Two_Product(bdx
, bdxtail
, negate
, negatetail
,
2128 bxay7
, bxay
[6], bxay
[5], bxay
[4],
2129 bxay
[3], bxay
[2], bxay
[1], bxay
[0]);
2131 Two_Two_Product(bdx
, bdxtail
, cdy
, cdytail
,
2132 bxcy7
, bxcy
[6], bxcy
[5], bxcy
[4],
2133 bxcy
[3], bxcy
[2], bxcy
[1], bxcy
[0]);
2136 negatetail
= -bdytail
;
2137 Two_Two_Product(cdx
, cdxtail
, negate
, negatetail
,
2138 cxby7
, cxby
[6], cxby
[5], cxby
[4],
2139 cxby
[3], cxby
[2], cxby
[1], cxby
[0]);
2141 Two_Two_Product(cdx
, cdxtail
, ady
, adytail
,
2142 cxay7
, cxay
[6], cxay
[5], cxay
[4],
2143 cxay
[3], cxay
[2], cxay
[1], cxay
[0]);
2146 negatetail
= -cdytail
;
2147 Two_Two_Product(adx
, adxtail
, negate
, negatetail
,
2148 axcy7
, axcy
[6], axcy
[5], axcy
[4],
2149 axcy
[3], axcy
[2], axcy
[1], axcy
[0]);
2152 temp16len
= fast_expansion_sum_zeroelim(8, bxcy
, 8, cxby
, temp16
);
2153 temp32len
= scale_expansion_zeroelim(temp16len
, temp16
, adz
, temp32
);
2154 temp32tlen
= scale_expansion_zeroelim(temp16len
, temp16
, adztail
, temp32t
);
2155 alen
= fast_expansion_sum_zeroelim(temp32len
, temp32
, temp32tlen
, temp32t
,
2158 temp16len
= fast_expansion_sum_zeroelim(8, cxay
, 8, axcy
, temp16
);
2159 temp32len
= scale_expansion_zeroelim(temp16len
, temp16
, bdz
, temp32
);
2160 temp32tlen
= scale_expansion_zeroelim(temp16len
, temp16
, bdztail
, temp32t
);
2161 blen
= fast_expansion_sum_zeroelim(temp32len
, temp32
, temp32tlen
, temp32t
,
2164 temp16len
= fast_expansion_sum_zeroelim(8, axby
, 8, bxay
, temp16
);
2165 temp32len
= scale_expansion_zeroelim(temp16len
, temp16
, cdz
, temp32
);
2166 temp32tlen
= scale_expansion_zeroelim(temp16len
, temp16
, cdztail
, temp32t
);
2167 clen
= fast_expansion_sum_zeroelim(temp32len
, temp32
, temp32tlen
, temp32t
,
2170 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2171 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, deter
);
2173 return deter
[deterlen
- 1];
2176 REAL
orient3dadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL permanent
)
2183 INEXACT REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
, adz
, bdz
, cdz
;
2186 INEXACT REAL bdxcdy1
, cdxbdy1
, cdxady1
, adxcdy1
, adxbdy1
, bdxady1
;
2187 REAL bdxcdy0
, cdxbdy0
, cdxady0
, adxcdy0
, adxbdy0
, bdxady0
;
2188 REAL bc
[4], ca
[4], ab
[4];
2189 INEXACT REAL bc3
, ca3
, ab3
;
2190 REAL adet
[8], bdet
[8], cdet
[8];
2191 int alen
, blen
, clen
;
2194 REAL
*finnow
, *finother
, *finswap
;
2195 REAL fin1
[192], fin2
[192];
2198 REAL adxtail
, bdxtail
, cdxtail
;
2199 REAL adytail
, bdytail
, cdytail
;
2200 REAL adztail
, bdztail
, cdztail
;
2201 INEXACT REAL at_blarge
, at_clarge
;
2202 INEXACT REAL bt_clarge
, bt_alarge
;
2203 INEXACT REAL ct_alarge
, ct_blarge
;
2204 REAL at_b
[4], at_c
[4], bt_c
[4], bt_a
[4], ct_a
[4], ct_b
[4];
2205 int at_blen
, at_clen
, bt_clen
, bt_alen
, ct_alen
, ct_blen
;
2206 INEXACT REAL bdxt_cdy1
, cdxt_bdy1
, cdxt_ady1
;
2207 INEXACT REAL adxt_cdy1
, adxt_bdy1
, bdxt_ady1
;
2208 REAL bdxt_cdy0
, cdxt_bdy0
, cdxt_ady0
;
2209 REAL adxt_cdy0
, adxt_bdy0
, bdxt_ady0
;
2210 INEXACT REAL bdyt_cdx1
, cdyt_bdx1
, cdyt_adx1
;
2211 INEXACT REAL adyt_cdx1
, adyt_bdx1
, bdyt_adx1
;
2212 REAL bdyt_cdx0
, cdyt_bdx0
, cdyt_adx0
;
2213 REAL adyt_cdx0
, adyt_bdx0
, bdyt_adx0
;
2214 REAL bct
[8], cat
[8], abt
[8];
2215 int bctlen
, catlen
, abtlen
;
2216 INEXACT REAL bdxt_cdyt1
, cdxt_bdyt1
, cdxt_adyt1
;
2217 INEXACT REAL adxt_cdyt1
, adxt_bdyt1
, bdxt_adyt1
;
2218 REAL bdxt_cdyt0
, cdxt_bdyt0
, cdxt_adyt0
;
2219 REAL adxt_cdyt0
, adxt_bdyt0
, bdxt_adyt0
;
2220 REAL u
[4], v
[12], w
[16];
2222 int vlength
, wlength
;
2226 REAL avirt
, bround
, around
;
2229 REAL ahi
, alo
, bhi
, blo
;
2230 REAL err1
, err2
, err3
;
2231 INEXACT REAL _i
, _j
, _k
;
2234 adx
= REAL(pa
[0] - pd
[0]);
2235 bdx
= REAL(pb
[0] - pd
[0]);
2236 cdx
= REAL(pc
[0] - pd
[0]);
2237 ady
= REAL(pa
[1] - pd
[1]);
2238 bdy
= REAL(pb
[1] - pd
[1]);
2239 cdy
= REAL(pc
[1] - pd
[1]);
2240 adz
= REAL(pa
[2] - pd
[2]);
2241 bdz
= REAL(pb
[2] - pd
[2]);
2242 cdz
= REAL(pc
[2] - pd
[2]);
2244 Two_Product(bdx
, cdy
, bdxcdy1
, bdxcdy0
);
2245 Two_Product(cdx
, bdy
, cdxbdy1
, cdxbdy0
);
2246 Two_Two_Diff(bdxcdy1
, bdxcdy0
, cdxbdy1
, cdxbdy0
, bc3
, bc
[2], bc
[1], bc
[0]);
2248 alen
= scale_expansion_zeroelim(4, bc
, adz
, adet
);
2250 Two_Product(cdx
, ady
, cdxady1
, cdxady0
);
2251 Two_Product(adx
, cdy
, adxcdy1
, adxcdy0
);
2252 Two_Two_Diff(cdxady1
, cdxady0
, adxcdy1
, adxcdy0
, ca3
, ca
[2], ca
[1], ca
[0]);
2254 blen
= scale_expansion_zeroelim(4, ca
, bdz
, bdet
);
2256 Two_Product(adx
, bdy
, adxbdy1
, adxbdy0
);
2257 Two_Product(bdx
, ady
, bdxady1
, bdxady0
);
2258 Two_Two_Diff(adxbdy1
, adxbdy0
, bdxady1
, bdxady0
, ab3
, ab
[2], ab
[1], ab
[0]);
2260 clen
= scale_expansion_zeroelim(4, ab
, cdz
, cdet
);
2262 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2263 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, fin1
);
2265 det
= estimate(finlength
, fin1
);
2266 errbound
= o3derrboundB
* permanent
;
2267 if((det
>= errbound
) || (-det
>= errbound
))
2272 Two_Diff_Tail(pa
[0], pd
[0], adx
, adxtail
);
2273 Two_Diff_Tail(pb
[0], pd
[0], bdx
, bdxtail
);
2274 Two_Diff_Tail(pc
[0], pd
[0], cdx
, cdxtail
);
2275 Two_Diff_Tail(pa
[1], pd
[1], ady
, adytail
);
2276 Two_Diff_Tail(pb
[1], pd
[1], bdy
, bdytail
);
2277 Two_Diff_Tail(pc
[1], pd
[1], cdy
, cdytail
);
2278 Two_Diff_Tail(pa
[2], pd
[2], adz
, adztail
);
2279 Two_Diff_Tail(pb
[2], pd
[2], bdz
, bdztail
);
2280 Two_Diff_Tail(pc
[2], pd
[2], cdz
, cdztail
);
2282 if((adxtail
== 0.0) && (bdxtail
== 0.0) && (cdxtail
== 0.0)
2283 && (adytail
== 0.0) && (bdytail
== 0.0) && (cdytail
== 0.0)
2284 && (adztail
== 0.0) && (bdztail
== 0.0) && (cdztail
== 0.0))
2289 errbound
= o3derrboundC
* permanent
+ resulterrbound
* Absolute(det
);
2290 det
+= (adz
* ((bdx
* cdytail
+ cdy
* bdxtail
)
2291 - (bdy
* cdxtail
+ cdx
* bdytail
))
2292 + adztail
* (bdx
* cdy
- bdy
* cdx
))
2293 + (bdz
* ((cdx
* adytail
+ ady
* cdxtail
)
2294 - (cdy
* adxtail
+ adx
* cdytail
))
2295 + bdztail
* (cdx
* ady
- cdy
* adx
))
2296 + (cdz
* ((adx
* bdytail
+ bdy
* adxtail
)
2297 - (ady
* bdxtail
+ bdx
* adytail
))
2298 + cdztail
* (adx
* bdy
- ady
* bdx
));
2299 if((det
>= errbound
) || (-det
>= errbound
))
2319 Two_Product(negate
, bdx
, at_blarge
, at_b
[0]);
2320 at_b
[1] = at_blarge
;
2322 Two_Product(adytail
, cdx
, at_clarge
, at_c
[0]);
2323 at_c
[1] = at_clarge
;
2331 Two_Product(adxtail
, bdy
, at_blarge
, at_b
[0]);
2332 at_b
[1] = at_blarge
;
2335 Two_Product(negate
, cdy
, at_clarge
, at_c
[0]);
2336 at_c
[1] = at_clarge
;
2341 Two_Product(adxtail
, bdy
, adxt_bdy1
, adxt_bdy0
);
2342 Two_Product(adytail
, bdx
, adyt_bdx1
, adyt_bdx0
);
2343 Two_Two_Diff(adxt_bdy1
, adxt_bdy0
, adyt_bdx1
, adyt_bdx0
,
2344 at_blarge
, at_b
[2], at_b
[1], at_b
[0]);
2345 at_b
[3] = at_blarge
;
2347 Two_Product(adytail
, cdx
, adyt_cdx1
, adyt_cdx0
);
2348 Two_Product(adxtail
, cdy
, adxt_cdy1
, adxt_cdy0
);
2349 Two_Two_Diff(adyt_cdx1
, adyt_cdx0
, adxt_cdy1
, adxt_cdy0
,
2350 at_clarge
, at_c
[2], at_c
[1], at_c
[0]);
2351 at_c
[3] = at_clarge
;
2367 Two_Product(negate
, cdx
, bt_clarge
, bt_c
[0]);
2368 bt_c
[1] = bt_clarge
;
2370 Two_Product(bdytail
, adx
, bt_alarge
, bt_a
[0]);
2371 bt_a
[1] = bt_alarge
;
2379 Two_Product(bdxtail
, cdy
, bt_clarge
, bt_c
[0]);
2380 bt_c
[1] = bt_clarge
;
2383 Two_Product(negate
, ady
, bt_alarge
, bt_a
[0]);
2384 bt_a
[1] = bt_alarge
;
2389 Two_Product(bdxtail
, cdy
, bdxt_cdy1
, bdxt_cdy0
);
2390 Two_Product(bdytail
, cdx
, bdyt_cdx1
, bdyt_cdx0
);
2391 Two_Two_Diff(bdxt_cdy1
, bdxt_cdy0
, bdyt_cdx1
, bdyt_cdx0
,
2392 bt_clarge
, bt_c
[2], bt_c
[1], bt_c
[0]);
2393 bt_c
[3] = bt_clarge
;
2395 Two_Product(bdytail
, adx
, bdyt_adx1
, bdyt_adx0
);
2396 Two_Product(bdxtail
, ady
, bdxt_ady1
, bdxt_ady0
);
2397 Two_Two_Diff(bdyt_adx1
, bdyt_adx0
, bdxt_ady1
, bdxt_ady0
,
2398 bt_alarge
, bt_a
[2], bt_a
[1], bt_a
[0]);
2399 bt_a
[3] = bt_alarge
;
2415 Two_Product(negate
, adx
, ct_alarge
, ct_a
[0]);
2416 ct_a
[1] = ct_alarge
;
2418 Two_Product(cdytail
, bdx
, ct_blarge
, ct_b
[0]);
2419 ct_b
[1] = ct_blarge
;
2427 Two_Product(cdxtail
, ady
, ct_alarge
, ct_a
[0]);
2428 ct_a
[1] = ct_alarge
;
2431 Two_Product(negate
, bdy
, ct_blarge
, ct_b
[0]);
2432 ct_b
[1] = ct_blarge
;
2437 Two_Product(cdxtail
, ady
, cdxt_ady1
, cdxt_ady0
);
2438 Two_Product(cdytail
, adx
, cdyt_adx1
, cdyt_adx0
);
2439 Two_Two_Diff(cdxt_ady1
, cdxt_ady0
, cdyt_adx1
, cdyt_adx0
,
2440 ct_alarge
, ct_a
[2], ct_a
[1], ct_a
[0]);
2441 ct_a
[3] = ct_alarge
;
2443 Two_Product(cdytail
, bdx
, cdyt_bdx1
, cdyt_bdx0
);
2444 Two_Product(cdxtail
, bdy
, cdxt_bdy1
, cdxt_bdy0
);
2445 Two_Two_Diff(cdyt_bdx1
, cdyt_bdx0
, cdxt_bdy1
, cdxt_bdy0
,
2446 ct_blarge
, ct_b
[2], ct_b
[1], ct_b
[0]);
2447 ct_b
[3] = ct_blarge
;
2452 bctlen
= fast_expansion_sum_zeroelim(bt_clen
, bt_c
, ct_blen
, ct_b
, bct
);
2453 wlength
= scale_expansion_zeroelim(bctlen
, bct
, adz
, w
);
2454 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2456 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2458 catlen
= fast_expansion_sum_zeroelim(ct_alen
, ct_a
, at_clen
, at_c
, cat
);
2459 wlength
= scale_expansion_zeroelim(catlen
, cat
, bdz
, w
);
2460 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2462 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2464 abtlen
= fast_expansion_sum_zeroelim(at_blen
, at_b
, bt_alen
, bt_a
, abt
);
2465 wlength
= scale_expansion_zeroelim(abtlen
, abt
, cdz
, w
);
2466 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2468 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2472 vlength
= scale_expansion_zeroelim(4, bc
, adztail
, v
);
2473 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
2475 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2479 vlength
= scale_expansion_zeroelim(4, ca
, bdztail
, v
);
2480 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
2482 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2486 vlength
= scale_expansion_zeroelim(4, ab
, cdztail
, v
);
2487 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, vlength
, v
,
2489 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2496 Two_Product(adxtail
, bdytail
, adxt_bdyt1
, adxt_bdyt0
);
2497 Two_One_Product(adxt_bdyt1
, adxt_bdyt0
, cdz
, u3
, u
[2], u
[1], u
[0]);
2499 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2501 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2504 Two_One_Product(adxt_bdyt1
, adxt_bdyt0
, cdztail
, u3
, u
[2], u
[1], u
[0]);
2506 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2508 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2514 Two_Product(negate
, cdytail
, adxt_cdyt1
, adxt_cdyt0
);
2515 Two_One_Product(adxt_cdyt1
, adxt_cdyt0
, bdz
, u3
, u
[2], u
[1], u
[0]);
2517 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2519 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2522 Two_One_Product(adxt_cdyt1
, adxt_cdyt0
, bdztail
, u3
, u
[2], u
[1], u
[0]);
2524 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2526 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2534 Two_Product(bdxtail
, cdytail
, bdxt_cdyt1
, bdxt_cdyt0
);
2535 Two_One_Product(bdxt_cdyt1
, bdxt_cdyt0
, adz
, u3
, u
[2], u
[1], u
[0]);
2537 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2539 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2542 Two_One_Product(bdxt_cdyt1
, bdxt_cdyt0
, adztail
, u3
, u
[2], u
[1], u
[0]);
2544 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2546 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2552 Two_Product(negate
, adytail
, bdxt_adyt1
, bdxt_adyt0
);
2553 Two_One_Product(bdxt_adyt1
, bdxt_adyt0
, cdz
, u3
, u
[2], u
[1], u
[0]);
2555 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2557 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2560 Two_One_Product(bdxt_adyt1
, bdxt_adyt0
, cdztail
, u3
, u
[2], u
[1], u
[0]);
2562 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2564 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2572 Two_Product(cdxtail
, adytail
, cdxt_adyt1
, cdxt_adyt0
);
2573 Two_One_Product(cdxt_adyt1
, cdxt_adyt0
, bdz
, u3
, u
[2], u
[1], u
[0]);
2575 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2577 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2580 Two_One_Product(cdxt_adyt1
, cdxt_adyt0
, bdztail
, u3
, u
[2], u
[1], u
[0]);
2582 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2584 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2590 Two_Product(negate
, bdytail
, cdxt_bdyt1
, cdxt_bdyt0
);
2591 Two_One_Product(cdxt_bdyt1
, cdxt_bdyt0
, adz
, u3
, u
[2], u
[1], u
[0]);
2593 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2595 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2598 Two_One_Product(cdxt_bdyt1
, cdxt_bdyt0
, adztail
, u3
, u
[2], u
[1], u
[0]);
2600 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, 4, u
,
2602 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2609 wlength
= scale_expansion_zeroelim(bctlen
, bct
, adztail
, w
);
2610 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2612 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2616 wlength
= scale_expansion_zeroelim(catlen
, cat
, bdztail
, w
);
2617 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2619 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2623 wlength
= scale_expansion_zeroelim(abtlen
, abt
, cdztail
, w
);
2624 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, wlength
, w
,
2626 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
2629 return finnow
[finlength
- 1];
2632 REAL
OSG::orient3d(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2638 REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
, adz
, bdz
, cdz
;
2639 REAL bdxcdy
, cdxbdy
, cdxady
, adxcdy
, adxbdy
, bdxady
;
2641 REAL permanent
, errbound
;
2644 OSG_FPU_ROUND_DOUBLE
;
2646 adx
= pa
[0] - pd
[0];
2647 bdx
= pb
[0] - pd
[0];
2648 cdx
= pc
[0] - pd
[0];
2649 ady
= pa
[1] - pd
[1];
2650 bdy
= pb
[1] - pd
[1];
2651 cdy
= pc
[1] - pd
[1];
2652 adz
= pa
[2] - pd
[2];
2653 bdz
= pb
[2] - pd
[2];
2654 cdz
= pc
[2] - pd
[2];
2665 det
= adz
* (bdxcdy
- cdxbdy
)
2666 + bdz
* (cdxady
- adxcdy
)
2667 + cdz
* (adxbdy
- bdxady
);
2669 permanent
= (Absolute(bdxcdy
) + Absolute(cdxbdy
)) * Absolute(adz
)
2670 + (Absolute(cdxady
) + Absolute(adxcdy
)) * Absolute(bdz
)
2671 + (Absolute(adxbdy
) + Absolute(bdxady
)) * Absolute(cdz
);
2672 errbound
= o3derrboundA
* permanent
;
2673 if((det
> errbound
) || (-det
> errbound
))
2679 orient
= orient3dadapt(pa
, pb
, pc
, pd
, permanent
);
2684 /*****************************************************************************/
2686 /* incirclefast() Approximate 2D incircle test. Nonrobust. */
2687 /* incircleexact() Exact 2D incircle test. Robust. */
2688 /* incircleslow() Another exact 2D incircle test. Robust. */
2689 /* incircle() Adaptive exact 2D incircle test. Robust. */
2691 /* Return a positive value if the point pd lies inside the */
2692 /* circle passing through pa, pb, and pc; a negative value if */
2693 /* it lies outside; and zero if the four points are cocircular.*/
2694 /* The points pa, pb, and pc must be in counterclockwise */
2695 /* order, or the sign of the result will be reversed. */
2697 /* Only the first and last routine should be used; the middle two are for */
2700 /* The last three use exact arithmetic to ensure a correct answer. The */
2701 /* result returned is the determinant of a matrix. In incircle() only, */
2702 /* this determinant is computed adaptively, in the sense that exact */
2703 /* arithmetic is used only to the degree it is needed to ensure that the */
2704 /* returned value has the correct sign. Hence, incircle() is usually quite */
2705 /* fast, but will run more slowly when the input points are cocircular or */
2708 /*****************************************************************************/
2710 REAL
incirclefast(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2716 REAL adx
, ady
, bdx
, bdy
, cdx
, cdy
;
2717 REAL abdet
, bcdet
, cadet
;
2718 REAL alift
, blift
, clift
;
2720 adx
= pa
[0] - pd
[0];
2721 ady
= pa
[1] - pd
[1];
2722 bdx
= pb
[0] - pd
[0];
2723 bdy
= pb
[1] - pd
[1];
2724 cdx
= pc
[0] - pd
[0];
2725 cdy
= pc
[1] - pd
[1];
2727 abdet
= adx
* bdy
- bdx
* ady
;
2728 bcdet
= bdx
* cdy
- cdx
* bdy
;
2729 cadet
= cdx
* ady
- adx
* cdy
;
2730 alift
= adx
* adx
+ ady
* ady
;
2731 blift
= bdx
* bdx
+ bdy
* bdy
;
2732 clift
= cdx
* cdx
+ cdy
* cdy
;
2734 return alift
* bcdet
+ blift
* cadet
+ clift
* abdet
;
2737 REAL
incircleexact(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2743 INEXACT REAL axby1
, bxcy1
, cxdy1
, dxay1
, axcy1
, bxdy1
;
2744 INEXACT REAL bxay1
, cxby1
, dxcy1
, axdy1
, cxay1
, dxby1
;
2745 REAL axby0
, bxcy0
, cxdy0
, dxay0
, axcy0
, bxdy0
;
2746 REAL bxay0
, cxby0
, dxcy0
, axdy0
, cxay0
, dxby0
;
2747 REAL ab
[4], bc
[4], cd
[4], da
[4], ac
[4], bd
[4];
2750 REAL abc
[12], bcd
[12], cda
[12], dab
[12];
2751 int abclen
, bcdlen
, cdalen
, dablen
;
2752 REAL det24x
[24], det24y
[24], det48x
[48], det48y
[48];
2754 REAL adet
[96], bdet
[96], cdet
[96], ddet
[96];
2755 int alen
, blen
, clen
, dlen
;
2756 REAL abdet
[192], cddet
[192];
2763 REAL avirt
, bround
, around
;
2766 REAL ahi
, alo
, bhi
, blo
;
2767 REAL err1
, err2
, err3
;
2768 INEXACT REAL _i
, _j
;
2771 Two_Product(pa
[0], pb
[1], axby1
, axby0
);
2772 Two_Product(pb
[0], pa
[1], bxay1
, bxay0
);
2773 Two_Two_Diff(axby1
, axby0
, bxay1
, bxay0
, ab
[3], ab
[2], ab
[1], ab
[0]);
2775 Two_Product(pb
[0], pc
[1], bxcy1
, bxcy0
);
2776 Two_Product(pc
[0], pb
[1], cxby1
, cxby0
);
2777 Two_Two_Diff(bxcy1
, bxcy0
, cxby1
, cxby0
, bc
[3], bc
[2], bc
[1], bc
[0]);
2779 Two_Product(pc
[0], pd
[1], cxdy1
, cxdy0
);
2780 Two_Product(pd
[0], pc
[1], dxcy1
, dxcy0
);
2781 Two_Two_Diff(cxdy1
, cxdy0
, dxcy1
, dxcy0
, cd
[3], cd
[2], cd
[1], cd
[0]);
2783 Two_Product(pd
[0], pa
[1], dxay1
, dxay0
);
2784 Two_Product(pa
[0], pd
[1], axdy1
, axdy0
);
2785 Two_Two_Diff(dxay1
, dxay0
, axdy1
, axdy0
, da
[3], da
[2], da
[1], da
[0]);
2787 Two_Product(pa
[0], pc
[1], axcy1
, axcy0
);
2788 Two_Product(pc
[0], pa
[1], cxay1
, cxay0
);
2789 Two_Two_Diff(axcy1
, axcy0
, cxay1
, cxay0
, ac
[3], ac
[2], ac
[1], ac
[0]);
2791 Two_Product(pb
[0], pd
[1], bxdy1
, bxdy0
);
2792 Two_Product(pd
[0], pb
[1], dxby1
, dxby0
);
2793 Two_Two_Diff(bxdy1
, bxdy0
, dxby1
, dxby0
, bd
[3], bd
[2], bd
[1], bd
[0]);
2795 templen
= fast_expansion_sum_zeroelim(4, cd
, 4, da
, temp8
);
2796 cdalen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, ac
, cda
);
2797 templen
= fast_expansion_sum_zeroelim(4, da
, 4, ab
, temp8
);
2798 dablen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, bd
, dab
);
2800 for(i
= 0; i
< 4; i
++)
2806 templen
= fast_expansion_sum_zeroelim(4, ab
, 4, bc
, temp8
);
2807 abclen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, ac
, abc
);
2808 templen
= fast_expansion_sum_zeroelim(4, bc
, 4, cd
, temp8
);
2809 bcdlen
= fast_expansion_sum_zeroelim(templen
, temp8
, 4, bd
, bcd
);
2811 xlen
= scale_expansion_zeroelim(bcdlen
, bcd
, pa
[0], det24x
);
2812 xlen
= scale_expansion_zeroelim(xlen
, det24x
, pa
[0], det48x
);
2813 ylen
= scale_expansion_zeroelim(bcdlen
, bcd
, pa
[1], det24y
);
2814 ylen
= scale_expansion_zeroelim(ylen
, det24y
, pa
[1], det48y
);
2815 alen
= fast_expansion_sum_zeroelim(xlen
, det48x
, ylen
, det48y
, adet
);
2817 xlen
= scale_expansion_zeroelim(cdalen
, cda
, pb
[0], det24x
);
2818 xlen
= scale_expansion_zeroelim(xlen
, det24x
, -pb
[0], det48x
);
2819 ylen
= scale_expansion_zeroelim(cdalen
, cda
, pb
[1], det24y
);
2820 ylen
= scale_expansion_zeroelim(ylen
, det24y
, -pb
[1], det48y
);
2821 blen
= fast_expansion_sum_zeroelim(xlen
, det48x
, ylen
, det48y
, bdet
);
2823 xlen
= scale_expansion_zeroelim(dablen
, dab
, pc
[0], det24x
);
2824 xlen
= scale_expansion_zeroelim(xlen
, det24x
, pc
[0], det48x
);
2825 ylen
= scale_expansion_zeroelim(dablen
, dab
, pc
[1], det24y
);
2826 ylen
= scale_expansion_zeroelim(ylen
, det24y
, pc
[1], det48y
);
2827 clen
= fast_expansion_sum_zeroelim(xlen
, det48x
, ylen
, det48y
, cdet
);
2829 xlen
= scale_expansion_zeroelim(abclen
, abc
, pd
[0], det24x
);
2830 xlen
= scale_expansion_zeroelim(xlen
, det24x
, -pd
[0], det48x
);
2831 ylen
= scale_expansion_zeroelim(abclen
, abc
, pd
[1], det24y
);
2832 ylen
= scale_expansion_zeroelim(ylen
, det24y
, -pd
[1], det48y
);
2833 dlen
= fast_expansion_sum_zeroelim(xlen
, det48x
, ylen
, det48y
, ddet
);
2835 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
2836 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
2837 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdlen
, cddet
, deter
);
2839 return deter
[deterlen
- 1];
2842 REAL
incircleslow(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
2848 INEXACT REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
;
2849 REAL adxtail
, bdxtail
, cdxtail
;
2850 REAL adytail
, bdytail
, cdytail
;
2851 REAL negate
, negatetail
;
2852 INEXACT REAL axby7
, bxcy7
, axcy7
, bxay7
, cxby7
, cxay7
;
2853 REAL axby
[8], bxcy
[8], axcy
[8], bxay
[8], cxby
[8], cxay
[8];
2856 REAL detx
[32], detxx
[64], detxt
[32], detxxt
[64], detxtxt
[64];
2857 int xlen
, xxlen
, xtlen
, xxtlen
, xtxtlen
;
2858 REAL x1
[128], x2
[192];
2860 REAL dety
[32], detyy
[64], detyt
[32], detyyt
[64], detytyt
[64];
2861 int ylen
, yylen
, ytlen
, yytlen
, ytytlen
;
2862 REAL y1
[128], y2
[192];
2864 REAL adet
[384], bdet
[384], cdet
[384], abdet
[768], deter
[1152];
2865 int alen
, blen
, clen
, ablen
, deterlen
;
2869 REAL avirt
, bround
, around
;
2872 REAL a0hi
, a0lo
, a1hi
, a1lo
, bhi
, blo
;
2873 REAL err1
, err2
, err3
;
2874 INEXACT REAL _i
, _j
, _k
, _l
, _m
, _n
;
2877 Two_Diff(pa
[0], pd
[0], adx
, adxtail
);
2878 Two_Diff(pa
[1], pd
[1], ady
, adytail
);
2879 Two_Diff(pb
[0], pd
[0], bdx
, bdxtail
);
2880 Two_Diff(pb
[1], pd
[1], bdy
, bdytail
);
2881 Two_Diff(pc
[0], pd
[0], cdx
, cdxtail
);
2882 Two_Diff(pc
[1], pd
[1], cdy
, cdytail
);
2884 Two_Two_Product(adx
, adxtail
, bdy
, bdytail
,
2885 axby7
, axby
[6], axby
[5], axby
[4],
2886 axby
[3], axby
[2], axby
[1], axby
[0]);
2889 negatetail
= -adytail
;
2890 Two_Two_Product(bdx
, bdxtail
, negate
, negatetail
,
2891 bxay7
, bxay
[6], bxay
[5], bxay
[4],
2892 bxay
[3], bxay
[2], bxay
[1], bxay
[0]);
2894 Two_Two_Product(bdx
, bdxtail
, cdy
, cdytail
,
2895 bxcy7
, bxcy
[6], bxcy
[5], bxcy
[4],
2896 bxcy
[3], bxcy
[2], bxcy
[1], bxcy
[0]);
2899 negatetail
= -bdytail
;
2900 Two_Two_Product(cdx
, cdxtail
, negate
, negatetail
,
2901 cxby7
, cxby
[6], cxby
[5], cxby
[4],
2902 cxby
[3], cxby
[2], cxby
[1], cxby
[0]);
2904 Two_Two_Product(cdx
, cdxtail
, ady
, adytail
,
2905 cxay7
, cxay
[6], cxay
[5], cxay
[4],
2906 cxay
[3], cxay
[2], cxay
[1], cxay
[0]);
2909 negatetail
= -cdytail
;
2910 Two_Two_Product(adx
, adxtail
, negate
, negatetail
,
2911 axcy7
, axcy
[6], axcy
[5], axcy
[4],
2912 axcy
[3], axcy
[2], axcy
[1], axcy
[0]);
2916 temp16len
= fast_expansion_sum_zeroelim(8, bxcy
, 8, cxby
, temp16
);
2918 xlen
= scale_expansion_zeroelim(temp16len
, temp16
, adx
, detx
);
2919 xxlen
= scale_expansion_zeroelim(xlen
, detx
, adx
, detxx
);
2920 xtlen
= scale_expansion_zeroelim(temp16len
, temp16
, adxtail
, detxt
);
2921 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, adx
, detxxt
);
2923 for(i
= 0; i
< xxtlen
; i
++)
2928 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, adxtail
, detxtxt
);
2929 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
2930 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
2932 ylen
= scale_expansion_zeroelim(temp16len
, temp16
, ady
, dety
);
2933 yylen
= scale_expansion_zeroelim(ylen
, dety
, ady
, detyy
);
2934 ytlen
= scale_expansion_zeroelim(temp16len
, temp16
, adytail
, detyt
);
2935 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, ady
, detyyt
);
2937 for(i
= 0; i
< yytlen
; i
++)
2942 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, adytail
, detytyt
);
2943 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
2944 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
2946 alen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, adet
);
2949 temp16len
= fast_expansion_sum_zeroelim(8, cxay
, 8, axcy
, temp16
);
2951 xlen
= scale_expansion_zeroelim(temp16len
, temp16
, bdx
, detx
);
2952 xxlen
= scale_expansion_zeroelim(xlen
, detx
, bdx
, detxx
);
2953 xtlen
= scale_expansion_zeroelim(temp16len
, temp16
, bdxtail
, detxt
);
2954 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, bdx
, detxxt
);
2956 for(i
= 0; i
< xxtlen
; i
++)
2961 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, bdxtail
, detxtxt
);
2962 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
2963 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
2965 ylen
= scale_expansion_zeroelim(temp16len
, temp16
, bdy
, dety
);
2966 yylen
= scale_expansion_zeroelim(ylen
, dety
, bdy
, detyy
);
2967 ytlen
= scale_expansion_zeroelim(temp16len
, temp16
, bdytail
, detyt
);
2968 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, bdy
, detyyt
);
2970 for(i
= 0; i
< yytlen
; i
++)
2975 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, bdytail
, detytyt
);
2976 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
2977 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
2979 blen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, bdet
);
2982 temp16len
= fast_expansion_sum_zeroelim(8, axby
, 8, bxay
, temp16
);
2984 xlen
= scale_expansion_zeroelim(temp16len
, temp16
, cdx
, detx
);
2985 xxlen
= scale_expansion_zeroelim(xlen
, detx
, cdx
, detxx
);
2986 xtlen
= scale_expansion_zeroelim(temp16len
, temp16
, cdxtail
, detxt
);
2987 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, cdx
, detxxt
);
2989 for(i
= 0; i
< xxtlen
; i
++)
2994 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, cdxtail
, detxtxt
);
2995 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
2996 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
2998 ylen
= scale_expansion_zeroelim(temp16len
, temp16
, cdy
, dety
);
2999 yylen
= scale_expansion_zeroelim(ylen
, dety
, cdy
, detyy
);
3000 ytlen
= scale_expansion_zeroelim(temp16len
, temp16
, cdytail
, detyt
);
3001 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, cdy
, detyyt
);
3003 for(i
= 0; i
< yytlen
; i
++)
3008 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, cdytail
, detytyt
);
3009 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
3010 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
3012 clen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, cdet
);
3014 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
3015 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, deter
);
3017 return deter
[deterlen
- 1];
3020 REAL
incircleadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL permanent
)
3027 INEXACT REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
;
3030 INEXACT REAL bdxcdy1
, cdxbdy1
, cdxady1
, adxcdy1
, adxbdy1
, bdxady1
;
3031 REAL bdxcdy0
, cdxbdy0
, cdxady0
, adxcdy0
, adxbdy0
, bdxady0
;
3032 REAL bc
[4], ca
[4], ab
[4];
3033 INEXACT REAL bc3
, ca3
, ab3
;
3034 REAL axbc
[8], axxbc
[16], aybc
[8], ayybc
[16], adet
[32];
3035 int axbclen
, axxbclen
, aybclen
, ayybclen
, alen
;
3036 REAL bxca
[8], bxxca
[16], byca
[8], byyca
[16], bdet
[32];
3037 int bxcalen
, bxxcalen
, bycalen
, byycalen
, blen
;
3038 REAL cxab
[8], cxxab
[16], cyab
[8], cyyab
[16], cdet
[32];
3039 int cxablen
, cxxablen
, cyablen
, cyyablen
, clen
;
3042 REAL fin1
[1152], fin2
[1152];
3043 REAL
*finnow
, *finother
, *finswap
;
3046 REAL adxtail
, bdxtail
, cdxtail
, adytail
, bdytail
, cdytail
;
3047 INEXACT REAL adxadx1
, adyady1
, bdxbdx1
, bdybdy1
, cdxcdx1
, cdycdy1
;
3048 REAL adxadx0
, adyady0
, bdxbdx0
, bdybdy0
, cdxcdx0
, cdycdy0
;
3049 REAL aa
[4], bb
[4], cc
[4];
3050 INEXACT REAL aa3
, bb3
, cc3
;
3051 INEXACT REAL ti1
, tj1
;
3054 INEXACT REAL u3
, v3
;
3055 REAL temp8
[8], temp16a
[16], temp16b
[16], temp16c
[16];
3056 REAL temp32a
[32], temp32b
[32], temp48
[48], temp64
[64];
3057 int temp8len
, temp16alen
, temp16blen
, temp16clen
;
3058 int temp32alen
, temp32blen
, temp48len
, temp64len
;
3059 REAL axtbb
[8], axtcc
[8], aytbb
[8], aytcc
[8];
3060 int axtbblen
, axtcclen
, aytbblen
, aytcclen
;
3061 REAL bxtaa
[8], bxtcc
[8], bytaa
[8], bytcc
[8];
3062 int bxtaalen
, bxtcclen
, bytaalen
, bytcclen
;
3063 REAL cxtaa
[8], cxtbb
[8], cytaa
[8], cytbb
[8];
3064 int cxtaalen
, cxtbblen
, cytaalen
, cytbblen
;
3065 REAL axtbc
[8], aytbc
[8], bxtca
[8], bytca
[8], cxtab
[8], cytab
[8];
3066 int axtbclen
= 0, aytbclen
= 0, bxtcalen
= 0, bytcalen
= 0, cxtablen
= 0, cytablen
= 0;
3067 REAL axtbct
[16], aytbct
[16], bxtcat
[16], bytcat
[16], cxtabt
[16], cytabt
[16];
3068 int axtbctlen
, aytbctlen
, bxtcatlen
, bytcatlen
, cxtabtlen
, cytabtlen
;
3069 REAL axtbctt
[8], aytbctt
[8], bxtcatt
[8];
3070 REAL bytcatt
[8], cxtabtt
[8], cytabtt
[8];
3071 int axtbcttlen
, aytbcttlen
, bxtcattlen
, bytcattlen
, cxtabttlen
, cytabttlen
;
3072 REAL abt
[8], bct
[8], cat
[8];
3073 int abtlen
, bctlen
, catlen
;
3074 REAL abtt
[4], bctt
[4], catt
[4];
3075 int abttlen
, bcttlen
, cattlen
;
3076 INEXACT REAL abtt3
, bctt3
, catt3
;
3080 REAL avirt
, bround
, around
;
3083 REAL ahi
, alo
, bhi
, blo
;
3084 REAL err1
, err2
, err3
;
3085 INEXACT REAL _i
, _j
;
3088 adx
= REAL(pa
[0] - pd
[0]);
3089 bdx
= REAL(pb
[0] - pd
[0]);
3090 cdx
= REAL(pc
[0] - pd
[0]);
3091 ady
= REAL(pa
[1] - pd
[1]);
3092 bdy
= REAL(pb
[1] - pd
[1]);
3093 cdy
= REAL(pc
[1] - pd
[1]);
3095 Two_Product(bdx
, cdy
, bdxcdy1
, bdxcdy0
);
3096 Two_Product(cdx
, bdy
, cdxbdy1
, cdxbdy0
);
3097 Two_Two_Diff(bdxcdy1
, bdxcdy0
, cdxbdy1
, cdxbdy0
, bc3
, bc
[2], bc
[1], bc
[0]);
3099 axbclen
= scale_expansion_zeroelim(4, bc
, adx
, axbc
);
3100 axxbclen
= scale_expansion_zeroelim(axbclen
, axbc
, adx
, axxbc
);
3101 aybclen
= scale_expansion_zeroelim(4, bc
, ady
, aybc
);
3102 ayybclen
= scale_expansion_zeroelim(aybclen
, aybc
, ady
, ayybc
);
3103 alen
= fast_expansion_sum_zeroelim(axxbclen
, axxbc
, ayybclen
, ayybc
, adet
);
3105 Two_Product(cdx
, ady
, cdxady1
, cdxady0
);
3106 Two_Product(adx
, cdy
, adxcdy1
, adxcdy0
);
3107 Two_Two_Diff(cdxady1
, cdxady0
, adxcdy1
, adxcdy0
, ca3
, ca
[2], ca
[1], ca
[0]);
3109 bxcalen
= scale_expansion_zeroelim(4, ca
, bdx
, bxca
);
3110 bxxcalen
= scale_expansion_zeroelim(bxcalen
, bxca
, bdx
, bxxca
);
3111 bycalen
= scale_expansion_zeroelim(4, ca
, bdy
, byca
);
3112 byycalen
= scale_expansion_zeroelim(bycalen
, byca
, bdy
, byyca
);
3113 blen
= fast_expansion_sum_zeroelim(bxxcalen
, bxxca
, byycalen
, byyca
, bdet
);
3115 Two_Product(adx
, bdy
, adxbdy1
, adxbdy0
);
3116 Two_Product(bdx
, ady
, bdxady1
, bdxady0
);
3117 Two_Two_Diff(adxbdy1
, adxbdy0
, bdxady1
, bdxady0
, ab3
, ab
[2], ab
[1], ab
[0]);
3119 cxablen
= scale_expansion_zeroelim(4, ab
, cdx
, cxab
);
3120 cxxablen
= scale_expansion_zeroelim(cxablen
, cxab
, cdx
, cxxab
);
3121 cyablen
= scale_expansion_zeroelim(4, ab
, cdy
, cyab
);
3122 cyyablen
= scale_expansion_zeroelim(cyablen
, cyab
, cdy
, cyyab
);
3123 clen
= fast_expansion_sum_zeroelim(cxxablen
, cxxab
, cyyablen
, cyyab
, cdet
);
3125 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
3126 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, clen
, cdet
, fin1
);
3128 det
= estimate(finlength
, fin1
);
3129 errbound
= iccerrboundB
* permanent
;
3130 if((det
>= errbound
) || (-det
>= errbound
))
3135 Two_Diff_Tail(pa
[0], pd
[0], adx
, adxtail
);
3136 Two_Diff_Tail(pa
[1], pd
[1], ady
, adytail
);
3137 Two_Diff_Tail(pb
[0], pd
[0], bdx
, bdxtail
);
3138 Two_Diff_Tail(pb
[1], pd
[1], bdy
, bdytail
);
3139 Two_Diff_Tail(pc
[0], pd
[0], cdx
, cdxtail
);
3140 Two_Diff_Tail(pc
[1], pd
[1], cdy
, cdytail
);
3141 if((adxtail
== 0.0) && (bdxtail
== 0.0) && (cdxtail
== 0.0)
3142 && (adytail
== 0.0) && (bdytail
== 0.0) && (cdytail
== 0.0))
3147 errbound
= iccerrboundC
* permanent
+ resulterrbound
* Absolute(det
);
3148 det
+= ((adx
* adx
+ ady
* ady
) * ((bdx
* cdytail
+ cdy
* bdxtail
)
3149 - (bdy
* cdxtail
+ cdx
* bdytail
))
3150 + 2.0 * (adx
* adxtail
+ ady
* adytail
) * (bdx
* cdy
- bdy
* cdx
))
3151 + ((bdx
* bdx
+ bdy
* bdy
) * ((cdx
* adytail
+ ady
* cdxtail
)
3152 - (cdy
* adxtail
+ adx
* cdytail
))
3153 + 2.0 * (bdx
* bdxtail
+ bdy
* bdytail
) * (cdx
* ady
- cdy
* adx
))
3154 + ((cdx
* cdx
+ cdy
* cdy
) * ((adx
* bdytail
+ bdy
* adxtail
)
3155 - (ady
* bdxtail
+ bdx
* adytail
))
3156 + 2.0 * (cdx
* cdxtail
+ cdy
* cdytail
) * (adx
* bdy
- ady
* bdx
));
3157 if((det
>= errbound
) || (-det
>= errbound
))
3165 if((bdxtail
!= 0.0) || (bdytail
!= 0.0)
3166 || (cdxtail
!= 0.0) || (cdytail
!= 0.0))
3168 Square(adx
, adxadx1
, adxadx0
);
3169 Square(ady
, adyady1
, adyady0
);
3170 Two_Two_Sum(adxadx1
, adxadx0
, adyady1
, adyady0
, aa3
, aa
[2], aa
[1], aa
[0]);
3173 if((cdxtail
!= 0.0) || (cdytail
!= 0.0)
3174 || (adxtail
!= 0.0) || (adytail
!= 0.0))
3176 Square(bdx
, bdxbdx1
, bdxbdx0
);
3177 Square(bdy
, bdybdy1
, bdybdy0
);
3178 Two_Two_Sum(bdxbdx1
, bdxbdx0
, bdybdy1
, bdybdy0
, bb3
, bb
[2], bb
[1], bb
[0]);
3181 if((adxtail
!= 0.0) || (adytail
!= 0.0)
3182 || (bdxtail
!= 0.0) || (bdytail
!= 0.0))
3184 Square(cdx
, cdxcdx1
, cdxcdx0
);
3185 Square(cdy
, cdycdy1
, cdycdy0
);
3186 Two_Two_Sum(cdxcdx1
, cdxcdx0
, cdycdy1
, cdycdy0
, cc3
, cc
[2], cc
[1], cc
[0]);
3192 axtbclen
= scale_expansion_zeroelim(4, bc
, adxtail
, axtbc
);
3193 temp16alen
= scale_expansion_zeroelim(axtbclen
, axtbc
, 2.0 * adx
,
3196 axtcclen
= scale_expansion_zeroelim(4, cc
, adxtail
, axtcc
);
3197 temp16blen
= scale_expansion_zeroelim(axtcclen
, axtcc
, bdy
, temp16b
);
3199 axtbblen
= scale_expansion_zeroelim(4, bb
, adxtail
, axtbb
);
3200 temp16clen
= scale_expansion_zeroelim(axtbblen
, axtbb
, -cdy
, temp16c
);
3202 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3203 temp16blen
, temp16b
, temp32a
);
3204 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3205 temp32alen
, temp32a
, temp48
);
3206 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3208 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3212 aytbclen
= scale_expansion_zeroelim(4, bc
, adytail
, aytbc
);
3213 temp16alen
= scale_expansion_zeroelim(aytbclen
, aytbc
, 2.0 * ady
,
3216 aytbblen
= scale_expansion_zeroelim(4, bb
, adytail
, aytbb
);
3217 temp16blen
= scale_expansion_zeroelim(aytbblen
, aytbb
, cdx
, temp16b
);
3219 aytcclen
= scale_expansion_zeroelim(4, cc
, adytail
, aytcc
);
3220 temp16clen
= scale_expansion_zeroelim(aytcclen
, aytcc
, -bdx
, temp16c
);
3222 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3223 temp16blen
, temp16b
, temp32a
);
3224 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3225 temp32alen
, temp32a
, temp48
);
3226 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3228 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3232 bxtcalen
= scale_expansion_zeroelim(4, ca
, bdxtail
, bxtca
);
3233 temp16alen
= scale_expansion_zeroelim(bxtcalen
, bxtca
, 2.0 * bdx
,
3236 bxtaalen
= scale_expansion_zeroelim(4, aa
, bdxtail
, bxtaa
);
3237 temp16blen
= scale_expansion_zeroelim(bxtaalen
, bxtaa
, cdy
, temp16b
);
3239 bxtcclen
= scale_expansion_zeroelim(4, cc
, bdxtail
, bxtcc
);
3240 temp16clen
= scale_expansion_zeroelim(bxtcclen
, bxtcc
, -ady
, temp16c
);
3242 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3243 temp16blen
, temp16b
, temp32a
);
3244 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3245 temp32alen
, temp32a
, temp48
);
3246 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3248 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3252 bytcalen
= scale_expansion_zeroelim(4, ca
, bdytail
, bytca
);
3253 temp16alen
= scale_expansion_zeroelim(bytcalen
, bytca
, 2.0 * bdy
,
3256 bytcclen
= scale_expansion_zeroelim(4, cc
, bdytail
, bytcc
);
3257 temp16blen
= scale_expansion_zeroelim(bytcclen
, bytcc
, adx
, temp16b
);
3259 bytaalen
= scale_expansion_zeroelim(4, aa
, bdytail
, bytaa
);
3260 temp16clen
= scale_expansion_zeroelim(bytaalen
, bytaa
, -cdx
, temp16c
);
3262 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3263 temp16blen
, temp16b
, temp32a
);
3264 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3265 temp32alen
, temp32a
, temp48
);
3266 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3268 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3272 cxtablen
= scale_expansion_zeroelim(4, ab
, cdxtail
, cxtab
);
3273 temp16alen
= scale_expansion_zeroelim(cxtablen
, cxtab
, 2.0 * cdx
,
3276 cxtbblen
= scale_expansion_zeroelim(4, bb
, cdxtail
, cxtbb
);
3277 temp16blen
= scale_expansion_zeroelim(cxtbblen
, cxtbb
, ady
, temp16b
);
3279 cxtaalen
= scale_expansion_zeroelim(4, aa
, cdxtail
, cxtaa
);
3280 temp16clen
= scale_expansion_zeroelim(cxtaalen
, cxtaa
, -bdy
, temp16c
);
3282 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3283 temp16blen
, temp16b
, temp32a
);
3284 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3285 temp32alen
, temp32a
, temp48
);
3286 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3288 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3292 cytablen
= scale_expansion_zeroelim(4, ab
, cdytail
, cytab
);
3293 temp16alen
= scale_expansion_zeroelim(cytablen
, cytab
, 2.0 * cdy
,
3296 cytaalen
= scale_expansion_zeroelim(4, aa
, cdytail
, cytaa
);
3297 temp16blen
= scale_expansion_zeroelim(cytaalen
, cytaa
, bdx
, temp16b
);
3299 cytbblen
= scale_expansion_zeroelim(4, bb
, cdytail
, cytbb
);
3300 temp16clen
= scale_expansion_zeroelim(cytbblen
, cytbb
, -adx
, temp16c
);
3302 temp32alen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3303 temp16blen
, temp16b
, temp32a
);
3304 temp48len
= fast_expansion_sum_zeroelim(temp16clen
, temp16c
,
3305 temp32alen
, temp32a
, temp48
);
3306 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3308 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3311 if((adxtail
!= 0.0) || (adytail
!= 0.0))
3313 if((bdxtail
!= 0.0) || (bdytail
!= 0.0)
3314 || (cdxtail
!= 0.0) || (cdytail
!= 0.0))
3316 Two_Product(bdxtail
, cdy
, ti1
, ti0
);
3317 Two_Product(bdx
, cdytail
, tj1
, tj0
);
3318 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
3321 Two_Product(cdxtail
, negate
, ti1
, ti0
);
3323 Two_Product(cdx
, negate
, tj1
, tj0
);
3324 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
3326 bctlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, bct
);
3328 Two_Product(bdxtail
, cdytail
, ti1
, ti0
);
3329 Two_Product(cdxtail
, bdytail
, tj1
, tj0
);
3330 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, bctt3
, bctt
[2], bctt
[1], bctt
[0]);
3344 temp16alen
= scale_expansion_zeroelim(axtbclen
, axtbc
, adxtail
, temp16a
);
3345 axtbctlen
= scale_expansion_zeroelim(bctlen
, bct
, adxtail
, axtbct
);
3346 temp32alen
= scale_expansion_zeroelim(axtbctlen
, axtbct
, 2.0 * adx
,
3348 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3349 temp32alen
, temp32a
, temp48
);
3350 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3352 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3355 temp8len
= scale_expansion_zeroelim(4, cc
, adxtail
, temp8
);
3356 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, bdytail
,
3358 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3360 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3364 temp8len
= scale_expansion_zeroelim(4, bb
, -adxtail
, temp8
);
3365 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, cdytail
,
3367 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3369 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3372 temp32alen
= scale_expansion_zeroelim(axtbctlen
, axtbct
, adxtail
,
3374 axtbcttlen
= scale_expansion_zeroelim(bcttlen
, bctt
, adxtail
, axtbctt
);
3375 temp16alen
= scale_expansion_zeroelim(axtbcttlen
, axtbctt
, 2.0 * adx
,
3377 temp16blen
= scale_expansion_zeroelim(axtbcttlen
, axtbctt
, adxtail
,
3379 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3380 temp16blen
, temp16b
, temp32b
);
3381 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3382 temp32blen
, temp32b
, temp64
);
3383 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3385 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3389 temp16alen
= scale_expansion_zeroelim(aytbclen
, aytbc
, adytail
, temp16a
);
3390 aytbctlen
= scale_expansion_zeroelim(bctlen
, bct
, adytail
, aytbct
);
3391 temp32alen
= scale_expansion_zeroelim(aytbctlen
, aytbct
, 2.0 * ady
,
3393 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3394 temp32alen
, temp32a
, temp48
);
3395 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3397 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3400 temp32alen
= scale_expansion_zeroelim(aytbctlen
, aytbct
, adytail
,
3402 aytbcttlen
= scale_expansion_zeroelim(bcttlen
, bctt
, adytail
, aytbctt
);
3403 temp16alen
= scale_expansion_zeroelim(aytbcttlen
, aytbctt
, 2.0 * ady
,
3405 temp16blen
= scale_expansion_zeroelim(aytbcttlen
, aytbctt
, adytail
,
3407 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3408 temp16blen
, temp16b
, temp32b
);
3409 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3410 temp32blen
, temp32b
, temp64
);
3411 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3413 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3416 if((bdxtail
!= 0.0) || (bdytail
!= 0.0))
3418 if((cdxtail
!= 0.0) || (cdytail
!= 0.0)
3419 || (adxtail
!= 0.0) || (adytail
!= 0.0))
3421 Two_Product(cdxtail
, ady
, ti1
, ti0
);
3422 Two_Product(cdx
, adytail
, tj1
, tj0
);
3423 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
3426 Two_Product(adxtail
, negate
, ti1
, ti0
);
3428 Two_Product(adx
, negate
, tj1
, tj0
);
3429 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
3431 catlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, cat
);
3433 Two_Product(cdxtail
, adytail
, ti1
, ti0
);
3434 Two_Product(adxtail
, cdytail
, tj1
, tj0
);
3435 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, catt3
, catt
[2], catt
[1], catt
[0]);
3449 temp16alen
= scale_expansion_zeroelim(bxtcalen
, bxtca
, bdxtail
, temp16a
);
3450 bxtcatlen
= scale_expansion_zeroelim(catlen
, cat
, bdxtail
, bxtcat
);
3451 temp32alen
= scale_expansion_zeroelim(bxtcatlen
, bxtcat
, 2.0 * bdx
,
3453 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3454 temp32alen
, temp32a
, temp48
);
3455 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3457 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3460 temp8len
= scale_expansion_zeroelim(4, aa
, bdxtail
, temp8
);
3461 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, cdytail
,
3463 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3465 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3469 temp8len
= scale_expansion_zeroelim(4, cc
, -bdxtail
, temp8
);
3470 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, adytail
,
3472 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3474 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3477 temp32alen
= scale_expansion_zeroelim(bxtcatlen
, bxtcat
, bdxtail
,
3479 bxtcattlen
= scale_expansion_zeroelim(cattlen
, catt
, bdxtail
, bxtcatt
);
3480 temp16alen
= scale_expansion_zeroelim(bxtcattlen
, bxtcatt
, 2.0 * bdx
,
3482 temp16blen
= scale_expansion_zeroelim(bxtcattlen
, bxtcatt
, bdxtail
,
3484 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3485 temp16blen
, temp16b
, temp32b
);
3486 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3487 temp32blen
, temp32b
, temp64
);
3488 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3490 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3494 temp16alen
= scale_expansion_zeroelim(bytcalen
, bytca
, bdytail
, temp16a
);
3495 bytcatlen
= scale_expansion_zeroelim(catlen
, cat
, bdytail
, bytcat
);
3496 temp32alen
= scale_expansion_zeroelim(bytcatlen
, bytcat
, 2.0 * bdy
,
3498 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3499 temp32alen
, temp32a
, temp48
);
3500 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3502 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3505 temp32alen
= scale_expansion_zeroelim(bytcatlen
, bytcat
, bdytail
,
3507 bytcattlen
= scale_expansion_zeroelim(cattlen
, catt
, bdytail
, bytcatt
);
3508 temp16alen
= scale_expansion_zeroelim(bytcattlen
, bytcatt
, 2.0 * bdy
,
3510 temp16blen
= scale_expansion_zeroelim(bytcattlen
, bytcatt
, bdytail
,
3512 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3513 temp16blen
, temp16b
, temp32b
);
3514 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3515 temp32blen
, temp32b
, temp64
);
3516 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3518 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3521 if((cdxtail
!= 0.0) || (cdytail
!= 0.0))
3523 if((adxtail
!= 0.0) || (adytail
!= 0.0)
3524 || (bdxtail
!= 0.0) || (bdytail
!= 0.0))
3526 Two_Product(adxtail
, bdy
, ti1
, ti0
);
3527 Two_Product(adx
, bdytail
, tj1
, tj0
);
3528 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, u3
, u
[2], u
[1], u
[0]);
3531 Two_Product(bdxtail
, negate
, ti1
, ti0
);
3533 Two_Product(bdx
, negate
, tj1
, tj0
);
3534 Two_Two_Sum(ti1
, ti0
, tj1
, tj0
, v3
, v
[2], v
[1], v
[0]);
3536 abtlen
= fast_expansion_sum_zeroelim(4, u
, 4, v
, abt
);
3538 Two_Product(adxtail
, bdytail
, ti1
, ti0
);
3539 Two_Product(bdxtail
, adytail
, tj1
, tj0
);
3540 Two_Two_Diff(ti1
, ti0
, tj1
, tj0
, abtt3
, abtt
[2], abtt
[1], abtt
[0]);
3554 temp16alen
= scale_expansion_zeroelim(cxtablen
, cxtab
, cdxtail
, temp16a
);
3555 cxtabtlen
= scale_expansion_zeroelim(abtlen
, abt
, cdxtail
, cxtabt
);
3556 temp32alen
= scale_expansion_zeroelim(cxtabtlen
, cxtabt
, 2.0 * cdx
,
3558 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3559 temp32alen
, temp32a
, temp48
);
3560 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3562 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3565 temp8len
= scale_expansion_zeroelim(4, bb
, cdxtail
, temp8
);
3566 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, adytail
,
3568 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3570 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3574 temp8len
= scale_expansion_zeroelim(4, aa
, -cdxtail
, temp8
);
3575 temp16alen
= scale_expansion_zeroelim(temp8len
, temp8
, bdytail
,
3577 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp16alen
,
3579 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3582 temp32alen
= scale_expansion_zeroelim(cxtabtlen
, cxtabt
, cdxtail
,
3584 cxtabttlen
= scale_expansion_zeroelim(abttlen
, abtt
, cdxtail
, cxtabtt
);
3585 temp16alen
= scale_expansion_zeroelim(cxtabttlen
, cxtabtt
, 2.0 * cdx
,
3587 temp16blen
= scale_expansion_zeroelim(cxtabttlen
, cxtabtt
, cdxtail
,
3589 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3590 temp16blen
, temp16b
, temp32b
);
3591 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3592 temp32blen
, temp32b
, temp64
);
3593 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3595 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3599 temp16alen
= scale_expansion_zeroelim(cytablen
, cytab
, cdytail
, temp16a
);
3600 cytabtlen
= scale_expansion_zeroelim(abtlen
, abt
, cdytail
, cytabt
);
3601 temp32alen
= scale_expansion_zeroelim(cytabtlen
, cytabt
, 2.0 * cdy
,
3603 temp48len
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3604 temp32alen
, temp32a
, temp48
);
3605 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp48len
,
3607 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3610 temp32alen
= scale_expansion_zeroelim(cytabtlen
, cytabt
, cdytail
,
3612 cytabttlen
= scale_expansion_zeroelim(abttlen
, abtt
, cdytail
, cytabtt
);
3613 temp16alen
= scale_expansion_zeroelim(cytabttlen
, cytabtt
, 2.0 * cdy
,
3615 temp16blen
= scale_expansion_zeroelim(cytabttlen
, cytabtt
, cdytail
,
3617 temp32blen
= fast_expansion_sum_zeroelim(temp16alen
, temp16a
,
3618 temp16blen
, temp16b
, temp32b
);
3619 temp64len
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
3620 temp32blen
, temp32b
, temp64
);
3621 finlength
= fast_expansion_sum_zeroelim(finlength
, finnow
, temp64len
,
3623 finswap
= finnow
; finnow
= finother
; finother
= finswap
;
3627 return finnow
[finlength
- 1];
3630 REAL
OSG::incircle(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
)
3636 REAL adx
, bdx
, cdx
, ady
, bdy
, cdy
;
3637 REAL bdxcdy
, cdxbdy
, cdxady
, adxcdy
, adxbdy
, bdxady
;
3638 REAL alift
, blift
, clift
;
3640 REAL permanent
, errbound
;
3643 OSG_FPU_ROUND_DOUBLE
;
3645 adx
= pa
[0] - pd
[0];
3646 bdx
= pb
[0] - pd
[0];
3647 cdx
= pc
[0] - pd
[0];
3648 ady
= pa
[1] - pd
[1];
3649 bdy
= pb
[1] - pd
[1];
3650 cdy
= pc
[1] - pd
[1];
3654 alift
= adx
* adx
+ ady
* ady
;
3658 blift
= bdx
* bdx
+ bdy
* bdy
;
3662 clift
= cdx
* cdx
+ cdy
* cdy
;
3664 det
= alift
* (bdxcdy
- cdxbdy
)
3665 + blift
* (cdxady
- adxcdy
)
3666 + clift
* (adxbdy
- bdxady
);
3668 permanent
= (Absolute(bdxcdy
) + Absolute(cdxbdy
)) * alift
3669 + (Absolute(cdxady
) + Absolute(adxcdy
)) * blift
3670 + (Absolute(adxbdy
) + Absolute(bdxady
)) * clift
;
3671 errbound
= iccerrboundA
* permanent
;
3672 if((det
> errbound
) || (-det
> errbound
))
3678 inc
= incircleadapt(pa
, pb
, pc
, pd
, permanent
);
3683 /*****************************************************************************/
3685 /* inspherefast() Approximate 3D insphere test. Nonrobust. */
3686 /* insphereexact() Exact 3D insphere test. Robust. */
3687 /* insphereslow() Another exact 3D insphere test. Robust. */
3688 /* insphere() Adaptive exact 3D insphere test. Robust. */
3690 /* Return a positive value if the point pe lies inside the */
3691 /* sphere passing through pa, pb, pc, and pd; a negative value */
3692 /* if it lies outside; and zero if the five points are */
3693 /* cospherical. The points pa, pb, pc, and pd must be ordered */
3694 /* so that they have a positive orientation (as defined by */
3695 /* orient3d()), or the sign of the result will be reversed. */
3697 /* Only the first and last routine should be used; the middle two are for */
3700 /* The last three use exact arithmetic to ensure a correct answer. The */
3701 /* result returned is the determinant of a matrix. In insphere() only, */
3702 /* this determinant is computed adaptively, in the sense that exact */
3703 /* arithmetic is used only to the degree it is needed to ensure that the */
3704 /* returned value has the correct sign. Hence, insphere() is usually quite */
3705 /* fast, but will run more slowly when the input points are cospherical or */
3708 /*****************************************************************************/
3710 REAL
inspherefast(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
)
3717 REAL aex
, bex
, cex
, dex
;
3718 REAL aey
, bey
, cey
, dey
;
3719 REAL aez
, bez
, cez
, dez
;
3720 REAL alift
, blift
, clift
, dlift
;
3721 REAL ab
, bc
, cd
, da
, ac
, bd
;
3722 REAL abc
, bcd
, cda
, dab
;
3724 aex
= pa
[0] - pe
[0];
3725 bex
= pb
[0] - pe
[0];
3726 cex
= pc
[0] - pe
[0];
3727 dex
= pd
[0] - pe
[0];
3728 aey
= pa
[1] - pe
[1];
3729 bey
= pb
[1] - pe
[1];
3730 cey
= pc
[1] - pe
[1];
3731 dey
= pd
[1] - pe
[1];
3732 aez
= pa
[2] - pe
[2];
3733 bez
= pb
[2] - pe
[2];
3734 cez
= pc
[2] - pe
[2];
3735 dez
= pd
[2] - pe
[2];
3737 ab
= aex
* bey
- bex
* aey
;
3738 bc
= bex
* cey
- cex
* bey
;
3739 cd
= cex
* dey
- dex
* cey
;
3740 da
= dex
* aey
- aex
* dey
;
3742 ac
= aex
* cey
- cex
* aey
;
3743 bd
= bex
* dey
- dex
* bey
;
3745 abc
= aez
* bc
- bez
* ac
+ cez
* ab
;
3746 bcd
= bez
* cd
- cez
* bd
+ dez
* bc
;
3747 cda
= cez
* da
+ dez
* ac
+ aez
* cd
;
3748 dab
= dez
* ab
+ aez
* bd
+ bez
* da
;
3750 alift
= aex
* aex
+ aey
* aey
+ aez
* aez
;
3751 blift
= bex
* bex
+ bey
* bey
+ bez
* bez
;
3752 clift
= cex
* cex
+ cey
* cey
+ cez
* cez
;
3753 dlift
= dex
* dex
+ dey
* dey
+ dez
* dez
;
3755 return (dlift
* abc
- clift
* dab
) + (blift
* cda
- alift
* bcd
);
3758 REAL
insphereexact(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
)
3765 INEXACT REAL axby1
, bxcy1
, cxdy1
, dxey1
, exay1
;
3766 INEXACT REAL bxay1
, cxby1
, dxcy1
, exdy1
, axey1
;
3767 INEXACT REAL axcy1
, bxdy1
, cxey1
, dxay1
, exby1
;
3768 INEXACT REAL cxay1
, dxby1
, excy1
, axdy1
, bxey1
;
3769 REAL axby0
, bxcy0
, cxdy0
, dxey0
, exay0
;
3770 REAL bxay0
, cxby0
, dxcy0
, exdy0
, axey0
;
3771 REAL axcy0
, bxdy0
, cxey0
, dxay0
, exby0
;
3772 REAL cxay0
, dxby0
, excy0
, axdy0
, bxey0
;
3773 REAL ab
[4], bc
[4], cd
[4], de
[4], ea
[4];
3774 REAL ac
[4], bd
[4], ce
[4], da
[4], eb
[4];
3775 REAL temp8a
[8], temp8b
[8], temp16
[16];
3776 int temp8alen
, temp8blen
, temp16len
;
3777 REAL abc
[24], bcd
[24], cde
[24], dea
[24], eab
[24];
3778 REAL abd
[24], bce
[24], cda
[24], deb
[24], eac
[24];
3779 int abclen
, bcdlen
, cdelen
, dealen
, eablen
;
3780 int abdlen
, bcelen
, cdalen
, deblen
, eaclen
;
3781 REAL temp48a
[48], temp48b
[48];
3782 int temp48alen
, temp48blen
;
3783 REAL abcd
[96], bcde
[96], cdea
[96], deab
[96], eabc
[96];
3784 int abcdlen
, bcdelen
, cdealen
, deablen
, eabclen
;
3786 REAL det384x
[384], det384y
[384], det384z
[384];
3787 int xlen
, ylen
, zlen
;
3790 REAL adet
[1152], bdet
[1152], cdet
[1152], ddet
[1152], edet
[1152];
3791 int alen
, blen
, clen
, dlen
, elen
;
3792 REAL abdet
[2304], cddet
[2304], cdedet
[3456];
3799 REAL avirt
, bround
, around
;
3802 REAL ahi
, alo
, bhi
, blo
;
3803 REAL err1
, err2
, err3
;
3804 INEXACT REAL _i
, _j
;
3807 Two_Product(pa
[0], pb
[1], axby1
, axby0
);
3808 Two_Product(pb
[0], pa
[1], bxay1
, bxay0
);
3809 Two_Two_Diff(axby1
, axby0
, bxay1
, bxay0
, ab
[3], ab
[2], ab
[1], ab
[0]);
3811 Two_Product(pb
[0], pc
[1], bxcy1
, bxcy0
);
3812 Two_Product(pc
[0], pb
[1], cxby1
, cxby0
);
3813 Two_Two_Diff(bxcy1
, bxcy0
, cxby1
, cxby0
, bc
[3], bc
[2], bc
[1], bc
[0]);
3815 Two_Product(pc
[0], pd
[1], cxdy1
, cxdy0
);
3816 Two_Product(pd
[0], pc
[1], dxcy1
, dxcy0
);
3817 Two_Two_Diff(cxdy1
, cxdy0
, dxcy1
, dxcy0
, cd
[3], cd
[2], cd
[1], cd
[0]);
3819 Two_Product(pd
[0], pe
[1], dxey1
, dxey0
);
3820 Two_Product(pe
[0], pd
[1], exdy1
, exdy0
);
3821 Two_Two_Diff(dxey1
, dxey0
, exdy1
, exdy0
, de
[3], de
[2], de
[1], de
[0]);
3823 Two_Product(pe
[0], pa
[1], exay1
, exay0
);
3824 Two_Product(pa
[0], pe
[1], axey1
, axey0
);
3825 Two_Two_Diff(exay1
, exay0
, axey1
, axey0
, ea
[3], ea
[2], ea
[1], ea
[0]);
3827 Two_Product(pa
[0], pc
[1], axcy1
, axcy0
);
3828 Two_Product(pc
[0], pa
[1], cxay1
, cxay0
);
3829 Two_Two_Diff(axcy1
, axcy0
, cxay1
, cxay0
, ac
[3], ac
[2], ac
[1], ac
[0]);
3831 Two_Product(pb
[0], pd
[1], bxdy1
, bxdy0
);
3832 Two_Product(pd
[0], pb
[1], dxby1
, dxby0
);
3833 Two_Two_Diff(bxdy1
, bxdy0
, dxby1
, dxby0
, bd
[3], bd
[2], bd
[1], bd
[0]);
3835 Two_Product(pc
[0], pe
[1], cxey1
, cxey0
);
3836 Two_Product(pe
[0], pc
[1], excy1
, excy0
);
3837 Two_Two_Diff(cxey1
, cxey0
, excy1
, excy0
, ce
[3], ce
[2], ce
[1], ce
[0]);
3839 Two_Product(pd
[0], pa
[1], dxay1
, dxay0
);
3840 Two_Product(pa
[0], pd
[1], axdy1
, axdy0
);
3841 Two_Two_Diff(dxay1
, dxay0
, axdy1
, axdy0
, da
[3], da
[2], da
[1], da
[0]);
3843 Two_Product(pe
[0], pb
[1], exby1
, exby0
);
3844 Two_Product(pb
[0], pe
[1], bxey1
, bxey0
);
3845 Two_Two_Diff(exby1
, exby0
, bxey1
, bxey0
, eb
[3], eb
[2], eb
[1], eb
[0]);
3847 temp8alen
= scale_expansion_zeroelim(4, bc
, pa
[2], temp8a
);
3848 temp8blen
= scale_expansion_zeroelim(4, ac
, -pb
[2], temp8b
);
3849 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3851 temp8alen
= scale_expansion_zeroelim(4, ab
, pc
[2], temp8a
);
3852 abclen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3855 temp8alen
= scale_expansion_zeroelim(4, cd
, pb
[2], temp8a
);
3856 temp8blen
= scale_expansion_zeroelim(4, bd
, -pc
[2], temp8b
);
3857 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3859 temp8alen
= scale_expansion_zeroelim(4, bc
, pd
[2], temp8a
);
3860 bcdlen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3863 temp8alen
= scale_expansion_zeroelim(4, de
, pc
[2], temp8a
);
3864 temp8blen
= scale_expansion_zeroelim(4, ce
, -pd
[2], temp8b
);
3865 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3867 temp8alen
= scale_expansion_zeroelim(4, cd
, pe
[2], temp8a
);
3868 cdelen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3871 temp8alen
= scale_expansion_zeroelim(4, ea
, pd
[2], temp8a
);
3872 temp8blen
= scale_expansion_zeroelim(4, da
, -pe
[2], temp8b
);
3873 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3875 temp8alen
= scale_expansion_zeroelim(4, de
, pa
[2], temp8a
);
3876 dealen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3879 temp8alen
= scale_expansion_zeroelim(4, ab
, pe
[2], temp8a
);
3880 temp8blen
= scale_expansion_zeroelim(4, eb
, -pa
[2], temp8b
);
3881 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3883 temp8alen
= scale_expansion_zeroelim(4, ea
, pb
[2], temp8a
);
3884 eablen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3887 temp8alen
= scale_expansion_zeroelim(4, bd
, pa
[2], temp8a
);
3888 temp8blen
= scale_expansion_zeroelim(4, da
, pb
[2], temp8b
);
3889 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3891 temp8alen
= scale_expansion_zeroelim(4, ab
, pd
[2], temp8a
);
3892 abdlen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3895 temp8alen
= scale_expansion_zeroelim(4, ce
, pb
[2], temp8a
);
3896 temp8blen
= scale_expansion_zeroelim(4, eb
, pc
[2], temp8b
);
3897 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3899 temp8alen
= scale_expansion_zeroelim(4, bc
, pe
[2], temp8a
);
3900 bcelen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3903 temp8alen
= scale_expansion_zeroelim(4, da
, pc
[2], temp8a
);
3904 temp8blen
= scale_expansion_zeroelim(4, ac
, pd
[2], temp8b
);
3905 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3907 temp8alen
= scale_expansion_zeroelim(4, cd
, pa
[2], temp8a
);
3908 cdalen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3911 temp8alen
= scale_expansion_zeroelim(4, eb
, pd
[2], temp8a
);
3912 temp8blen
= scale_expansion_zeroelim(4, bd
, pe
[2], temp8b
);
3913 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3915 temp8alen
= scale_expansion_zeroelim(4, de
, pb
[2], temp8a
);
3916 deblen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3919 temp8alen
= scale_expansion_zeroelim(4, ac
, pe
[2], temp8a
);
3920 temp8blen
= scale_expansion_zeroelim(4, ce
, pa
[2], temp8b
);
3921 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp8blen
, temp8b
,
3923 temp8alen
= scale_expansion_zeroelim(4, ea
, pc
[2], temp8a
);
3924 eaclen
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
, temp16len
, temp16
,
3927 temp48alen
= fast_expansion_sum_zeroelim(cdelen
, cde
, bcelen
, bce
, temp48a
);
3928 temp48blen
= fast_expansion_sum_zeroelim(deblen
, deb
, bcdlen
, bcd
, temp48b
);
3930 for(i
= 0; i
< temp48blen
; i
++)
3932 temp48b
[i
] = -temp48b
[i
];
3935 bcdelen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
3936 temp48blen
, temp48b
, bcde
);
3937 xlen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[0], temp192
);
3938 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pa
[0], det384x
);
3939 ylen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[1], temp192
);
3940 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pa
[1], det384y
);
3941 zlen
= scale_expansion_zeroelim(bcdelen
, bcde
, pa
[2], temp192
);
3942 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pa
[2], det384z
);
3943 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
3944 alen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, adet
);
3946 temp48alen
= fast_expansion_sum_zeroelim(dealen
, dea
, cdalen
, cda
, temp48a
);
3947 temp48blen
= fast_expansion_sum_zeroelim(eaclen
, eac
, cdelen
, cde
, temp48b
);
3949 for(i
= 0; i
< temp48blen
; i
++)
3951 temp48b
[i
] = -temp48b
[i
];
3954 cdealen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
3955 temp48blen
, temp48b
, cdea
);
3956 xlen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[0], temp192
);
3957 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pb
[0], det384x
);
3958 ylen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[1], temp192
);
3959 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pb
[1], det384y
);
3960 zlen
= scale_expansion_zeroelim(cdealen
, cdea
, pb
[2], temp192
);
3961 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pb
[2], det384z
);
3962 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
3963 blen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, bdet
);
3965 temp48alen
= fast_expansion_sum_zeroelim(eablen
, eab
, deblen
, deb
, temp48a
);
3966 temp48blen
= fast_expansion_sum_zeroelim(abdlen
, abd
, dealen
, dea
, temp48b
);
3968 for(i
= 0; i
< temp48blen
; i
++)
3970 temp48b
[i
] = -temp48b
[i
];
3973 deablen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
3974 temp48blen
, temp48b
, deab
);
3975 xlen
= scale_expansion_zeroelim(deablen
, deab
, pc
[0], temp192
);
3976 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pc
[0], det384x
);
3977 ylen
= scale_expansion_zeroelim(deablen
, deab
, pc
[1], temp192
);
3978 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pc
[1], det384y
);
3979 zlen
= scale_expansion_zeroelim(deablen
, deab
, pc
[2], temp192
);
3980 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pc
[2], det384z
);
3981 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
3982 clen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, cdet
);
3984 temp48alen
= fast_expansion_sum_zeroelim(abclen
, abc
, eaclen
, eac
, temp48a
);
3985 temp48blen
= fast_expansion_sum_zeroelim(bcelen
, bce
, eablen
, eab
, temp48b
);
3987 for(i
= 0; i
< temp48blen
; i
++)
3989 temp48b
[i
] = -temp48b
[i
];
3992 eabclen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
3993 temp48blen
, temp48b
, eabc
);
3994 xlen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[0], temp192
);
3995 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pd
[0], det384x
);
3996 ylen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[1], temp192
);
3997 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pd
[1], det384y
);
3998 zlen
= scale_expansion_zeroelim(eabclen
, eabc
, pd
[2], temp192
);
3999 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pd
[2], det384z
);
4000 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
4001 dlen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, ddet
);
4003 temp48alen
= fast_expansion_sum_zeroelim(bcdlen
, bcd
, abdlen
, abd
, temp48a
);
4004 temp48blen
= fast_expansion_sum_zeroelim(cdalen
, cda
, abclen
, abc
, temp48b
);
4006 for(i
= 0; i
< temp48blen
; i
++)
4008 temp48b
[i
] = -temp48b
[i
];
4011 abcdlen
= fast_expansion_sum_zeroelim(temp48alen
, temp48a
,
4012 temp48blen
, temp48b
, abcd
);
4013 xlen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[0], temp192
);
4014 xlen
= scale_expansion_zeroelim(xlen
, temp192
, pe
[0], det384x
);
4015 ylen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[1], temp192
);
4016 ylen
= scale_expansion_zeroelim(ylen
, temp192
, pe
[1], det384y
);
4017 zlen
= scale_expansion_zeroelim(abcdlen
, abcd
, pe
[2], temp192
);
4018 zlen
= scale_expansion_zeroelim(zlen
, temp192
, pe
[2], det384z
);
4019 xylen
= fast_expansion_sum_zeroelim(xlen
, det384x
, ylen
, det384y
, detxy
);
4020 elen
= fast_expansion_sum_zeroelim(xylen
, detxy
, zlen
, det384z
, edet
);
4022 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
4023 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
4024 cdelen
= fast_expansion_sum_zeroelim(cdlen
, cddet
, elen
, edet
, cdedet
);
4025 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdelen
, cdedet
, deter
);
4027 return deter
[deterlen
- 1];
4030 REAL
insphereslow(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
)
4037 INEXACT REAL aex
, bex
, cex
, dex
, aey
, bey
, cey
, dey
, aez
, bez
, cez
, dez
;
4038 REAL aextail
, bextail
, cextail
, dextail
;
4039 REAL aeytail
, beytail
, ceytail
, deytail
;
4040 REAL aeztail
, beztail
, ceztail
, deztail
;
4041 REAL negate
, negatetail
;
4042 INEXACT REAL axby7
, bxcy7
, cxdy7
, dxay7
, axcy7
, bxdy7
;
4043 INEXACT REAL bxay7
, cxby7
, dxcy7
, axdy7
, cxay7
, dxby7
;
4044 REAL axby
[8], bxcy
[8], cxdy
[8], dxay
[8], axcy
[8], bxdy
[8];
4045 REAL bxay
[8], cxby
[8], dxcy
[8], axdy
[8], cxay
[8], dxby
[8];
4046 REAL ab
[16], bc
[16], cd
[16], da
[16], ac
[16], bd
[16];
4047 int ablen
, bclen
, cdlen
, dalen
, aclen
, bdlen
;
4048 REAL temp32a
[32], temp32b
[32], temp64a
[64], temp64b
[64], temp64c
[64];
4049 int temp32alen
, temp32blen
, temp64alen
, temp64blen
, temp64clen
;
4050 REAL temp128
[128], temp192
[192];
4051 int temp128len
, temp192len
;
4052 REAL detx
[384], detxx
[768], detxt
[384], detxxt
[768], detxtxt
[768];
4053 int xlen
, xxlen
, xtlen
, xxtlen
, xtxtlen
;
4054 REAL x1
[1536], x2
[2304];
4056 REAL dety
[384], detyy
[768], detyt
[384], detyyt
[768], detytyt
[768];
4057 int ylen
, yylen
, ytlen
, yytlen
, ytytlen
;
4058 REAL y1
[1536], y2
[2304];
4060 REAL detz
[384], detzz
[768], detzt
[384], detzzt
[768], detztzt
[768];
4061 int zlen
, zzlen
, ztlen
, zztlen
, ztztlen
;
4062 REAL z1
[1536], z2
[2304];
4066 REAL adet
[6912], bdet
[6912], cdet
[6912], ddet
[6912];
4067 int alen
, blen
, clen
, dlen
;
4068 REAL abdet
[13824], cddet
[13824], deter
[27648];
4073 REAL avirt
, bround
, around
;
4076 REAL a0hi
, a0lo
, a1hi
, a1lo
, bhi
, blo
;
4077 REAL err1
, err2
, err3
;
4078 INEXACT REAL _i
, _j
, _k
, _l
, _m
, _n
;
4081 Two_Diff(pa
[0], pe
[0], aex
, aextail
);
4082 Two_Diff(pa
[1], pe
[1], aey
, aeytail
);
4083 Two_Diff(pa
[2], pe
[2], aez
, aeztail
);
4084 Two_Diff(pb
[0], pe
[0], bex
, bextail
);
4085 Two_Diff(pb
[1], pe
[1], bey
, beytail
);
4086 Two_Diff(pb
[2], pe
[2], bez
, beztail
);
4087 Two_Diff(pc
[0], pe
[0], cex
, cextail
);
4088 Two_Diff(pc
[1], pe
[1], cey
, ceytail
);
4089 Two_Diff(pc
[2], pe
[2], cez
, ceztail
);
4090 Two_Diff(pd
[0], pe
[0], dex
, dextail
);
4091 Two_Diff(pd
[1], pe
[1], dey
, deytail
);
4092 Two_Diff(pd
[2], pe
[2], dez
, deztail
);
4094 Two_Two_Product(aex
, aextail
, bey
, beytail
,
4095 axby7
, axby
[6], axby
[5], axby
[4],
4096 axby
[3], axby
[2], axby
[1], axby
[0]);
4099 negatetail
= -aeytail
;
4100 Two_Two_Product(bex
, bextail
, negate
, negatetail
,
4101 bxay7
, bxay
[6], bxay
[5], bxay
[4],
4102 bxay
[3], bxay
[2], bxay
[1], bxay
[0]);
4104 ablen
= fast_expansion_sum_zeroelim(8, axby
, 8, bxay
, ab
);
4105 Two_Two_Product(bex
, bextail
, cey
, ceytail
,
4106 bxcy7
, bxcy
[6], bxcy
[5], bxcy
[4],
4107 bxcy
[3], bxcy
[2], bxcy
[1], bxcy
[0]);
4110 negatetail
= -beytail
;
4111 Two_Two_Product(cex
, cextail
, negate
, negatetail
,
4112 cxby7
, cxby
[6], cxby
[5], cxby
[4],
4113 cxby
[3], cxby
[2], cxby
[1], cxby
[0]);
4115 bclen
= fast_expansion_sum_zeroelim(8, bxcy
, 8, cxby
, bc
);
4116 Two_Two_Product(cex
, cextail
, dey
, deytail
,
4117 cxdy7
, cxdy
[6], cxdy
[5], cxdy
[4],
4118 cxdy
[3], cxdy
[2], cxdy
[1], cxdy
[0]);
4121 negatetail
= -ceytail
;
4122 Two_Two_Product(dex
, dextail
, negate
, negatetail
,
4123 dxcy7
, dxcy
[6], dxcy
[5], dxcy
[4],
4124 dxcy
[3], dxcy
[2], dxcy
[1], dxcy
[0]);
4126 cdlen
= fast_expansion_sum_zeroelim(8, cxdy
, 8, dxcy
, cd
);
4127 Two_Two_Product(dex
, dextail
, aey
, aeytail
,
4128 dxay7
, dxay
[6], dxay
[5], dxay
[4],
4129 dxay
[3], dxay
[2], dxay
[1], dxay
[0]);
4132 negatetail
= -deytail
;
4133 Two_Two_Product(aex
, aextail
, negate
, negatetail
,
4134 axdy7
, axdy
[6], axdy
[5], axdy
[4],
4135 axdy
[3], axdy
[2], axdy
[1], axdy
[0]);
4137 dalen
= fast_expansion_sum_zeroelim(8, dxay
, 8, axdy
, da
);
4138 Two_Two_Product(aex
, aextail
, cey
, ceytail
,
4139 axcy7
, axcy
[6], axcy
[5], axcy
[4],
4140 axcy
[3], axcy
[2], axcy
[1], axcy
[0]);
4143 negatetail
= -aeytail
;
4144 Two_Two_Product(cex
, cextail
, negate
, negatetail
,
4145 cxay7
, cxay
[6], cxay
[5], cxay
[4],
4146 cxay
[3], cxay
[2], cxay
[1], cxay
[0]);
4148 aclen
= fast_expansion_sum_zeroelim(8, axcy
, 8, cxay
, ac
);
4149 Two_Two_Product(bex
, bextail
, dey
, deytail
,
4150 bxdy7
, bxdy
[6], bxdy
[5], bxdy
[4],
4151 bxdy
[3], bxdy
[2], bxdy
[1], bxdy
[0]);
4154 negatetail
= -beytail
;
4155 Two_Two_Product(dex
, dextail
, negate
, negatetail
,
4156 dxby7
, dxby
[6], dxby
[5], dxby
[4],
4157 dxby
[3], dxby
[2], dxby
[1], dxby
[0]);
4159 bdlen
= fast_expansion_sum_zeroelim(8, bxdy
, 8, dxby
, bd
);
4161 temp32alen
= scale_expansion_zeroelim(cdlen
, cd
, -bez
, temp32a
);
4162 temp32blen
= scale_expansion_zeroelim(cdlen
, cd
, -beztail
, temp32b
);
4163 temp64alen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4164 temp32blen
, temp32b
, temp64a
);
4165 temp32alen
= scale_expansion_zeroelim(bdlen
, bd
, cez
, temp32a
);
4166 temp32blen
= scale_expansion_zeroelim(bdlen
, bd
, ceztail
, temp32b
);
4167 temp64blen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4168 temp32blen
, temp32b
, temp64b
);
4169 temp32alen
= scale_expansion_zeroelim(bclen
, bc
, -dez
, temp32a
);
4170 temp32blen
= scale_expansion_zeroelim(bclen
, bc
, -deztail
, temp32b
);
4171 temp64clen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4172 temp32blen
, temp32b
, temp64c
);
4173 temp128len
= fast_expansion_sum_zeroelim(temp64alen
, temp64a
,
4174 temp64blen
, temp64b
, temp128
);
4175 temp192len
= fast_expansion_sum_zeroelim(temp64clen
, temp64c
,
4176 temp128len
, temp128
, temp192
);
4177 xlen
= scale_expansion_zeroelim(temp192len
, temp192
, aex
, detx
);
4178 xxlen
= scale_expansion_zeroelim(xlen
, detx
, aex
, detxx
);
4179 xtlen
= scale_expansion_zeroelim(temp192len
, temp192
, aextail
, detxt
);
4180 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, aex
, detxxt
);
4182 for(i
= 0; i
< xxtlen
; i
++)
4187 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, aextail
, detxtxt
);
4188 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
4189 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
4190 ylen
= scale_expansion_zeroelim(temp192len
, temp192
, aey
, dety
);
4191 yylen
= scale_expansion_zeroelim(ylen
, dety
, aey
, detyy
);
4192 ytlen
= scale_expansion_zeroelim(temp192len
, temp192
, aeytail
, detyt
);
4193 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, aey
, detyyt
);
4195 for(i
= 0; i
< yytlen
; i
++)
4200 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, aeytail
, detytyt
);
4201 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
4202 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
4203 zlen
= scale_expansion_zeroelim(temp192len
, temp192
, aez
, detz
);
4204 zzlen
= scale_expansion_zeroelim(zlen
, detz
, aez
, detzz
);
4205 ztlen
= scale_expansion_zeroelim(temp192len
, temp192
, aeztail
, detzt
);
4206 zztlen
= scale_expansion_zeroelim(ztlen
, detzt
, aez
, detzzt
);
4208 for(i
= 0; i
< zztlen
; i
++)
4213 ztztlen
= scale_expansion_zeroelim(ztlen
, detzt
, aeztail
, detztzt
);
4214 z1len
= fast_expansion_sum_zeroelim(zzlen
, detzz
, zztlen
, detzzt
, z1
);
4215 z2len
= fast_expansion_sum_zeroelim(z1len
, z1
, ztztlen
, detztzt
, z2
);
4216 xylen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, detxy
);
4217 alen
= fast_expansion_sum_zeroelim(z2len
, z2
, xylen
, detxy
, adet
);
4219 temp32alen
= scale_expansion_zeroelim(dalen
, da
, cez
, temp32a
);
4220 temp32blen
= scale_expansion_zeroelim(dalen
, da
, ceztail
, temp32b
);
4221 temp64alen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4222 temp32blen
, temp32b
, temp64a
);
4223 temp32alen
= scale_expansion_zeroelim(aclen
, ac
, dez
, temp32a
);
4224 temp32blen
= scale_expansion_zeroelim(aclen
, ac
, deztail
, temp32b
);
4225 temp64blen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4226 temp32blen
, temp32b
, temp64b
);
4227 temp32alen
= scale_expansion_zeroelim(cdlen
, cd
, aez
, temp32a
);
4228 temp32blen
= scale_expansion_zeroelim(cdlen
, cd
, aeztail
, temp32b
);
4229 temp64clen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4230 temp32blen
, temp32b
, temp64c
);
4231 temp128len
= fast_expansion_sum_zeroelim(temp64alen
, temp64a
,
4232 temp64blen
, temp64b
, temp128
);
4233 temp192len
= fast_expansion_sum_zeroelim(temp64clen
, temp64c
,
4234 temp128len
, temp128
, temp192
);
4235 xlen
= scale_expansion_zeroelim(temp192len
, temp192
, bex
, detx
);
4236 xxlen
= scale_expansion_zeroelim(xlen
, detx
, bex
, detxx
);
4237 xtlen
= scale_expansion_zeroelim(temp192len
, temp192
, bextail
, detxt
);
4238 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, bex
, detxxt
);
4240 for(i
= 0; i
< xxtlen
; i
++)
4245 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, bextail
, detxtxt
);
4246 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
4247 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
4248 ylen
= scale_expansion_zeroelim(temp192len
, temp192
, bey
, dety
);
4249 yylen
= scale_expansion_zeroelim(ylen
, dety
, bey
, detyy
);
4250 ytlen
= scale_expansion_zeroelim(temp192len
, temp192
, beytail
, detyt
);
4251 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, bey
, detyyt
);
4253 for(i
= 0; i
< yytlen
; i
++)
4258 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, beytail
, detytyt
);
4259 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
4260 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
4261 zlen
= scale_expansion_zeroelim(temp192len
, temp192
, bez
, detz
);
4262 zzlen
= scale_expansion_zeroelim(zlen
, detz
, bez
, detzz
);
4263 ztlen
= scale_expansion_zeroelim(temp192len
, temp192
, beztail
, detzt
);
4264 zztlen
= scale_expansion_zeroelim(ztlen
, detzt
, bez
, detzzt
);
4266 for(i
= 0; i
< zztlen
; i
++)
4271 ztztlen
= scale_expansion_zeroelim(ztlen
, detzt
, beztail
, detztzt
);
4272 z1len
= fast_expansion_sum_zeroelim(zzlen
, detzz
, zztlen
, detzzt
, z1
);
4273 z2len
= fast_expansion_sum_zeroelim(z1len
, z1
, ztztlen
, detztzt
, z2
);
4274 xylen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, detxy
);
4275 blen
= fast_expansion_sum_zeroelim(z2len
, z2
, xylen
, detxy
, bdet
);
4277 temp32alen
= scale_expansion_zeroelim(ablen
, ab
, -dez
, temp32a
);
4278 temp32blen
= scale_expansion_zeroelim(ablen
, ab
, -deztail
, temp32b
);
4279 temp64alen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4280 temp32blen
, temp32b
, temp64a
);
4281 temp32alen
= scale_expansion_zeroelim(bdlen
, bd
, -aez
, temp32a
);
4282 temp32blen
= scale_expansion_zeroelim(bdlen
, bd
, -aeztail
, temp32b
);
4283 temp64blen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4284 temp32blen
, temp32b
, temp64b
);
4285 temp32alen
= scale_expansion_zeroelim(dalen
, da
, -bez
, temp32a
);
4286 temp32blen
= scale_expansion_zeroelim(dalen
, da
, -beztail
, temp32b
);
4287 temp64clen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4288 temp32blen
, temp32b
, temp64c
);
4289 temp128len
= fast_expansion_sum_zeroelim(temp64alen
, temp64a
,
4290 temp64blen
, temp64b
, temp128
);
4291 temp192len
= fast_expansion_sum_zeroelim(temp64clen
, temp64c
,
4292 temp128len
, temp128
, temp192
);
4293 xlen
= scale_expansion_zeroelim(temp192len
, temp192
, cex
, detx
);
4294 xxlen
= scale_expansion_zeroelim(xlen
, detx
, cex
, detxx
);
4295 xtlen
= scale_expansion_zeroelim(temp192len
, temp192
, cextail
, detxt
);
4296 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, cex
, detxxt
);
4298 for(i
= 0; i
< xxtlen
; i
++)
4303 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, cextail
, detxtxt
);
4304 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
4305 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
4306 ylen
= scale_expansion_zeroelim(temp192len
, temp192
, cey
, dety
);
4307 yylen
= scale_expansion_zeroelim(ylen
, dety
, cey
, detyy
);
4308 ytlen
= scale_expansion_zeroelim(temp192len
, temp192
, ceytail
, detyt
);
4309 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, cey
, detyyt
);
4311 for(i
= 0; i
< yytlen
; i
++)
4316 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, ceytail
, detytyt
);
4317 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
4318 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
4319 zlen
= scale_expansion_zeroelim(temp192len
, temp192
, cez
, detz
);
4320 zzlen
= scale_expansion_zeroelim(zlen
, detz
, cez
, detzz
);
4321 ztlen
= scale_expansion_zeroelim(temp192len
, temp192
, ceztail
, detzt
);
4322 zztlen
= scale_expansion_zeroelim(ztlen
, detzt
, cez
, detzzt
);
4324 for(i
= 0; i
< zztlen
; i
++)
4329 ztztlen
= scale_expansion_zeroelim(ztlen
, detzt
, ceztail
, detztzt
);
4330 z1len
= fast_expansion_sum_zeroelim(zzlen
, detzz
, zztlen
, detzzt
, z1
);
4331 z2len
= fast_expansion_sum_zeroelim(z1len
, z1
, ztztlen
, detztzt
, z2
);
4332 xylen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, detxy
);
4333 clen
= fast_expansion_sum_zeroelim(z2len
, z2
, xylen
, detxy
, cdet
);
4335 temp32alen
= scale_expansion_zeroelim(bclen
, bc
, aez
, temp32a
);
4336 temp32blen
= scale_expansion_zeroelim(bclen
, bc
, aeztail
, temp32b
);
4337 temp64alen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4338 temp32blen
, temp32b
, temp64a
);
4339 temp32alen
= scale_expansion_zeroelim(aclen
, ac
, -bez
, temp32a
);
4340 temp32blen
= scale_expansion_zeroelim(aclen
, ac
, -beztail
, temp32b
);
4341 temp64blen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4342 temp32blen
, temp32b
, temp64b
);
4343 temp32alen
= scale_expansion_zeroelim(ablen
, ab
, cez
, temp32a
);
4344 temp32blen
= scale_expansion_zeroelim(ablen
, ab
, ceztail
, temp32b
);
4345 temp64clen
= fast_expansion_sum_zeroelim(temp32alen
, temp32a
,
4346 temp32blen
, temp32b
, temp64c
);
4347 temp128len
= fast_expansion_sum_zeroelim(temp64alen
, temp64a
,
4348 temp64blen
, temp64b
, temp128
);
4349 temp192len
= fast_expansion_sum_zeroelim(temp64clen
, temp64c
,
4350 temp128len
, temp128
, temp192
);
4351 xlen
= scale_expansion_zeroelim(temp192len
, temp192
, dex
, detx
);
4352 xxlen
= scale_expansion_zeroelim(xlen
, detx
, dex
, detxx
);
4353 xtlen
= scale_expansion_zeroelim(temp192len
, temp192
, dextail
, detxt
);
4354 xxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, dex
, detxxt
);
4356 for(i
= 0; i
< xxtlen
; i
++)
4361 xtxtlen
= scale_expansion_zeroelim(xtlen
, detxt
, dextail
, detxtxt
);
4362 x1len
= fast_expansion_sum_zeroelim(xxlen
, detxx
, xxtlen
, detxxt
, x1
);
4363 x2len
= fast_expansion_sum_zeroelim(x1len
, x1
, xtxtlen
, detxtxt
, x2
);
4364 ylen
= scale_expansion_zeroelim(temp192len
, temp192
, dey
, dety
);
4365 yylen
= scale_expansion_zeroelim(ylen
, dety
, dey
, detyy
);
4366 ytlen
= scale_expansion_zeroelim(temp192len
, temp192
, deytail
, detyt
);
4367 yytlen
= scale_expansion_zeroelim(ytlen
, detyt
, dey
, detyyt
);
4369 for(i
= 0; i
< yytlen
; i
++)
4374 ytytlen
= scale_expansion_zeroelim(ytlen
, detyt
, deytail
, detytyt
);
4375 y1len
= fast_expansion_sum_zeroelim(yylen
, detyy
, yytlen
, detyyt
, y1
);
4376 y2len
= fast_expansion_sum_zeroelim(y1len
, y1
, ytytlen
, detytyt
, y2
);
4377 zlen
= scale_expansion_zeroelim(temp192len
, temp192
, dez
, detz
);
4378 zzlen
= scale_expansion_zeroelim(zlen
, detz
, dez
, detzz
);
4379 ztlen
= scale_expansion_zeroelim(temp192len
, temp192
, deztail
, detzt
);
4380 zztlen
= scale_expansion_zeroelim(ztlen
, detzt
, dez
, detzzt
);
4382 for(i
= 0; i
< zztlen
; i
++)
4387 ztztlen
= scale_expansion_zeroelim(ztlen
, detzt
, deztail
, detztzt
);
4388 z1len
= fast_expansion_sum_zeroelim(zzlen
, detzz
, zztlen
, detzzt
, z1
);
4389 z2len
= fast_expansion_sum_zeroelim(z1len
, z1
, ztztlen
, detztzt
, z2
);
4390 xylen
= fast_expansion_sum_zeroelim(x2len
, x2
, y2len
, y2
, detxy
);
4391 dlen
= fast_expansion_sum_zeroelim(z2len
, z2
, xylen
, detxy
, ddet
);
4393 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
4394 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
4395 deterlen
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdlen
, cddet
, deter
);
4397 return deter
[deterlen
- 1];
4400 REAL
insphereadapt(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
, REAL permanent
)
4408 INEXACT REAL aex
, bex
, cex
, dex
, aey
, bey
, cey
, dey
, aez
, bez
, cez
, dez
;
4411 INEXACT REAL aexbey1
, bexaey1
, bexcey1
, cexbey1
;
4412 INEXACT REAL cexdey1
, dexcey1
, dexaey1
, aexdey1
;
4413 INEXACT REAL aexcey1
, cexaey1
, bexdey1
, dexbey1
;
4414 REAL aexbey0
, bexaey0
, bexcey0
, cexbey0
;
4415 REAL cexdey0
, dexcey0
, dexaey0
, aexdey0
;
4416 REAL aexcey0
, cexaey0
, bexdey0
, dexbey0
;
4417 REAL ab
[4], bc
[4], cd
[4], da
[4], ac
[4], bd
[4];
4418 INEXACT REAL ab3
, bc3
, cd3
, da3
, ac3
, bd3
;
4419 REAL abeps
, bceps
, cdeps
, daeps
, aceps
, bdeps
;
4420 REAL temp8a
[8], temp8b
[8], temp8c
[8], temp16
[16], temp24
[24], temp48
[48];
4421 int temp8alen
, temp8blen
, temp8clen
, temp16len
, temp24len
, temp48len
;
4422 REAL xdet
[96], ydet
[96], zdet
[96], xydet
[192];
4423 int xlen
, ylen
, zlen
, xylen
;
4424 REAL adet
[288], bdet
[288], cdet
[288], ddet
[288];
4425 int alen
, blen
, clen
, dlen
;
4426 REAL abdet
[576], cddet
[576];
4431 REAL aextail
, bextail
, cextail
, dextail
;
4432 REAL aeytail
, beytail
, ceytail
, deytail
;
4433 REAL aeztail
, beztail
, ceztail
, deztail
;
4436 REAL avirt
, bround
, around
;
4439 REAL ahi
, alo
, bhi
, blo
;
4440 REAL err1
, err2
, err3
;
4441 INEXACT REAL _i
, _j
;
4444 aex
= REAL(pa
[0] - pe
[0]);
4445 bex
= REAL(pb
[0] - pe
[0]);
4446 cex
= REAL(pc
[0] - pe
[0]);
4447 dex
= REAL(pd
[0] - pe
[0]);
4448 aey
= REAL(pa
[1] - pe
[1]);
4449 bey
= REAL(pb
[1] - pe
[1]);
4450 cey
= REAL(pc
[1] - pe
[1]);
4451 dey
= REAL(pd
[1] - pe
[1]);
4452 aez
= REAL(pa
[2] - pe
[2]);
4453 bez
= REAL(pb
[2] - pe
[2]);
4454 cez
= REAL(pc
[2] - pe
[2]);
4455 dez
= REAL(pd
[2] - pe
[2]);
4457 Two_Product(aex
, bey
, aexbey1
, aexbey0
);
4458 Two_Product(bex
, aey
, bexaey1
, bexaey0
);
4459 Two_Two_Diff(aexbey1
, aexbey0
, bexaey1
, bexaey0
, ab3
, ab
[2], ab
[1], ab
[0]);
4462 Two_Product(bex
, cey
, bexcey1
, bexcey0
);
4463 Two_Product(cex
, bey
, cexbey1
, cexbey0
);
4464 Two_Two_Diff(bexcey1
, bexcey0
, cexbey1
, cexbey0
, bc3
, bc
[2], bc
[1], bc
[0]);
4467 Two_Product(cex
, dey
, cexdey1
, cexdey0
);
4468 Two_Product(dex
, cey
, dexcey1
, dexcey0
);
4469 Two_Two_Diff(cexdey1
, cexdey0
, dexcey1
, dexcey0
, cd3
, cd
[2], cd
[1], cd
[0]);
4472 Two_Product(dex
, aey
, dexaey1
, dexaey0
);
4473 Two_Product(aex
, dey
, aexdey1
, aexdey0
);
4474 Two_Two_Diff(dexaey1
, dexaey0
, aexdey1
, aexdey0
, da3
, da
[2], da
[1], da
[0]);
4477 Two_Product(aex
, cey
, aexcey1
, aexcey0
);
4478 Two_Product(cex
, aey
, cexaey1
, cexaey0
);
4479 Two_Two_Diff(aexcey1
, aexcey0
, cexaey1
, cexaey0
, ac3
, ac
[2], ac
[1], ac
[0]);
4482 Two_Product(bex
, dey
, bexdey1
, bexdey0
);
4483 Two_Product(dex
, bey
, dexbey1
, dexbey0
);
4484 Two_Two_Diff(bexdey1
, bexdey0
, dexbey1
, dexbey0
, bd3
, bd
[2], bd
[1], bd
[0]);
4487 temp8alen
= scale_expansion_zeroelim(4, cd
, bez
, temp8a
);
4488 temp8blen
= scale_expansion_zeroelim(4, bd
, -cez
, temp8b
);
4489 temp8clen
= scale_expansion_zeroelim(4, bc
, dez
, temp8c
);
4490 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
4491 temp8blen
, temp8b
, temp16
);
4492 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
4493 temp16len
, temp16
, temp24
);
4494 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aex
, temp48
);
4495 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, -aex
, xdet
);
4496 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aey
, temp48
);
4497 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, -aey
, ydet
);
4498 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, aez
, temp48
);
4499 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, -aez
, zdet
);
4500 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
4501 alen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, adet
);
4503 temp8alen
= scale_expansion_zeroelim(4, da
, cez
, temp8a
);
4504 temp8blen
= scale_expansion_zeroelim(4, ac
, dez
, temp8b
);
4505 temp8clen
= scale_expansion_zeroelim(4, cd
, aez
, temp8c
);
4506 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
4507 temp8blen
, temp8b
, temp16
);
4508 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
4509 temp16len
, temp16
, temp24
);
4510 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bex
, temp48
);
4511 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, bex
, xdet
);
4512 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bey
, temp48
);
4513 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, bey
, ydet
);
4514 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, bez
, temp48
);
4515 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, bez
, zdet
);
4516 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
4517 blen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, bdet
);
4519 temp8alen
= scale_expansion_zeroelim(4, ab
, dez
, temp8a
);
4520 temp8blen
= scale_expansion_zeroelim(4, bd
, aez
, temp8b
);
4521 temp8clen
= scale_expansion_zeroelim(4, da
, bez
, temp8c
);
4522 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
4523 temp8blen
, temp8b
, temp16
);
4524 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
4525 temp16len
, temp16
, temp24
);
4526 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cex
, temp48
);
4527 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, -cex
, xdet
);
4528 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cey
, temp48
);
4529 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, -cey
, ydet
);
4530 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, cez
, temp48
);
4531 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, -cez
, zdet
);
4532 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
4533 clen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, cdet
);
4535 temp8alen
= scale_expansion_zeroelim(4, bc
, aez
, temp8a
);
4536 temp8blen
= scale_expansion_zeroelim(4, ac
, -bez
, temp8b
);
4537 temp8clen
= scale_expansion_zeroelim(4, ab
, cez
, temp8c
);
4538 temp16len
= fast_expansion_sum_zeroelim(temp8alen
, temp8a
,
4539 temp8blen
, temp8b
, temp16
);
4540 temp24len
= fast_expansion_sum_zeroelim(temp8clen
, temp8c
,
4541 temp16len
, temp16
, temp24
);
4542 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dex
, temp48
);
4543 xlen
= scale_expansion_zeroelim(temp48len
, temp48
, dex
, xdet
);
4544 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dey
, temp48
);
4545 ylen
= scale_expansion_zeroelim(temp48len
, temp48
, dey
, ydet
);
4546 temp48len
= scale_expansion_zeroelim(temp24len
, temp24
, dez
, temp48
);
4547 zlen
= scale_expansion_zeroelim(temp48len
, temp48
, dez
, zdet
);
4548 xylen
= fast_expansion_sum_zeroelim(xlen
, xdet
, ylen
, ydet
, xydet
);
4549 dlen
= fast_expansion_sum_zeroelim(xylen
, xydet
, zlen
, zdet
, ddet
);
4551 ablen
= fast_expansion_sum_zeroelim(alen
, adet
, blen
, bdet
, abdet
);
4552 cdlen
= fast_expansion_sum_zeroelim(clen
, cdet
, dlen
, ddet
, cddet
);
4553 finlength
= fast_expansion_sum_zeroelim(ablen
, abdet
, cdlen
, cddet
, fin1
);
4555 det
= estimate(finlength
, fin1
);
4556 errbound
= isperrboundB
* permanent
;
4557 if((det
>= errbound
) || (-det
>= errbound
))
4562 Two_Diff_Tail(pa
[0], pe
[0], aex
, aextail
);
4563 Two_Diff_Tail(pa
[1], pe
[1], aey
, aeytail
);
4564 Two_Diff_Tail(pa
[2], pe
[2], aez
, aeztail
);
4565 Two_Diff_Tail(pb
[0], pe
[0], bex
, bextail
);
4566 Two_Diff_Tail(pb
[1], pe
[1], bey
, beytail
);
4567 Two_Diff_Tail(pb
[2], pe
[2], bez
, beztail
);
4568 Two_Diff_Tail(pc
[0], pe
[0], cex
, cextail
);
4569 Two_Diff_Tail(pc
[1], pe
[1], cey
, ceytail
);
4570 Two_Diff_Tail(pc
[2], pe
[2], cez
, ceztail
);
4571 Two_Diff_Tail(pd
[0], pe
[0], dex
, dextail
);
4572 Two_Diff_Tail(pd
[1], pe
[1], dey
, deytail
);
4573 Two_Diff_Tail(pd
[2], pe
[2], dez
, deztail
);
4574 if((aextail
== 0.0) && (aeytail
== 0.0) && (aeztail
== 0.0)
4575 && (bextail
== 0.0) && (beytail
== 0.0) && (beztail
== 0.0)
4576 && (cextail
== 0.0) && (ceytail
== 0.0) && (ceztail
== 0.0)
4577 && (dextail
== 0.0) && (deytail
== 0.0) && (deztail
== 0.0))
4582 errbound
= isperrboundC
* permanent
+ resulterrbound
* Absolute(det
);
4583 abeps
= (aex
* beytail
+ bey
* aextail
)
4584 - (aey
* bextail
+ bex
* aeytail
);
4585 bceps
= (bex
* ceytail
+ cey
* bextail
)
4586 - (bey
* cextail
+ cex
* beytail
);
4587 cdeps
= (cex
* deytail
+ dey
* cextail
)
4588 - (cey
* dextail
+ dex
* ceytail
);
4589 daeps
= (dex
* aeytail
+ aey
* dextail
)
4590 - (dey
* aextail
+ aex
* deytail
);
4591 aceps
= (aex
* ceytail
+ cey
* aextail
)
4592 - (aey
* cextail
+ cex
* aeytail
);
4593 bdeps
= (bex
* deytail
+ dey
* bextail
)
4594 - (bey
* dextail
+ dex
* beytail
);
4595 det
+= (((bex
* bex
+ bey
* bey
+ bez
* bez
)
4596 * ((cez
* daeps
+ dez
* aceps
+ aez
* cdeps
)
4597 + (ceztail
* da3
+ deztail
* ac3
+ aeztail
* cd3
))
4598 + (dex
* dex
+ dey
* dey
+ dez
* dez
)
4599 * ((aez
* bceps
- bez
* aceps
+ cez
* abeps
)
4600 + (aeztail
* bc3
- beztail
* ac3
+ ceztail
* ab3
)))
4601 - ((aex
* aex
+ aey
* aey
+ aez
* aez
)
4602 * ((bez
* cdeps
- cez
* bdeps
+ dez
* bceps
)
4603 + (beztail
* cd3
- ceztail
* bd3
+ deztail
* bc3
))
4604 + (cex
* cex
+ cey
* cey
+ cez
* cez
)
4605 * ((dez
* abeps
+ aez
* bdeps
+ bez
* daeps
)
4606 + (deztail
* ab3
+ aeztail
* bd3
+ beztail
* da3
))))
4607 + 2.0 * (((bex
* bextail
+ bey
* beytail
+ bez
* beztail
)
4608 * (cez
* da3
+ dez
* ac3
+ aez
* cd3
)
4609 + (dex
* dextail
+ dey
* deytail
+ dez
* deztail
)
4610 * (aez
* bc3
- bez
* ac3
+ cez
* ab3
))
4611 - ((aex
* aextail
+ aey
* aeytail
+ aez
* aeztail
)
4612 * (bez
* cd3
- cez
* bd3
+ dez
* bc3
)
4613 + (cex
* cextail
+ cey
* ceytail
+ cez
* ceztail
)
4614 * (dez
* ab3
+ aez
* bd3
+ bez
* da3
)));
4615 if((det
>= errbound
) || (-det
>= errbound
))
4620 return insphereexact(pa
, pb
, pc
, pd
, pe
);
4623 REAL
OSG::insphere(REAL
*pa
, REAL
*pb
, REAL
*pc
, REAL
*pd
, REAL
*pe
)
4630 REAL aex
, bex
, cex
, dex
;
4631 REAL aey
, bey
, cey
, dey
;
4632 REAL aez
, bez
, cez
, dez
;
4633 REAL aexbey
, bexaey
, bexcey
, cexbey
, cexdey
, dexcey
, dexaey
, aexdey
;
4634 REAL aexcey
, cexaey
, bexdey
, dexbey
;
4635 REAL alift
, blift
, clift
, dlift
;
4636 REAL ab
, bc
, cd
, da
, ac
, bd
;
4637 REAL abc
, bcd
, cda
, dab
;
4638 REAL aezplus
, bezplus
, cezplus
, dezplus
;
4639 REAL aexbeyplus
, bexaeyplus
, bexceyplus
, cexbeyplus
;
4640 REAL cexdeyplus
, dexceyplus
, dexaeyplus
, aexdeyplus
;
4641 REAL aexceyplus
, cexaeyplus
, bexdeyplus
, dexbeyplus
;
4643 REAL permanent
, errbound
;
4646 OSG_FPU_ROUND_DOUBLE
;
4648 aex
= pa
[0] - pe
[0];
4649 bex
= pb
[0] - pe
[0];
4650 cex
= pc
[0] - pe
[0];
4651 dex
= pd
[0] - pe
[0];
4652 aey
= pa
[1] - pe
[1];
4653 bey
= pb
[1] - pe
[1];
4654 cey
= pc
[1] - pe
[1];
4655 dey
= pd
[1] - pe
[1];
4656 aez
= pa
[2] - pe
[2];
4657 bez
= pb
[2] - pe
[2];
4658 cez
= pc
[2] - pe
[2];
4659 dez
= pd
[2] - pe
[2];
4663 ab
= aexbey
- bexaey
;
4666 bc
= bexcey
- cexbey
;
4669 cd
= cexdey
- dexcey
;
4672 da
= dexaey
- aexdey
;
4676 ac
= aexcey
- cexaey
;
4679 bd
= bexdey
- dexbey
;
4681 abc
= aez
* bc
- bez
* ac
+ cez
* ab
;
4682 bcd
= bez
* cd
- cez
* bd
+ dez
* bc
;
4683 cda
= cez
* da
+ dez
* ac
+ aez
* cd
;
4684 dab
= dez
* ab
+ aez
* bd
+ bez
* da
;
4686 alift
= aex
* aex
+ aey
* aey
+ aez
* aez
;
4687 blift
= bex
* bex
+ bey
* bey
+ bez
* bez
;
4688 clift
= cex
* cex
+ cey
* cey
+ cez
* cez
;
4689 dlift
= dex
* dex
+ dey
* dey
+ dez
* dez
;
4691 det
= (dlift
* abc
- clift
* dab
) + (blift
* cda
- alift
* bcd
);
4693 aezplus
= Absolute(aez
);
4694 bezplus
= Absolute(bez
);
4695 cezplus
= Absolute(cez
);
4696 dezplus
= Absolute(dez
);
4697 aexbeyplus
= Absolute(aexbey
);
4698 bexaeyplus
= Absolute(bexaey
);
4699 bexceyplus
= Absolute(bexcey
);
4700 cexbeyplus
= Absolute(cexbey
);
4701 cexdeyplus
= Absolute(cexdey
);
4702 dexceyplus
= Absolute(dexcey
);
4703 dexaeyplus
= Absolute(dexaey
);
4704 aexdeyplus
= Absolute(aexdey
);
4705 aexceyplus
= Absolute(aexcey
);
4706 cexaeyplus
= Absolute(cexaey
);
4707 bexdeyplus
= Absolute(bexdey
);
4708 dexbeyplus
= Absolute(dexbey
);
4709 permanent
= ((cexdeyplus
+ dexceyplus
) * bezplus
4710 + (dexbeyplus
+ bexdeyplus
) * cezplus
4711 + (bexceyplus
+ cexbeyplus
) * dezplus
)
4713 + ((dexaeyplus
+ aexdeyplus
) * cezplus
4714 + (aexceyplus
+ cexaeyplus
) * dezplus
4715 + (cexdeyplus
+ dexceyplus
) * aezplus
)
4717 + ((aexbeyplus
+ bexaeyplus
) * dezplus
4718 + (bexdeyplus
+ dexbeyplus
) * aezplus
4719 + (dexaeyplus
+ aexdeyplus
) * bezplus
)
4721 + ((bexceyplus
+ cexbeyplus
) * aezplus
4722 + (cexaeyplus
+ aexceyplus
) * bezplus
4723 + (aexbeyplus
+ bexaeyplus
) * cezplus
)
4725 errbound
= isperrboundA
* permanent
;
4726 if((det
> errbound
) || (-det
> errbound
))
4732 ins
= insphereadapt(pa
, pb
, pc
, pd
, pe
, permanent
);