Shiny 3D eye-candy
[geda-pcb/pcjc2.git] / gts / predicates.c
blob7b7fcf27d0e8409a115d1f39039654f58409beb6
1 /*****************************************************************************/
2 /* */
3 /* Routines for Arbitrary Precision Floating-point Arithmetic */
4 /* and Fast Robust Geometric Predicates */
5 /* (predicates.c) */
6 /* */
7 /* May 18, 1996 */
8 /* */
9 /* Placed in the public domain by */
10 /* Jonathan Richard Shewchuk */
11 /* School of Computer Science */
12 /* Carnegie Mellon University */
13 /* 5000 Forbes Avenue */
14 /* Pittsburgh, Pennsylvania 15213-3891 */
15 /* jrs@cs.cmu.edu */
16 /* */
17 /* This file contains C implementation of algorithms for exact addition */
18 /* and multiplication of floating-point numbers, and predicates for */
19 /* robustly performing the orientation and incircle tests used in */
20 /* computational geometry. The algorithms and underlying theory are */
21 /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
22 /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
23 /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
24 /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
25 /* Discrete & Computational Geometry.) */
26 /* */
27 /* This file, the paper listed above, and other information are available */
28 /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
29 /* */
30 /*****************************************************************************/
32 /*****************************************************************************/
33 /* */
34 /* Using this code: */
35 /* */
36 /* First, read the short or long version of the paper (from the Web page */
37 /* above). */
38 /* */
39 /* Be sure to call exactinit() once, before calling any of the arithmetic */
40 /* functions or geometric predicates. Also be sure to turn on the */
41 /* optimizer when compiling this file. */
42 /* */
43 /* */
44 /* Several geometric predicates are defined. Their parameters are all */
45 /* points. Each point is an array of two or three floating-point */
46 /* numbers. The geometric predicates, described in the papers, are */
47 /* */
48 /* orient2d(pa, pb, pc) */
49 /* orient2dfast(pa, pb, pc) */
50 /* orient3d(pa, pb, pc, pd) */
51 /* orient3dfast(pa, pb, pc, pd) */
52 /* incircle(pa, pb, pc, pd) */
53 /* incirclefast(pa, pb, pc, pd) */
54 /* insphere(pa, pb, pc, pd, pe) */
55 /* inspherefast(pa, pb, pc, pd, pe) */
56 /* */
57 /* Those with suffix "fast" are approximate, non-robust versions. Those */
58 /* without the suffix are adaptive precision, robust versions. There */
59 /* are also versions with the suffices "exact" and "slow", which are */
60 /* non-adaptive, exact arithmetic versions, which I use only for timings */
61 /* in my arithmetic papers. */
62 /* */
63 /* */
64 /* An expansion is represented by an array of floating-point numbers, */
65 /* sorted from smallest to largest magnitude (possibly with interspersed */
66 /* zeros). The length of each expansion is stored as a separate integer, */
67 /* and each arithmetic function returns an integer which is the length */
68 /* of the expansion it created. */
69 /* */
70 /* Several arithmetic functions are defined. Their parameters are */
71 /* */
72 /* e, f Input expansions */
73 /* elen, flen Lengths of input expansions (must be >= 1) */
74 /* h Output expansion */
75 /* b Input scalar */
76 /* */
77 /* The arithmetic functions are */
78 /* */
79 /* grow_expansion(elen, e, b, h) */
80 /* grow_expansion_zeroelim(elen, e, b, h) */
81 /* expansion_sum(elen, e, flen, f, h) */
82 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */
83 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */
84 /* fast_expansion_sum(elen, e, flen, f, h) */
85 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
86 /* linear_expansion_sum(elen, e, flen, f, h) */
87 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
88 /* scale_expansion(elen, e, b, h) */
89 /* scale_expansion_zeroelim(elen, e, b, h) */
90 /* compress(elen, e, h) */
91 /* */
92 /* All of these are described in the long version of the paper; some are */
93 /* described in the short version. All return an integer that is the */
94 /* length of h. Those with suffix _zeroelim perform zero elimination, */
95 /* and are recommended over their counterparts. The procedure */
96 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
97 /* processors that do not use the round-to-even tiebreaking rule) is */
98 /* recommended over expansion_sum_zeroelim(). Each procedure has a */
99 /* little note next to it (in the code below) that tells you whether or */
100 /* not the output expansion may be the same array as one of the input */
101 /* expansions. */
102 /* */
103 /* */
104 /* If you look around below, you'll also find macros for a bunch of */
105 /* simple unrolled arithmetic operations, and procedures for printing */
106 /* expansions (commented out because they don't work with all C */
107 /* compilers) and for generating random floating-point numbers whose */
108 /* significand bits are all random. Most of the macros have undocumented */
109 /* requirements that certain of their parameters should not be the same */
110 /* variable; for safety, better to make sure all the parameters are */
111 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
112 /* have questions. */
113 /* */
114 /*****************************************************************************/
116 #include <stdio.h>
117 #include <stdlib.h>
118 #include <math.h>
119 #include "predicates.h"
121 /* Use header file generated automatically by predicates_init. */
122 //#define USE_PREDICATES_INIT
124 #ifdef USE_PREDICATES_INIT
125 #include "predicates_init.h"
126 #endif /* USE_PREDICATES_INIT */
128 /* FPU control. We MUST have only double precision (not extended precision) */
129 #include "rounding.h"
131 /* On some machines, the exact arithmetic routines might be defeated by the */
132 /* use of internal extended precision floating-point registers. Sometimes */
133 /* this problem can be fixed by defining certain values to be volatile, */
134 /* thus forcing them to be stored to memory and rounded off. This isn't */
135 /* a great solution, though, as it slows the arithmetic down. */
136 /* */
137 /* To try this out, write "#define INEXACT volatile" below. Normally, */
138 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
140 #define INEXACT /* Nothing */
141 /* #define INEXACT volatile */
143 #define REAL double /* float or double */
144 #define REALPRINT doubleprint
145 #define REALRAND doublerand
146 #define NARROWRAND narrowdoublerand
147 #define UNIFORMRAND uniformdoublerand
149 /* Which of the following two methods of finding the absolute values is */
150 /* fastest is compiler-dependent. A few compilers can inline and optimize */
151 /* the fabs() call; but most will incur the overhead of a function call, */
152 /* which is disastrously slow. A faster way on IEEE machines might be to */
153 /* mask the appropriate bit, but that's difficult to do in C. */
155 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
156 /* #define Absolute(a) fabs(a) */
158 /* Many of the operations are broken up into two pieces, a main part that */
159 /* performs an approximate operation, and a "tail" that computes the */
160 /* roundoff error of that operation. */
161 /* */
162 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
163 /* Split(), and Two_Product() are all implemented as described in the */
164 /* reference. Each of these macros requires certain variables to be */
165 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
166 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
167 /* they store the result of an operation that may incur roundoff error. */
168 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
169 /* also be declared `INEXACT'. */
171 #define Fast_Two_Sum_Tail(a, b, x, y) \
172 bvirt = x - a; \
173 y = b - bvirt
175 #define Fast_Two_Sum(a, b, x, y) \
176 x = (REAL) (a + b); \
177 Fast_Two_Sum_Tail(a, b, x, y)
179 #define Fast_Two_Diff_Tail(a, b, x, y) \
180 bvirt = a - x; \
181 y = bvirt - b
183 #define Fast_Two_Diff(a, b, x, y) \
184 x = (REAL) (a - b); \
185 Fast_Two_Diff_Tail(a, b, x, y)
187 #define Two_Sum_Tail(a, b, x, y) \
188 bvirt = (REAL) (x - a); \
189 avirt = x - bvirt; \
190 bround = b - bvirt; \
191 around = a - avirt; \
192 y = around + bround
194 #define Two_Sum(a, b, x, y) \
195 x = (REAL) (a + b); \
196 Two_Sum_Tail(a, b, x, y)
198 #define Two_Diff_Tail(a, b, x, y) \
199 bvirt = (REAL) (a - x); \
200 avirt = x + bvirt; \
201 bround = bvirt - b; \
202 around = a - avirt; \
203 y = around + bround
205 #define Two_Diff(a, b, x, y) \
206 x = (REAL) (a - b); \
207 Two_Diff_Tail(a, b, x, y)
209 #define Split(a, ahi, alo) \
210 c = (REAL) (splitter * a); \
211 abig = (REAL) (c - a); \
212 ahi = c - abig; \
213 alo = a - ahi
215 #define Two_Product_Tail(a, b, x, y) \
216 Split(a, ahi, alo); \
217 Split(b, bhi, blo); \
218 err1 = x - (ahi * bhi); \
219 err2 = err1 - (alo * bhi); \
220 err3 = err2 - (ahi * blo); \
221 y = (alo * blo) - err3
223 #define Two_Product(a, b, x, y) \
224 x = (REAL) (a * b); \
225 Two_Product_Tail(a, b, x, y)
227 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
228 /* already been split. Avoids redundant splitting. */
230 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
231 x = (REAL) (a * b); \
232 Split(a, ahi, alo); \
233 err1 = x - (ahi * bhi); \
234 err2 = err1 - (alo * bhi); \
235 err3 = err2 - (ahi * blo); \
236 y = (alo * blo) - err3
238 /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
239 /* already been split. Avoids redundant splitting. */
241 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
242 x = (REAL) (a * b); \
243 err1 = x - (ahi * bhi); \
244 err2 = err1 - (alo * bhi); \
245 err3 = err2 - (ahi * blo); \
246 y = (alo * blo) - err3
248 /* Square() can be done more quickly than Two_Product(). */
250 #define Square_Tail(a, x, y) \
251 Split(a, ahi, alo); \
252 err1 = x - (ahi * ahi); \
253 err3 = err1 - ((ahi + ahi) * alo); \
254 y = (alo * alo) - err3
256 #define Square(a, x, y) \
257 x = (REAL) (a * a); \
258 Square_Tail(a, x, y)
260 /* Macros for summing expansions of various fixed lengths. These are all */
261 /* unrolled versions of Expansion_Sum(). */
263 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
264 Two_Sum(a0, b , _i, x0); \
265 Two_Sum(a1, _i, x2, x1)
267 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
268 Two_Diff(a0, b , _i, x0); \
269 Two_Sum( a1, _i, x2, x1)
271 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
272 Two_One_Sum(a1, a0, b0, _j, _0, x0); \
273 Two_One_Sum(_j, _0, b1, x3, x2, x1)
275 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
276 Two_One_Diff(a1, a0, b0, _j, _0, x0); \
277 Two_One_Diff(_j, _0, b1, x3, x2, x1)
279 #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
280 Two_One_Sum(a1, a0, b , _j, x1, x0); \
281 Two_One_Sum(a3, a2, _j, x4, x3, x2)
283 #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
284 Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
285 Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
287 #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
288 x1, x0) \
289 Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
290 Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
292 #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
293 x3, x2, x1, x0) \
294 Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
295 Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
297 #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
298 x6, x5, x4, x3, x2, x1, x0) \
299 Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
300 _1, _0, x0); \
301 Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
302 x3, x2, x1)
304 #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
305 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
306 Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
307 _2, _1, _0, x1, x0); \
308 Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
309 x7, x6, x5, x4, x3, x2)
311 /* Macros for multiplying expansions of various fixed lengths. */
313 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
314 Split(b, bhi, blo); \
315 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
316 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
317 Two_Sum(_i, _0, _k, x1); \
318 Fast_Two_Sum(_j, _k, x3, x2)
320 #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
321 Split(b, bhi, blo); \
322 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
323 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
324 Two_Sum(_i, _0, _k, x1); \
325 Fast_Two_Sum(_j, _k, _i, x2); \
326 Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
327 Two_Sum(_i, _0, _k, x3); \
328 Fast_Two_Sum(_j, _k, _i, x4); \
329 Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
330 Two_Sum(_i, _0, _k, x5); \
331 Fast_Two_Sum(_j, _k, x7, x6)
333 #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
334 Split(a0, a0hi, a0lo); \
335 Split(b0, bhi, blo); \
336 Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
337 Split(a1, a1hi, a1lo); \
338 Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
339 Two_Sum(_i, _0, _k, _1); \
340 Fast_Two_Sum(_j, _k, _l, _2); \
341 Split(b1, bhi, blo); \
342 Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
343 Two_Sum(_1, _0, _k, x1); \
344 Two_Sum(_2, _k, _j, _1); \
345 Two_Sum(_l, _j, _m, _2); \
346 Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
347 Two_Sum(_i, _0, _n, _0); \
348 Two_Sum(_1, _0, _i, x2); \
349 Two_Sum(_2, _i, _k, _1); \
350 Two_Sum(_m, _k, _l, _2); \
351 Two_Sum(_j, _n, _k, _0); \
352 Two_Sum(_1, _0, _j, x3); \
353 Two_Sum(_2, _j, _i, _1); \
354 Two_Sum(_l, _i, _m, _2); \
355 Two_Sum(_1, _k, _i, x4); \
356 Two_Sum(_2, _i, _k, x5); \
357 Two_Sum(_m, _k, x7, x6)
359 /* An expansion of length two can be squared more quickly than finding the */
360 /* product of two different expansions of length two, and the result is */
361 /* guaranteed to have no more than six (rather than eight) components. */
363 #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
364 Square(a0, _j, x0); \
365 _0 = a0 + a0; \
366 Two_Product(a1, _0, _k, _1); \
367 Two_One_Sum(_k, _1, _j, _l, _2, x1); \
368 Square(a1, _j, _1); \
369 Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
371 #ifndef USE_PREDICATES_INIT
373 static REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
374 /* A set of coefficients used to calculate maximum roundoff errors. */
375 static REAL resulterrbound;
376 static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
377 static REAL o3derrboundA, o3derrboundB, o3derrboundC;
378 static REAL iccerrboundA, iccerrboundB, iccerrboundC;
379 static REAL isperrboundA, isperrboundB, isperrboundC;
381 void
382 gts_predicates_init()
384 double half = 0.5;
385 double check = 1.0, lastcheck;
386 int every_other = 1;
387 /* epsilon = 2^(-p). Used to estimate roundoff errors. */
388 double epsilon = 1.0;
390 FPU_ROUND_DOUBLE;
392 splitter = 1.;
394 /* Repeatedly divide `epsilon' by two until it is too small to add to */
395 /* one without causing roundoff. (Also check if the sum is equal to */
396 /* the previous sum, for machines that round up instead of using exact */
397 /* rounding. Not that this library will work on such machines anyway). */
398 do {
399 lastcheck = check;
400 epsilon *= half;
401 if (every_other) {
402 splitter *= 2.0;
404 every_other = !every_other;
405 check = 1.0 + epsilon;
406 } while ((check != 1.0) && (check != lastcheck));
407 splitter += 1.0;
408 /* Error bounds for orientation and incircle tests. */
409 resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
410 ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
411 ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
412 ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
413 o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
414 o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
415 o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
416 iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
417 iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
418 iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
419 isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
420 isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
421 isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
424 FPU_RESTORE;
427 #endif /* USE_PREDICATES_INIT */
429 /*****************************************************************************/
430 /* */
431 /* doubleprint() Print the bit representation of a double. */
432 /* */
433 /* Useful for debugging exact arithmetic routines. */
434 /* */
435 /*****************************************************************************/
438 void doubleprint(number)
439 double number;
441 unsigned long long no;
442 unsigned long long sign, expo;
443 int exponent;
444 int i, bottomi;
446 no = *(unsigned long long *) &number;
447 sign = no & 0x8000000000000000ll;
448 expo = (no >> 52) & 0x7ffll;
449 exponent = (int) expo;
450 exponent = exponent - 1023;
451 if (sign) {
452 printf("-");
453 } else {
454 printf(" ");
456 if (exponent == -1023) {
457 printf(
458 "0.0000000000000000000000000000000000000000000000000000_ ( )");
459 } else {
460 printf("1.");
461 bottomi = -1;
462 for (i = 0; i < 52; i++) {
463 if (no & 0x0008000000000000ll) {
464 printf("1");
465 bottomi = i;
466 } else {
467 printf("0");
469 no <<= 1;
471 printf("_%d (%d)", exponent, exponent - 1 - bottomi);
476 /*****************************************************************************/
477 /* */
478 /* floatprint() Print the bit representation of a float. */
479 /* */
480 /* Useful for debugging exact arithmetic routines. */
481 /* */
482 /*****************************************************************************/
485 void floatprint(number)
486 float number;
488 unsigned no;
489 unsigned sign, expo;
490 int exponent;
491 int i, bottomi;
493 no = *(unsigned *) &number;
494 sign = no & 0x80000000;
495 expo = (no >> 23) & 0xff;
496 exponent = (int) expo;
497 exponent = exponent - 127;
498 if (sign) {
499 printf("-");
500 } else {
501 printf(" ");
503 if (exponent == -127) {
504 printf("0.00000000000000000000000_ ( )");
505 } else {
506 printf("1.");
507 bottomi = -1;
508 for (i = 0; i < 23; i++) {
509 if (no & 0x00400000) {
510 printf("1");
511 bottomi = i;
512 } else {
513 printf("0");
515 no <<= 1;
517 printf("_%3d (%3d)", exponent, exponent - 1 - bottomi);
522 /*****************************************************************************/
523 /* */
524 /* expansion_print() Print the bit representation of an expansion. */
525 /* */
526 /* Useful for debugging exact arithmetic routines. */
527 /* */
528 /*****************************************************************************/
531 void expansion_print(elen, e)
532 int elen;
533 REAL *e;
535 int i;
537 for (i = elen - 1; i >= 0; i--) {
538 REALPRINT(e[i]);
539 if (i > 0) {
540 printf(" +\n");
541 } else {
542 printf("\n");
548 /*****************************************************************************/
549 /* */
550 /* doublerand() Generate a double with random 53-bit significand and a */
551 /* random exponent in [0, 511]. */
552 /* */
553 /*****************************************************************************/
556 static double doublerand()
558 double result;
559 double expo;
560 long a, b, c;
561 long i;
563 a = random();
564 b = random();
565 c = random();
566 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
567 for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) {
568 if (c & i) {
569 result *= expo;
572 return result;
576 /*****************************************************************************/
577 /* */
578 /* narrowdoublerand() Generate a double with random 53-bit significand */
579 /* and a random exponent in [0, 7]. */
580 /* */
581 /*****************************************************************************/
584 static double narrowdoublerand()
586 double result;
587 double expo;
588 long a, b, c;
589 long i;
591 a = random();
592 b = random();
593 c = random();
594 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
595 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
596 if (c & i) {
597 result *= expo;
600 return result;
604 /*****************************************************************************/
605 /* */
606 /* uniformdoublerand() Generate a double with random 53-bit significand. */
607 /* */
608 /*****************************************************************************/
611 static double uniformdoublerand()
613 double result;
614 long a, b;
616 a = random();
617 b = random();
618 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
619 return result;
623 /*****************************************************************************/
624 /* */
625 /* floatrand() Generate a float with random 24-bit significand and a */
626 /* random exponent in [0, 63]. */
627 /* */
628 /*****************************************************************************/
631 static float floatrand()
633 float result;
634 float expo;
635 long a, c;
636 long i;
638 a = random();
639 c = random();
640 result = (float) ((a - 1073741824) >> 6);
641 for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) {
642 if (c & i) {
643 result *= expo;
646 return result;
650 /*****************************************************************************/
651 /* */
652 /* narrowfloatrand() Generate a float with random 24-bit significand and */
653 /* a random exponent in [0, 7]. */
654 /* */
655 /*****************************************************************************/
658 static float narrowfloatrand()
660 float result;
661 float expo;
662 long a, c;
663 long i;
665 a = random();
666 c = random();
667 result = (float) ((a - 1073741824) >> 6);
668 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
669 if (c & i) {
670 result *= expo;
673 return result;
677 /*****************************************************************************/
678 /* */
679 /* uniformfloatrand() Generate a float with random 24-bit significand. */
680 /* */
681 /*****************************************************************************/
684 static float uniformfloatrand()
686 float result;
687 long a;
689 a = random();
690 result = (float) ((a - 1073741824) >> 6);
691 return result;
695 /*****************************************************************************/
696 /* */
697 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
698 /* components from the output expansion. */
699 /* */
700 /* Sets h = e + f. See the long version of my paper for details. */
701 /* */
702 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
703 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
704 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
705 /* properties. */
706 /* */
707 /*****************************************************************************/
709 static int fast_expansion_sum_zeroelim(int elen, REAL *e,
710 int flen, REAL *f, REAL *h)
711 /* h cannot be e or f. */
713 REAL Q;
714 INEXACT REAL Qnew;
715 INEXACT REAL hh;
716 INEXACT REAL bvirt;
717 REAL avirt, bround, around;
718 int eindex, findex, hindex;
719 REAL enow, fnow;
721 enow = e[0];
722 fnow = f[0];
723 eindex = findex = 0;
724 if ((fnow > enow) == (fnow > -enow)) {
725 Q = enow;
726 enow = e[++eindex];
727 } else {
728 Q = fnow;
729 fnow = f[++findex];
731 hindex = 0;
732 if ((eindex < elen) && (findex < flen)) {
733 if ((fnow > enow) == (fnow > -enow)) {
734 Fast_Two_Sum(enow, Q, Qnew, hh);
735 enow = e[++eindex];
736 } else {
737 Fast_Two_Sum(fnow, Q, Qnew, hh);
738 fnow = f[++findex];
740 Q = Qnew;
741 if (hh != 0.0) {
742 h[hindex++] = hh;
744 while ((eindex < elen) && (findex < flen)) {
745 if ((fnow > enow) == (fnow > -enow)) {
746 Two_Sum(Q, enow, Qnew, hh);
747 enow = e[++eindex];
748 } else {
749 Two_Sum(Q, fnow, Qnew, hh);
750 fnow = f[++findex];
752 Q = Qnew;
753 if (hh != 0.0) {
754 h[hindex++] = hh;
758 while (eindex < elen) {
759 Two_Sum(Q, enow, Qnew, hh);
760 enow = e[++eindex];
761 Q = Qnew;
762 if (hh != 0.0) {
763 h[hindex++] = hh;
766 while (findex < flen) {
767 Two_Sum(Q, fnow, Qnew, hh);
768 fnow = f[++findex];
769 Q = Qnew;
770 if (hh != 0.0) {
771 h[hindex++] = hh;
774 if ((Q != 0.0) || (hindex == 0)) {
775 h[hindex++] = Q;
777 return hindex;
780 /*****************************************************************************/
781 /* */
782 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
783 /* eliminating zero components from the */
784 /* output expansion. */
785 /* */
786 /* Sets h = be. See either version of my paper for details. */
787 /* */
788 /* Maintains the nonoverlapping property. If round-to-even is used (as */
789 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
790 /* properties as well. (That is, if e has one of these properties, so */
791 /* will h.) */
792 /* */
793 /*****************************************************************************/
795 static int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)
796 /* e and h cannot be the same. */
798 INEXACT REAL Q, sum;
799 REAL hh;
800 INEXACT REAL product1;
801 REAL product0;
802 int eindex, hindex;
803 REAL enow;
804 INEXACT REAL bvirt;
805 REAL avirt, bround, around;
806 INEXACT REAL c;
807 INEXACT REAL abig;
808 REAL ahi, alo, bhi, blo;
809 REAL err1, err2, err3;
811 Split(b, bhi, blo);
812 Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
813 hindex = 0;
814 if (hh != 0) {
815 h[hindex++] = hh;
817 for (eindex = 1; eindex < elen; eindex++) {
818 enow = e[eindex];
819 Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
820 Two_Sum(Q, product0, sum, hh);
821 if (hh != 0) {
822 h[hindex++] = hh;
824 Fast_Two_Sum(product1, sum, Q, hh);
825 if (hh != 0) {
826 h[hindex++] = hh;
829 if ((Q != 0.0) || (hindex == 0)) {
830 h[hindex++] = Q;
832 return hindex;
835 /*****************************************************************************/
836 /* */
837 /* estimate() Produce a one-word estimate of an expansion's value. */
838 /* */
839 /* See either version of my paper for details. */
840 /* */
841 /*****************************************************************************/
843 static REAL estimate(int elen, REAL *e)
845 REAL Q;
846 int eindex;
848 Q = e[0];
849 for (eindex = 1; eindex < elen; eindex++) {
850 Q += e[eindex];
852 return Q;
855 /*****************************************************************************/
856 /* */
857 /* orient2dfast() Approximate 2D orientation test. Nonrobust. */
858 /* orient2dexact() Exact 2D orientation test. Robust. */
859 /* orient2dslow() Another exact 2D orientation test. Robust. */
860 /* orient2d() Adaptive exact 2D orientation test. Robust. */
861 /* */
862 /* Return a positive value if the points pa, pb, and pc occur */
863 /* in counterclockwise order; a negative value if they occur */
864 /* in clockwise order; and zero if they are collinear. The */
865 /* result is also a rough approximation of twice the signed */
866 /* area of the triangle defined by the three points. */
867 /* */
868 /* Only the first and last routine should be used; the middle two are for */
869 /* timings. */
870 /* */
871 /* The last three use exact arithmetic to ensure a correct answer. The */
872 /* result returned is the determinant of a matrix. In orient2d() only, */
873 /* this determinant is computed adaptively, in the sense that exact */
874 /* arithmetic is used only to the degree it is needed to ensure that the */
875 /* returned value has the correct sign. Hence, orient2d() is usually quite */
876 /* fast, but will run more slowly when the input points are collinear or */
877 /* nearly so. */
878 /* */
879 /*****************************************************************************/
881 static REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum)
883 INEXACT REAL acx, acy, bcx, bcy;
884 REAL acxtail, acytail, bcxtail, bcytail;
885 INEXACT REAL detleft, detright;
886 REAL detlefttail, detrighttail;
887 REAL det, errbound;
888 REAL B[4], C1[8], C2[12], D[16];
889 INEXACT REAL B3;
890 int C1length, C2length, Dlength;
891 REAL u[4];
892 INEXACT REAL u3;
893 INEXACT REAL s1, t1;
894 REAL s0, t0;
896 INEXACT REAL bvirt;
897 REAL avirt, bround, around;
898 INEXACT REAL c;
899 INEXACT REAL abig;
900 REAL ahi, alo, bhi, blo;
901 REAL err1, err2, err3;
902 INEXACT REAL _i, _j;
903 REAL _0;
905 acx = (REAL) (pa[0] - pc[0]);
906 bcx = (REAL) (pb[0] - pc[0]);
907 acy = (REAL) (pa[1] - pc[1]);
908 bcy = (REAL) (pb[1] - pc[1]);
910 Two_Product(acx, bcy, detleft, detlefttail);
911 Two_Product(acy, bcx, detright, detrighttail);
913 Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
914 B3, B[2], B[1], B[0]);
915 B[3] = B3;
917 det = estimate(4, B);
918 errbound = ccwerrboundB * detsum;
919 if ((det >= errbound) || (-det >= errbound)) {
920 return det;
923 Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
924 Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
925 Two_Diff_Tail(pa[1], pc[1], acy, acytail);
926 Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
928 if ((acxtail == 0.0) && (acytail == 0.0)
929 && (bcxtail == 0.0) && (bcytail == 0.0)) {
930 return det;
933 errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
934 det += (acx * bcytail + bcy * acxtail)
935 - (acy * bcxtail + bcx * acytail);
936 if ((det >= errbound) || (-det >= errbound)) {
937 return det;
940 Two_Product(acxtail, bcy, s1, s0);
941 Two_Product(acytail, bcx, t1, t0);
942 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
943 u[3] = u3;
944 C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
946 Two_Product(acx, bcytail, s1, s0);
947 Two_Product(acy, bcxtail, t1, t0);
948 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
949 u[3] = u3;
950 C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
952 Two_Product(acxtail, bcytail, s1, s0);
953 Two_Product(acytail, bcxtail, t1, t0);
954 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
955 u[3] = u3;
956 Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
958 return(D[Dlength - 1]);
961 REAL orient2d(pa, pb, pc)
962 REAL *pa;
963 REAL *pb;
964 REAL *pc;
966 REAL detleft, detright, det;
967 REAL detsum, errbound;
968 REAL orient;
970 FPU_ROUND_DOUBLE;
972 detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
973 detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
974 det = detleft - detright;
976 if (detleft > 0.0) {
977 if (detright <= 0.0) {
978 FPU_RESTORE;
979 return det;
980 } else {
981 detsum = detleft + detright;
983 } else if (detleft < 0.0) {
984 if (detright >= 0.0) {
985 FPU_RESTORE;
986 return det;
987 } else {
988 detsum = -detleft - detright;
990 } else {
991 FPU_RESTORE;
992 return det;
995 errbound = ccwerrboundA * detsum;
996 if ((det >= errbound) || (-det >= errbound)) {
997 FPU_RESTORE;
998 return det;
1001 orient = orient2dadapt(pa, pb, pc, detsum);
1002 FPU_RESTORE;
1003 return orient;
1006 /*****************************************************************************/
1007 /* */
1008 /* orient3dfast() Approximate 3D orientation test. Nonrobust. */
1009 /* orient3dexact() Exact 3D orientation test. Robust. */
1010 /* orient3dslow() Another exact 3D orientation test. Robust. */
1011 /* orient3d() Adaptive exact 3D orientation test. Robust. */
1012 /* */
1013 /* Return a positive value if the point pd lies below the */
1014 /* plane passing through pa, pb, and pc; "below" is defined so */
1015 /* that pa, pb, and pc appear in counterclockwise order when */
1016 /* viewed from above the plane. Returns a negative value if */
1017 /* pd lies above the plane. Returns zero if the points are */
1018 /* coplanar. The result is also a rough approximation of six */
1019 /* times the signed volume of the tetrahedron defined by the */
1020 /* four points. */
1021 /* */
1022 /* Only the first and last routine should be used; the middle two are for */
1023 /* timings. */
1024 /* */
1025 /* The last three use exact arithmetic to ensure a correct answer. The */
1026 /* result returned is the determinant of a matrix. In orient3d() only, */
1027 /* this determinant is computed adaptively, in the sense that exact */
1028 /* arithmetic is used only to the degree it is needed to ensure that the */
1029 /* returned value has the correct sign. Hence, orient3d() is usually quite */
1030 /* fast, but will run more slowly when the input points are coplanar or */
1031 /* nearly so. */
1032 /* */
1033 /*****************************************************************************/
1035 static REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd,
1036 REAL permanent)
1038 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
1039 REAL det, errbound;
1041 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
1042 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
1043 REAL bc[4], ca[4], ab[4];
1044 INEXACT REAL bc3, ca3, ab3;
1045 REAL adet[8], bdet[8], cdet[8];
1046 int alen, blen, clen;
1047 REAL abdet[16];
1048 int ablen;
1049 REAL *finnow, *finother, *finswap;
1050 REAL fin1[192], fin2[192];
1051 int finlength;
1053 REAL adxtail, bdxtail, cdxtail;
1054 REAL adytail, bdytail, cdytail;
1055 REAL adztail, bdztail, cdztail;
1056 INEXACT REAL at_blarge, at_clarge;
1057 INEXACT REAL bt_clarge, bt_alarge;
1058 INEXACT REAL ct_alarge, ct_blarge;
1059 REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
1060 int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
1061 INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
1062 INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
1063 REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
1064 REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
1065 INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
1066 INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
1067 REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
1068 REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
1069 REAL bct[8], cat[8], abt[8];
1070 int bctlen, catlen, abtlen;
1071 INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
1072 INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
1073 REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
1074 REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
1075 REAL u[4], v[12], w[16];
1076 INEXACT REAL u3;
1077 int vlength, wlength;
1078 REAL negate;
1080 INEXACT REAL bvirt;
1081 REAL avirt, bround, around;
1082 INEXACT REAL c;
1083 INEXACT REAL abig;
1084 REAL ahi, alo, bhi, blo;
1085 REAL err1, err2, err3;
1086 INEXACT REAL _i, _j, _k;
1087 REAL _0;
1089 adx = (REAL) (pa[0] - pd[0]);
1090 bdx = (REAL) (pb[0] - pd[0]);
1091 cdx = (REAL) (pc[0] - pd[0]);
1092 ady = (REAL) (pa[1] - pd[1]);
1093 bdy = (REAL) (pb[1] - pd[1]);
1094 cdy = (REAL) (pc[1] - pd[1]);
1095 adz = (REAL) (pa[2] - pd[2]);
1096 bdz = (REAL) (pb[2] - pd[2]);
1097 cdz = (REAL) (pc[2] - pd[2]);
1099 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
1100 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
1101 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
1102 bc[3] = bc3;
1103 alen = scale_expansion_zeroelim(4, bc, adz, adet);
1105 Two_Product(cdx, ady, cdxady1, cdxady0);
1106 Two_Product(adx, cdy, adxcdy1, adxcdy0);
1107 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
1108 ca[3] = ca3;
1109 blen = scale_expansion_zeroelim(4, ca, bdz, bdet);
1111 Two_Product(adx, bdy, adxbdy1, adxbdy0);
1112 Two_Product(bdx, ady, bdxady1, bdxady0);
1113 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
1114 ab[3] = ab3;
1115 clen = scale_expansion_zeroelim(4, ab, cdz, cdet);
1117 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
1118 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
1120 det = estimate(finlength, fin1);
1121 errbound = o3derrboundB * permanent;
1122 if ((det >= errbound) || (-det >= errbound)) {
1123 return det;
1126 Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
1127 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
1128 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
1129 Two_Diff_Tail(pa[1], pd[1], ady, adytail);
1130 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
1131 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
1132 Two_Diff_Tail(pa[2], pd[2], adz, adztail);
1133 Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);
1134 Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);
1136 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
1137 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)
1138 && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {
1139 return det;
1142 errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
1143 det += (adz * ((bdx * cdytail + cdy * bdxtail)
1144 - (bdy * cdxtail + cdx * bdytail))
1145 + adztail * (bdx * cdy - bdy * cdx))
1146 + (bdz * ((cdx * adytail + ady * cdxtail)
1147 - (cdy * adxtail + adx * cdytail))
1148 + bdztail * (cdx * ady - cdy * adx))
1149 + (cdz * ((adx * bdytail + bdy * adxtail)
1150 - (ady * bdxtail + bdx * adytail))
1151 + cdztail * (adx * bdy - ady * bdx));
1152 if ((det >= errbound) || (-det >= errbound)) {
1153 return det;
1156 finnow = fin1;
1157 finother = fin2;
1159 if (adxtail == 0.0) {
1160 if (adytail == 0.0) {
1161 at_b[0] = 0.0;
1162 at_blen = 1;
1163 at_c[0] = 0.0;
1164 at_clen = 1;
1165 } else {
1166 negate = -adytail;
1167 Two_Product(negate, bdx, at_blarge, at_b[0]);
1168 at_b[1] = at_blarge;
1169 at_blen = 2;
1170 Two_Product(adytail, cdx, at_clarge, at_c[0]);
1171 at_c[1] = at_clarge;
1172 at_clen = 2;
1174 } else {
1175 if (adytail == 0.0) {
1176 Two_Product(adxtail, bdy, at_blarge, at_b[0]);
1177 at_b[1] = at_blarge;
1178 at_blen = 2;
1179 negate = -adxtail;
1180 Two_Product(negate, cdy, at_clarge, at_c[0]);
1181 at_c[1] = at_clarge;
1182 at_clen = 2;
1183 } else {
1184 Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
1185 Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
1186 Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
1187 at_blarge, at_b[2], at_b[1], at_b[0]);
1188 at_b[3] = at_blarge;
1189 at_blen = 4;
1190 Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
1191 Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
1192 Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
1193 at_clarge, at_c[2], at_c[1], at_c[0]);
1194 at_c[3] = at_clarge;
1195 at_clen = 4;
1198 if (bdxtail == 0.0) {
1199 if (bdytail == 0.0) {
1200 bt_c[0] = 0.0;
1201 bt_clen = 1;
1202 bt_a[0] = 0.0;
1203 bt_alen = 1;
1204 } else {
1205 negate = -bdytail;
1206 Two_Product(negate, cdx, bt_clarge, bt_c[0]);
1207 bt_c[1] = bt_clarge;
1208 bt_clen = 2;
1209 Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
1210 bt_a[1] = bt_alarge;
1211 bt_alen = 2;
1213 } else {
1214 if (bdytail == 0.0) {
1215 Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
1216 bt_c[1] = bt_clarge;
1217 bt_clen = 2;
1218 negate = -bdxtail;
1219 Two_Product(negate, ady, bt_alarge, bt_a[0]);
1220 bt_a[1] = bt_alarge;
1221 bt_alen = 2;
1222 } else {
1223 Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
1224 Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
1225 Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
1226 bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
1227 bt_c[3] = bt_clarge;
1228 bt_clen = 4;
1229 Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
1230 Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
1231 Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
1232 bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
1233 bt_a[3] = bt_alarge;
1234 bt_alen = 4;
1237 if (cdxtail == 0.0) {
1238 if (cdytail == 0.0) {
1239 ct_a[0] = 0.0;
1240 ct_alen = 1;
1241 ct_b[0] = 0.0;
1242 ct_blen = 1;
1243 } else {
1244 negate = -cdytail;
1245 Two_Product(negate, adx, ct_alarge, ct_a[0]);
1246 ct_a[1] = ct_alarge;
1247 ct_alen = 2;
1248 Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
1249 ct_b[1] = ct_blarge;
1250 ct_blen = 2;
1252 } else {
1253 if (cdytail == 0.0) {
1254 Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
1255 ct_a[1] = ct_alarge;
1256 ct_alen = 2;
1257 negate = -cdxtail;
1258 Two_Product(negate, bdy, ct_blarge, ct_b[0]);
1259 ct_b[1] = ct_blarge;
1260 ct_blen = 2;
1261 } else {
1262 Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
1263 Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
1264 Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
1265 ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
1266 ct_a[3] = ct_alarge;
1267 ct_alen = 4;
1268 Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
1269 Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
1270 Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
1271 ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
1272 ct_b[3] = ct_blarge;
1273 ct_blen = 4;
1277 bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
1278 wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);
1279 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1280 finother);
1281 finswap = finnow; finnow = finother; finother = finswap;
1283 catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
1284 wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);
1285 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1286 finother);
1287 finswap = finnow; finnow = finother; finother = finswap;
1289 abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
1290 wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);
1291 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1292 finother);
1293 finswap = finnow; finnow = finother; finother = finswap;
1295 if (adztail != 0.0) {
1296 vlength = scale_expansion_zeroelim(4, bc, adztail, v);
1297 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
1298 finother);
1299 finswap = finnow; finnow = finother; finother = finswap;
1301 if (bdztail != 0.0) {
1302 vlength = scale_expansion_zeroelim(4, ca, bdztail, v);
1303 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
1304 finother);
1305 finswap = finnow; finnow = finother; finother = finswap;
1307 if (cdztail != 0.0) {
1308 vlength = scale_expansion_zeroelim(4, ab, cdztail, v);
1309 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
1310 finother);
1311 finswap = finnow; finnow = finother; finother = finswap;
1314 if (adxtail != 0.0) {
1315 if (bdytail != 0.0) {
1316 Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
1317 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);
1318 u[3] = u3;
1319 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1320 finother);
1321 finswap = finnow; finnow = finother; finother = finswap;
1322 if (cdztail != 0.0) {
1323 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);
1324 u[3] = u3;
1325 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1326 finother);
1327 finswap = finnow; finnow = finother; finother = finswap;
1330 if (cdytail != 0.0) {
1331 negate = -adxtail;
1332 Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
1333 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);
1334 u[3] = u3;
1335 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1336 finother);
1337 finswap = finnow; finnow = finother; finother = finswap;
1338 if (bdztail != 0.0) {
1339 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);
1340 u[3] = u3;
1341 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1342 finother);
1343 finswap = finnow; finnow = finother; finother = finswap;
1347 if (bdxtail != 0.0) {
1348 if (cdytail != 0.0) {
1349 Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
1350 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);
1351 u[3] = u3;
1352 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1353 finother);
1354 finswap = finnow; finnow = finother; finother = finswap;
1355 if (adztail != 0.0) {
1356 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);
1357 u[3] = u3;
1358 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1359 finother);
1360 finswap = finnow; finnow = finother; finother = finswap;
1363 if (adytail != 0.0) {
1364 negate = -bdxtail;
1365 Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
1366 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);
1367 u[3] = u3;
1368 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1369 finother);
1370 finswap = finnow; finnow = finother; finother = finswap;
1371 if (cdztail != 0.0) {
1372 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);
1373 u[3] = u3;
1374 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1375 finother);
1376 finswap = finnow; finnow = finother; finother = finswap;
1380 if (cdxtail != 0.0) {
1381 if (adytail != 0.0) {
1382 Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
1383 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);
1384 u[3] = u3;
1385 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1386 finother);
1387 finswap = finnow; finnow = finother; finother = finswap;
1388 if (bdztail != 0.0) {
1389 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);
1390 u[3] = u3;
1391 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1392 finother);
1393 finswap = finnow; finnow = finother; finother = finswap;
1396 if (bdytail != 0.0) {
1397 negate = -cdxtail;
1398 Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
1399 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);
1400 u[3] = u3;
1401 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1402 finother);
1403 finswap = finnow; finnow = finother; finother = finswap;
1404 if (adztail != 0.0) {
1405 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);
1406 u[3] = u3;
1407 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
1408 finother);
1409 finswap = finnow; finnow = finother; finother = finswap;
1414 if (adztail != 0.0) {
1415 wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);
1416 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1417 finother);
1418 finswap = finnow; finnow = finother; finother = finswap;
1420 if (bdztail != 0.0) {
1421 wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);
1422 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1423 finother);
1424 finswap = finnow; finnow = finother; finother = finswap;
1426 if (cdztail != 0.0) {
1427 wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);
1428 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
1429 finother);
1430 finswap = finnow; finnow = finother; finother = finswap;
1433 return finnow[finlength - 1];
1436 REAL orient3d(pa, pb, pc, pd)
1437 REAL *pa;
1438 REAL *pb;
1439 REAL *pc;
1440 REAL *pd;
1442 REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
1443 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
1444 REAL det;
1445 REAL permanent, errbound;
1446 REAL orient;
1448 FPU_ROUND_DOUBLE;
1450 adx = pa[0] - pd[0];
1451 bdx = pb[0] - pd[0];
1452 cdx = pc[0] - pd[0];
1453 ady = pa[1] - pd[1];
1454 bdy = pb[1] - pd[1];
1455 cdy = pc[1] - pd[1];
1456 adz = pa[2] - pd[2];
1457 bdz = pb[2] - pd[2];
1458 cdz = pc[2] - pd[2];
1460 bdxcdy = bdx * cdy;
1461 cdxbdy = cdx * bdy;
1463 cdxady = cdx * ady;
1464 adxcdy = adx * cdy;
1466 adxbdy = adx * bdy;
1467 bdxady = bdx * ady;
1469 det = adz * (bdxcdy - cdxbdy)
1470 + bdz * (cdxady - adxcdy)
1471 + cdz * (adxbdy - bdxady);
1473 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz)
1474 + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz)
1475 + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);
1476 errbound = o3derrboundA * permanent;
1477 if ((det > errbound) || (-det > errbound)) {
1478 FPU_RESTORE;
1479 return det;
1482 orient = orient3dadapt(pa, pb, pc, pd, permanent);
1483 FPU_RESTORE;
1484 return orient;
1487 /*****************************************************************************/
1488 /* */
1489 /* incirclefast() Approximate 2D incircle test. Nonrobust. */
1490 /* incircleexact() Exact 2D incircle test. Robust. */
1491 /* incircleslow() Another exact 2D incircle test. Robust. */
1492 /* incircle() Adaptive exact 2D incircle test. Robust. */
1493 /* */
1494 /* Return a positive value if the point pd lies inside the */
1495 /* circle passing through pa, pb, and pc; a negative value if */
1496 /* it lies outside; and zero if the four points are cocircular.*/
1497 /* The points pa, pb, and pc must be in counterclockwise */
1498 /* order, or the sign of the result will be reversed. */
1499 /* */
1500 /* Only the first and last routine should be used; the middle two are for */
1501 /* timings. */
1502 /* */
1503 /* The last three use exact arithmetic to ensure a correct answer. The */
1504 /* result returned is the determinant of a matrix. In incircle() only, */
1505 /* this determinant is computed adaptively, in the sense that exact */
1506 /* arithmetic is used only to the degree it is needed to ensure that the */
1507 /* returned value has the correct sign. Hence, incircle() is usually quite */
1508 /* fast, but will run more slowly when the input points are cocircular or */
1509 /* nearly so. */
1510 /* */
1511 /*****************************************************************************/
1513 static REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd,
1514 REAL permanent)
1516 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
1517 REAL det, errbound;
1519 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
1520 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
1521 REAL bc[4], ca[4], ab[4];
1522 INEXACT REAL bc3, ca3, ab3;
1523 REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
1524 int axbclen, axxbclen, aybclen, ayybclen, alen;
1525 REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
1526 int bxcalen, bxxcalen, bycalen, byycalen, blen;
1527 REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
1528 int cxablen, cxxablen, cyablen, cyyablen, clen;
1529 REAL abdet[64];
1530 int ablen;
1531 REAL fin1[1152], fin2[1152];
1532 REAL *finnow, *finother, *finswap;
1533 int finlength;
1535 REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
1536 INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
1537 REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
1538 REAL aa[4], bb[4], cc[4];
1539 INEXACT REAL aa3, bb3, cc3;
1540 INEXACT REAL ti1, tj1;
1541 REAL ti0, tj0;
1542 REAL u[4], v[4];
1543 INEXACT REAL u3, v3;
1544 REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
1545 REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
1546 int temp8len, temp16alen, temp16blen, temp16clen;
1547 int temp32alen, temp32blen, temp48len, temp64len;
1548 REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
1549 int axtbblen, axtcclen, aytbblen, aytcclen;
1550 REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
1551 int bxtaalen, bxtcclen, bytaalen, bytcclen;
1552 REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
1553 int cxtaalen, cxtbblen, cytaalen, cytbblen;
1554 REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
1555 int axtbclen = 0, aytbclen = 0;
1556 int bxtcalen = 0, bytcalen = 0;
1557 int cxtablen = 0, cytablen = 0;
1558 REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
1559 int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
1560 REAL axtbctt[8], aytbctt[8], bxtcatt[8];
1561 REAL bytcatt[8], cxtabtt[8], cytabtt[8];
1562 int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
1563 REAL abt[8], bct[8], cat[8];
1564 int abtlen, bctlen, catlen;
1565 REAL abtt[4], bctt[4], catt[4];
1566 int abttlen, bcttlen, cattlen;
1567 INEXACT REAL abtt3, bctt3, catt3;
1568 REAL negate;
1570 INEXACT REAL bvirt;
1571 REAL avirt, bround, around;
1572 INEXACT REAL c;
1573 INEXACT REAL abig;
1574 REAL ahi, alo, bhi, blo;
1575 REAL err1, err2, err3;
1576 INEXACT REAL _i, _j;
1577 REAL _0;
1579 adx = (REAL) (pa[0] - pd[0]);
1580 bdx = (REAL) (pb[0] - pd[0]);
1581 cdx = (REAL) (pc[0] - pd[0]);
1582 ady = (REAL) (pa[1] - pd[1]);
1583 bdy = (REAL) (pb[1] - pd[1]);
1584 cdy = (REAL) (pc[1] - pd[1]);
1586 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
1587 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
1588 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
1589 bc[3] = bc3;
1590 axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
1591 axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
1592 aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
1593 ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
1594 alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
1596 Two_Product(cdx, ady, cdxady1, cdxady0);
1597 Two_Product(adx, cdy, adxcdy1, adxcdy0);
1598 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
1599 ca[3] = ca3;
1600 bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
1601 bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
1602 bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
1603 byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
1604 blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
1606 Two_Product(adx, bdy, adxbdy1, adxbdy0);
1607 Two_Product(bdx, ady, bdxady1, bdxady0);
1608 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
1609 ab[3] = ab3;
1610 cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
1611 cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
1612 cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
1613 cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
1614 clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
1616 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
1617 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
1619 det = estimate(finlength, fin1);
1620 errbound = iccerrboundB * permanent;
1621 if ((det >= errbound) || (-det >= errbound)) {
1622 return det;
1625 Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
1626 Two_Diff_Tail(pa[1], pd[1], ady, adytail);
1627 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
1628 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
1629 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
1630 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
1631 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
1632 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
1633 return det;
1636 errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
1637 det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
1638 - (bdy * cdxtail + cdx * bdytail))
1639 + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
1640 + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
1641 - (cdy * adxtail + adx * cdytail))
1642 + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
1643 + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
1644 - (ady * bdxtail + bdx * adytail))
1645 + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
1646 if ((det >= errbound) || (-det >= errbound)) {
1647 return det;
1650 finnow = fin1;
1651 finother = fin2;
1653 if ((bdxtail != 0.0) || (bdytail != 0.0)
1654 || (cdxtail != 0.0) || (cdytail != 0.0)) {
1655 Square(adx, adxadx1, adxadx0);
1656 Square(ady, adyady1, adyady0);
1657 Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
1658 aa[3] = aa3;
1660 if ((cdxtail != 0.0) || (cdytail != 0.0)
1661 || (adxtail != 0.0) || (adytail != 0.0)) {
1662 Square(bdx, bdxbdx1, bdxbdx0);
1663 Square(bdy, bdybdy1, bdybdy0);
1664 Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
1665 bb[3] = bb3;
1667 if ((adxtail != 0.0) || (adytail != 0.0)
1668 || (bdxtail != 0.0) || (bdytail != 0.0)) {
1669 Square(cdx, cdxcdx1, cdxcdx0);
1670 Square(cdy, cdycdy1, cdycdy0);
1671 Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
1672 cc[3] = cc3;
1675 if (adxtail != 0.0) {
1676 axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
1677 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
1678 temp16a);
1680 axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
1681 temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
1683 axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
1684 temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
1686 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1687 temp16blen, temp16b, temp32a);
1688 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1689 temp32alen, temp32a, temp48);
1690 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1691 temp48, finother);
1692 finswap = finnow; finnow = finother; finother = finswap;
1694 if (adytail != 0.0) {
1695 aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
1696 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
1697 temp16a);
1699 aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
1700 temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
1702 aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
1703 temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
1705 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1706 temp16blen, temp16b, temp32a);
1707 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1708 temp32alen, temp32a, temp48);
1709 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1710 temp48, finother);
1711 finswap = finnow; finnow = finother; finother = finswap;
1713 if (bdxtail != 0.0) {
1714 bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
1715 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
1716 temp16a);
1718 bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
1719 temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
1721 bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
1722 temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
1724 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1725 temp16blen, temp16b, temp32a);
1726 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1727 temp32alen, temp32a, temp48);
1728 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1729 temp48, finother);
1730 finswap = finnow; finnow = finother; finother = finswap;
1732 if (bdytail != 0.0) {
1733 bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
1734 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
1735 temp16a);
1737 bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
1738 temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
1740 bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
1741 temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
1743 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1744 temp16blen, temp16b, temp32a);
1745 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1746 temp32alen, temp32a, temp48);
1747 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1748 temp48, finother);
1749 finswap = finnow; finnow = finother; finother = finswap;
1751 if (cdxtail != 0.0) {
1752 cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
1753 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
1754 temp16a);
1756 cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
1757 temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
1759 cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
1760 temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
1762 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1763 temp16blen, temp16b, temp32a);
1764 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1765 temp32alen, temp32a, temp48);
1766 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1767 temp48, finother);
1768 finswap = finnow; finnow = finother; finother = finswap;
1770 if (cdytail != 0.0) {
1771 cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
1772 temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
1773 temp16a);
1775 cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
1776 temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
1778 cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
1779 temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
1781 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1782 temp16blen, temp16b, temp32a);
1783 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
1784 temp32alen, temp32a, temp48);
1785 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1786 temp48, finother);
1787 finswap = finnow; finnow = finother; finother = finswap;
1790 if ((adxtail != 0.0) || (adytail != 0.0)) {
1791 if ((bdxtail != 0.0) || (bdytail != 0.0)
1792 || (cdxtail != 0.0) || (cdytail != 0.0)) {
1793 Two_Product(bdxtail, cdy, ti1, ti0);
1794 Two_Product(bdx, cdytail, tj1, tj0);
1795 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
1796 u[3] = u3;
1797 negate = -bdy;
1798 Two_Product(cdxtail, negate, ti1, ti0);
1799 negate = -bdytail;
1800 Two_Product(cdx, negate, tj1, tj0);
1801 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
1802 v[3] = v3;
1803 bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
1805 Two_Product(bdxtail, cdytail, ti1, ti0);
1806 Two_Product(cdxtail, bdytail, tj1, tj0);
1807 Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
1808 bctt[3] = bctt3;
1809 bcttlen = 4;
1810 } else {
1811 bct[0] = 0.0;
1812 bctlen = 1;
1813 bctt[0] = 0.0;
1814 bcttlen = 1;
1817 if (adxtail != 0.0) {
1818 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
1819 axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
1820 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
1821 temp32a);
1822 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1823 temp32alen, temp32a, temp48);
1824 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1825 temp48, finother);
1826 finswap = finnow; finnow = finother; finother = finswap;
1827 if (bdytail != 0.0) {
1828 temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
1829 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
1830 temp16a);
1831 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
1832 temp16a, finother);
1833 finswap = finnow; finnow = finother; finother = finswap;
1835 if (cdytail != 0.0) {
1836 temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
1837 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
1838 temp16a);
1839 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
1840 temp16a, finother);
1841 finswap = finnow; finnow = finother; finother = finswap;
1844 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
1845 temp32a);
1846 axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
1847 temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
1848 temp16a);
1849 temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
1850 temp16b);
1851 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1852 temp16blen, temp16b, temp32b);
1853 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
1854 temp32blen, temp32b, temp64);
1855 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
1856 temp64, finother);
1857 finswap = finnow; finnow = finother; finother = finswap;
1859 if (adytail != 0.0) {
1860 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
1861 aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
1862 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
1863 temp32a);
1864 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1865 temp32alen, temp32a, temp48);
1866 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1867 temp48, finother);
1868 finswap = finnow; finnow = finother; finother = finswap;
1871 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
1872 temp32a);
1873 aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
1874 temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
1875 temp16a);
1876 temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
1877 temp16b);
1878 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1879 temp16blen, temp16b, temp32b);
1880 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
1881 temp32blen, temp32b, temp64);
1882 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
1883 temp64, finother);
1884 finswap = finnow; finnow = finother; finother = finswap;
1887 if ((bdxtail != 0.0) || (bdytail != 0.0)) {
1888 if ((cdxtail != 0.0) || (cdytail != 0.0)
1889 || (adxtail != 0.0) || (adytail != 0.0)) {
1890 Two_Product(cdxtail, ady, ti1, ti0);
1891 Two_Product(cdx, adytail, tj1, tj0);
1892 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
1893 u[3] = u3;
1894 negate = -cdy;
1895 Two_Product(adxtail, negate, ti1, ti0);
1896 negate = -cdytail;
1897 Two_Product(adx, negate, tj1, tj0);
1898 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
1899 v[3] = v3;
1900 catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
1902 Two_Product(cdxtail, adytail, ti1, ti0);
1903 Two_Product(adxtail, cdytail, tj1, tj0);
1904 Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
1905 catt[3] = catt3;
1906 cattlen = 4;
1907 } else {
1908 cat[0] = 0.0;
1909 catlen = 1;
1910 catt[0] = 0.0;
1911 cattlen = 1;
1914 if (bdxtail != 0.0) {
1915 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
1916 bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
1917 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
1918 temp32a);
1919 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1920 temp32alen, temp32a, temp48);
1921 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1922 temp48, finother);
1923 finswap = finnow; finnow = finother; finother = finswap;
1924 if (cdytail != 0.0) {
1925 temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
1926 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
1927 temp16a);
1928 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
1929 temp16a, finother);
1930 finswap = finnow; finnow = finother; finother = finswap;
1932 if (adytail != 0.0) {
1933 temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
1934 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
1935 temp16a);
1936 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
1937 temp16a, finother);
1938 finswap = finnow; finnow = finother; finother = finswap;
1941 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
1942 temp32a);
1943 bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
1944 temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
1945 temp16a);
1946 temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
1947 temp16b);
1948 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1949 temp16blen, temp16b, temp32b);
1950 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
1951 temp32blen, temp32b, temp64);
1952 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
1953 temp64, finother);
1954 finswap = finnow; finnow = finother; finother = finswap;
1956 if (bdytail != 0.0) {
1957 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
1958 bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
1959 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
1960 temp32a);
1961 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1962 temp32alen, temp32a, temp48);
1963 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
1964 temp48, finother);
1965 finswap = finnow; finnow = finother; finother = finswap;
1968 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
1969 temp32a);
1970 bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
1971 temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
1972 temp16a);
1973 temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
1974 temp16b);
1975 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
1976 temp16blen, temp16b, temp32b);
1977 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
1978 temp32blen, temp32b, temp64);
1979 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
1980 temp64, finother);
1981 finswap = finnow; finnow = finother; finother = finswap;
1984 if ((cdxtail != 0.0) || (cdytail != 0.0)) {
1985 if ((adxtail != 0.0) || (adytail != 0.0)
1986 || (bdxtail != 0.0) || (bdytail != 0.0)) {
1987 Two_Product(adxtail, bdy, ti1, ti0);
1988 Two_Product(adx, bdytail, tj1, tj0);
1989 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
1990 u[3] = u3;
1991 negate = -ady;
1992 Two_Product(bdxtail, negate, ti1, ti0);
1993 negate = -adytail;
1994 Two_Product(bdx, negate, tj1, tj0);
1995 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
1996 v[3] = v3;
1997 abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
1999 Two_Product(adxtail, bdytail, ti1, ti0);
2000 Two_Product(bdxtail, adytail, tj1, tj0);
2001 Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
2002 abtt[3] = abtt3;
2003 abttlen = 4;
2004 } else {
2005 abt[0] = 0.0;
2006 abtlen = 1;
2007 abtt[0] = 0.0;
2008 abttlen = 1;
2011 if (cdxtail != 0.0) {
2012 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
2013 cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
2014 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
2015 temp32a);
2016 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
2017 temp32alen, temp32a, temp48);
2018 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
2019 temp48, finother);
2020 finswap = finnow; finnow = finother; finother = finswap;
2021 if (adytail != 0.0) {
2022 temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
2023 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
2024 temp16a);
2025 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
2026 temp16a, finother);
2027 finswap = finnow; finnow = finother; finother = finswap;
2029 if (bdytail != 0.0) {
2030 temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
2031 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
2032 temp16a);
2033 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
2034 temp16a, finother);
2035 finswap = finnow; finnow = finother; finother = finswap;
2038 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
2039 temp32a);
2040 cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
2041 temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
2042 temp16a);
2043 temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
2044 temp16b);
2045 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
2046 temp16blen, temp16b, temp32b);
2047 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
2048 temp32blen, temp32b, temp64);
2049 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
2050 temp64, finother);
2051 finswap = finnow; finnow = finother; finother = finswap;
2053 if (cdytail != 0.0) {
2054 temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
2055 cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
2056 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
2057 temp32a);
2058 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
2059 temp32alen, temp32a, temp48);
2060 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
2061 temp48, finother);
2062 finswap = finnow; finnow = finother; finother = finswap;
2065 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
2066 temp32a);
2067 cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
2068 temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
2069 temp16a);
2070 temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
2071 temp16b);
2072 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
2073 temp16blen, temp16b, temp32b);
2074 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
2075 temp32blen, temp32b, temp64);
2076 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
2077 temp64, finother);
2078 finswap = finnow; finnow = finother; finother = finswap;
2082 return finnow[finlength - 1];
2085 REAL incircle(pa, pb, pc, pd)
2086 REAL *pa;
2087 REAL *pb;
2088 REAL *pc;
2089 REAL *pd;
2091 REAL adx, bdx, cdx, ady, bdy, cdy;
2092 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
2093 REAL alift, blift, clift;
2094 REAL det;
2095 REAL permanent, errbound;
2096 REAL inc;
2098 FPU_ROUND_DOUBLE;
2100 adx = pa[0] - pd[0];
2101 bdx = pb[0] - pd[0];
2102 cdx = pc[0] - pd[0];
2103 ady = pa[1] - pd[1];
2104 bdy = pb[1] - pd[1];
2105 cdy = pc[1] - pd[1];
2107 bdxcdy = bdx * cdy;
2108 cdxbdy = cdx * bdy;
2109 alift = adx * adx + ady * ady;
2111 cdxady = cdx * ady;
2112 adxcdy = adx * cdy;
2113 blift = bdx * bdx + bdy * bdy;
2115 adxbdy = adx * bdy;
2116 bdxady = bdx * ady;
2117 clift = cdx * cdx + cdy * cdy;
2119 det = alift * (bdxcdy - cdxbdy)
2120 + blift * (cdxady - adxcdy)
2121 + clift * (adxbdy - bdxady);
2123 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
2124 + (Absolute(cdxady) + Absolute(adxcdy)) * blift
2125 + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
2126 errbound = iccerrboundA * permanent;
2127 if ((det > errbound) || (-det > errbound)) {
2128 FPU_RESTORE;
2129 return det;
2132 inc = incircleadapt(pa, pb, pc, pd, permanent);
2133 FPU_RESTORE;
2134 return inc;
2137 /*****************************************************************************/
2138 /* */
2139 /* inspherefast() Approximate 3D insphere test. Nonrobust. */
2140 /* insphereexact() Exact 3D insphere test. Robust. */
2141 /* insphereslow() Another exact 3D insphere test. Robust. */
2142 /* insphere() Adaptive exact 3D insphere test. Robust. */
2143 /* */
2144 /* Return a positive value if the point pe lies inside the */
2145 /* sphere passing through pa, pb, pc, and pd; a negative value */
2146 /* if it lies outside; and zero if the five points are */
2147 /* cospherical. The points pa, pb, pc, and pd must be ordered */
2148 /* so that they have a positive orientation (as defined by */
2149 /* orient3d()), or the sign of the result will be reversed. */
2150 /* */
2151 /* Only the first and last routine should be used; the middle two are for */
2152 /* timings. */
2153 /* */
2154 /* The last three use exact arithmetic to ensure a correct answer. The */
2155 /* result returned is the determinant of a matrix. In insphere() only, */
2156 /* this determinant is computed adaptively, in the sense that exact */
2157 /* arithmetic is used only to the degree it is needed to ensure that the */
2158 /* returned value has the correct sign. Hence, insphere() is usually quite */
2159 /* fast, but will run more slowly when the input points are cospherical or */
2160 /* nearly so. */
2161 /* */
2162 /*****************************************************************************/
2164 static REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe)
2166 INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1;
2167 INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1;
2168 INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1;
2169 INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1;
2170 REAL axby0, bxcy0, cxdy0, dxey0, exay0;
2171 REAL bxay0, cxby0, dxcy0, exdy0, axey0;
2172 REAL axcy0, bxdy0, cxey0, dxay0, exby0;
2173 REAL cxay0, dxby0, excy0, axdy0, bxey0;
2174 REAL ab[4], bc[4], cd[4], de[4], ea[4];
2175 REAL ac[4], bd[4], ce[4], da[4], eb[4];
2176 REAL temp8a[8], temp8b[8], temp16[16];
2177 int temp8alen, temp8blen, temp16len;
2178 REAL abc[24], bcd[24], cde[24], dea[24], eab[24];
2179 REAL abd[24], bce[24], cda[24], deb[24], eac[24];
2180 int abclen, bcdlen, cdelen, dealen, eablen;
2181 int abdlen, bcelen, cdalen, deblen, eaclen;
2182 REAL temp48a[48], temp48b[48];
2183 int temp48alen, temp48blen;
2184 REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];
2185 int abcdlen, bcdelen, cdealen, deablen, eabclen;
2186 REAL temp192[192];
2187 REAL det384x[384], det384y[384], det384z[384];
2188 int xlen, ylen, zlen;
2189 REAL detxy[768];
2190 int xylen;
2191 REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152];
2192 int alen, blen, clen, dlen, elen;
2193 REAL abdet[2304], cddet[2304], cdedet[3456];
2194 int ablen, cdlen;
2195 REAL deter[5760];
2196 int deterlen;
2197 int i;
2199 INEXACT REAL bvirt;
2200 REAL avirt, bround, around;
2201 INEXACT REAL c;
2202 INEXACT REAL abig;
2203 REAL ahi, alo, bhi, blo;
2204 REAL err1, err2, err3;
2205 INEXACT REAL _i, _j;
2206 REAL _0;
2208 Two_Product(pa[0], pb[1], axby1, axby0);
2209 Two_Product(pb[0], pa[1], bxay1, bxay0);
2210 Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
2212 Two_Product(pb[0], pc[1], bxcy1, bxcy0);
2213 Two_Product(pc[0], pb[1], cxby1, cxby0);
2214 Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
2216 Two_Product(pc[0], pd[1], cxdy1, cxdy0);
2217 Two_Product(pd[0], pc[1], dxcy1, dxcy0);
2218 Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
2220 Two_Product(pd[0], pe[1], dxey1, dxey0);
2221 Two_Product(pe[0], pd[1], exdy1, exdy0);
2222 Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]);
2224 Two_Product(pe[0], pa[1], exay1, exay0);
2225 Two_Product(pa[0], pe[1], axey1, axey0);
2226 Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]);
2228 Two_Product(pa[0], pc[1], axcy1, axcy0);
2229 Two_Product(pc[0], pa[1], cxay1, cxay0);
2230 Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
2232 Two_Product(pb[0], pd[1], bxdy1, bxdy0);
2233 Two_Product(pd[0], pb[1], dxby1, dxby0);
2234 Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
2236 Two_Product(pc[0], pe[1], cxey1, cxey0);
2237 Two_Product(pe[0], pc[1], excy1, excy0);
2238 Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]);
2240 Two_Product(pd[0], pa[1], dxay1, dxay0);
2241 Two_Product(pa[0], pd[1], axdy1, axdy0);
2242 Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
2244 Two_Product(pe[0], pb[1], exby1, exby0);
2245 Two_Product(pb[0], pe[1], bxey1, bxey0);
2246 Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]);
2248 temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a);
2249 temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b);
2250 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2251 temp16);
2252 temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a);
2253 abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2254 abc);
2256 temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a);
2257 temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b);
2258 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2259 temp16);
2260 temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a);
2261 bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2262 bcd);
2264 temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a);
2265 temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b);
2266 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2267 temp16);
2268 temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a);
2269 cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2270 cde);
2272 temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a);
2273 temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b);
2274 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2275 temp16);
2276 temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a);
2277 dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2278 dea);
2280 temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a);
2281 temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b);
2282 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2283 temp16);
2284 temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a);
2285 eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2286 eab);
2288 temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a);
2289 temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b);
2290 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2291 temp16);
2292 temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a);
2293 abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2294 abd);
2296 temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a);
2297 temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b);
2298 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2299 temp16);
2300 temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a);
2301 bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2302 bce);
2304 temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a);
2305 temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b);
2306 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2307 temp16);
2308 temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a);
2309 cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2310 cda);
2312 temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a);
2313 temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b);
2314 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2315 temp16);
2316 temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a);
2317 deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2318 deb);
2320 temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a);
2321 temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b);
2322 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
2323 temp16);
2324 temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a);
2325 eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
2326 eac);
2328 temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a);
2329 temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b);
2330 for (i = 0; i < temp48blen; i++) {
2331 temp48b[i] = -temp48b[i];
2333 bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
2334 temp48blen, temp48b, bcde);
2335 xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192);
2336 xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x);
2337 ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192);
2338 ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y);
2339 zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192);
2340 zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z);
2341 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
2342 alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet);
2344 temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a);
2345 temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b);
2346 for (i = 0; i < temp48blen; i++) {
2347 temp48b[i] = -temp48b[i];
2349 cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
2350 temp48blen, temp48b, cdea);
2351 xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192);
2352 xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x);
2353 ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192);
2354 ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y);
2355 zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192);
2356 zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z);
2357 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
2358 blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet);
2360 temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a);
2361 temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b);
2362 for (i = 0; i < temp48blen; i++) {
2363 temp48b[i] = -temp48b[i];
2365 deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
2366 temp48blen, temp48b, deab);
2367 xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192);
2368 xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x);
2369 ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192);
2370 ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y);
2371 zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192);
2372 zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z);
2373 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
2374 clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet);
2376 temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a);
2377 temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b);
2378 for (i = 0; i < temp48blen; i++) {
2379 temp48b[i] = -temp48b[i];
2381 eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
2382 temp48blen, temp48b, eabc);
2383 xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192);
2384 xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x);
2385 ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192);
2386 ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y);
2387 zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192);
2388 zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z);
2389 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
2390 dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet);
2392 temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a);
2393 temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b);
2394 for (i = 0; i < temp48blen; i++) {
2395 temp48b[i] = -temp48b[i];
2397 abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
2398 temp48blen, temp48b, abcd);
2399 xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192);
2400 xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x);
2401 ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192);
2402 ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y);
2403 zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192);
2404 zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z);
2405 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
2406 elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet);
2408 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
2409 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
2410 cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet);
2411 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter);
2413 return deter[deterlen - 1];
2416 static REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe,
2417 REAL permanent)
2419 INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
2420 REAL det, errbound;
2422 INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1;
2423 INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1;
2424 INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1;
2425 REAL aexbey0, bexaey0, bexcey0, cexbey0;
2426 REAL cexdey0, dexcey0, dexaey0, aexdey0;
2427 REAL aexcey0, cexaey0, bexdey0, dexbey0;
2428 REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
2429 INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3;
2430 REAL abeps, bceps, cdeps, daeps, aceps, bdeps;
2431 REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48];
2432 int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len;
2433 REAL xdet[96], ydet[96], zdet[96], xydet[192];
2434 int xlen, ylen, zlen, xylen;
2435 REAL adet[288], bdet[288], cdet[288], ddet[288];
2436 int alen, blen, clen, dlen;
2437 REAL abdet[576], cddet[576];
2438 int ablen, cdlen;
2439 REAL fin1[1152];
2440 int finlength;
2442 REAL aextail, bextail, cextail, dextail;
2443 REAL aeytail, beytail, ceytail, deytail;
2444 REAL aeztail, beztail, ceztail, deztail;
2446 INEXACT REAL bvirt;
2447 REAL avirt, bround, around;
2448 INEXACT REAL c;
2449 INEXACT REAL abig;
2450 REAL ahi, alo, bhi, blo;
2451 REAL err1, err2, err3;
2452 INEXACT REAL _i, _j;
2453 REAL _0;
2455 aex = (REAL) (pa[0] - pe[0]);
2456 bex = (REAL) (pb[0] - pe[0]);
2457 cex = (REAL) (pc[0] - pe[0]);
2458 dex = (REAL) (pd[0] - pe[0]);
2459 aey = (REAL) (pa[1] - pe[1]);
2460 bey = (REAL) (pb[1] - pe[1]);
2461 cey = (REAL) (pc[1] - pe[1]);
2462 dey = (REAL) (pd[1] - pe[1]);
2463 aez = (REAL) (pa[2] - pe[2]);
2464 bez = (REAL) (pb[2] - pe[2]);
2465 cez = (REAL) (pc[2] - pe[2]);
2466 dez = (REAL) (pd[2] - pe[2]);
2468 Two_Product(aex, bey, aexbey1, aexbey0);
2469 Two_Product(bex, aey, bexaey1, bexaey0);
2470 Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);
2471 ab[3] = ab3;
2473 Two_Product(bex, cey, bexcey1, bexcey0);
2474 Two_Product(cex, bey, cexbey1, cexbey0);
2475 Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);
2476 bc[3] = bc3;
2478 Two_Product(cex, dey, cexdey1, cexdey0);
2479 Two_Product(dex, cey, dexcey1, dexcey0);
2480 Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);
2481 cd[3] = cd3;
2483 Two_Product(dex, aey, dexaey1, dexaey0);
2484 Two_Product(aex, dey, aexdey1, aexdey0);
2485 Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);
2486 da[3] = da3;
2488 Two_Product(aex, cey, aexcey1, aexcey0);
2489 Two_Product(cex, aey, cexaey1, cexaey0);
2490 Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);
2491 ac[3] = ac3;
2493 Two_Product(bex, dey, bexdey1, bexdey0);
2494 Two_Product(dex, bey, dexbey1, dexbey0);
2495 Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);
2496 bd[3] = bd3;
2498 temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);
2499 temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);
2500 temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);
2501 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
2502 temp8blen, temp8b, temp16);
2503 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
2504 temp16len, temp16, temp24);
2505 temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48);
2506 xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet);
2507 temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48);
2508 ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet);
2509 temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48);
2510 zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet);
2511 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
2512 alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet);
2514 temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);
2515 temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);
2516 temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);
2517 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
2518 temp8blen, temp8b, temp16);
2519 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
2520 temp16len, temp16, temp24);
2521 temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48);
2522 xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet);
2523 temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48);
2524 ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet);
2525 temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48);
2526 zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet);
2527 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
2528 blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet);
2530 temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);
2531 temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);
2532 temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);
2533 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
2534 temp8blen, temp8b, temp16);
2535 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
2536 temp16len, temp16, temp24);
2537 temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48);
2538 xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet);
2539 temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48);
2540 ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet);
2541 temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48);
2542 zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet);
2543 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
2544 clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet);
2546 temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);
2547 temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);
2548 temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);
2549 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
2550 temp8blen, temp8b, temp16);
2551 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
2552 temp16len, temp16, temp24);
2553 temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48);
2554 xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet);
2555 temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48);
2556 ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet);
2557 temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48);
2558 zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet);
2559 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
2560 dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet);
2562 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
2563 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
2564 finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);
2566 det = estimate(finlength, fin1);
2567 errbound = isperrboundB * permanent;
2568 if ((det >= errbound) || (-det >= errbound)) {
2569 return det;
2572 Two_Diff_Tail(pa[0], pe[0], aex, aextail);
2573 Two_Diff_Tail(pa[1], pe[1], aey, aeytail);
2574 Two_Diff_Tail(pa[2], pe[2], aez, aeztail);
2575 Two_Diff_Tail(pb[0], pe[0], bex, bextail);
2576 Two_Diff_Tail(pb[1], pe[1], bey, beytail);
2577 Two_Diff_Tail(pb[2], pe[2], bez, beztail);
2578 Two_Diff_Tail(pc[0], pe[0], cex, cextail);
2579 Two_Diff_Tail(pc[1], pe[1], cey, ceytail);
2580 Two_Diff_Tail(pc[2], pe[2], cez, ceztail);
2581 Two_Diff_Tail(pd[0], pe[0], dex, dextail);
2582 Two_Diff_Tail(pd[1], pe[1], dey, deytail);
2583 Two_Diff_Tail(pd[2], pe[2], dez, deztail);
2584 if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0)
2585 && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0)
2586 && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0)
2587 && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) {
2588 return det;
2591 errbound = isperrboundC * permanent + resulterrbound * Absolute(det);
2592 abeps = (aex * beytail + bey * aextail)
2593 - (aey * bextail + bex * aeytail);
2594 bceps = (bex * ceytail + cey * bextail)
2595 - (bey * cextail + cex * beytail);
2596 cdeps = (cex * deytail + dey * cextail)
2597 - (cey * dextail + dex * ceytail);
2598 daeps = (dex * aeytail + aey * dextail)
2599 - (dey * aextail + aex * deytail);
2600 aceps = (aex * ceytail + cey * aextail)
2601 - (aey * cextail + cex * aeytail);
2602 bdeps = (bex * deytail + dey * bextail)
2603 - (bey * dextail + dex * beytail);
2604 det += (((bex * bex + bey * bey + bez * bez)
2605 * ((cez * daeps + dez * aceps + aez * cdeps)
2606 + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
2607 + (dex * dex + dey * dey + dez * dez)
2608 * ((aez * bceps - bez * aceps + cez * abeps)
2609 + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)))
2610 - ((aex * aex + aey * aey + aez * aez)
2611 * ((bez * cdeps - cez * bdeps + dez * bceps)
2612 + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
2613 + (cex * cex + cey * cey + cez * cez)
2614 * ((dez * abeps + aez * bdeps + bez * daeps)
2615 + (deztail * ab3 + aeztail * bd3 + beztail * da3))))
2616 + 2.0 * (((bex * bextail + bey * beytail + bez * beztail)
2617 * (cez * da3 + dez * ac3 + aez * cd3)
2618 + (dex * dextail + dey * deytail + dez * deztail)
2619 * (aez * bc3 - bez * ac3 + cez * ab3))
2620 - ((aex * aextail + aey * aeytail + aez * aeztail)
2621 * (bez * cd3 - cez * bd3 + dez * bc3)
2622 + (cex * cextail + cey * ceytail + cez * ceztail)
2623 * (dez * ab3 + aez * bd3 + bez * da3)));
2624 if ((det >= errbound) || (-det >= errbound)) {
2625 return det;
2628 return insphereexact(pa, pb, pc, pd, pe);
2631 REAL insphere(pa, pb, pc, pd, pe)
2632 REAL *pa;
2633 REAL *pb;
2634 REAL *pc;
2635 REAL *pd;
2636 REAL *pe;
2638 REAL aex, bex, cex, dex;
2639 REAL aey, bey, cey, dey;
2640 REAL aez, bez, cez, dez;
2641 REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;
2642 REAL aexcey, cexaey, bexdey, dexbey;
2643 REAL alift, blift, clift, dlift;
2644 REAL ab, bc, cd, da, ac, bd;
2645 REAL abc, bcd, cda, dab;
2646 REAL aezplus, bezplus, cezplus, dezplus;
2647 REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;
2648 REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;
2649 REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;
2650 REAL det;
2651 REAL permanent, errbound;
2652 REAL ins;
2654 FPU_ROUND_DOUBLE;
2656 aex = pa[0] - pe[0];
2657 bex = pb[0] - pe[0];
2658 cex = pc[0] - pe[0];
2659 dex = pd[0] - pe[0];
2660 aey = pa[1] - pe[1];
2661 bey = pb[1] - pe[1];
2662 cey = pc[1] - pe[1];
2663 dey = pd[1] - pe[1];
2664 aez = pa[2] - pe[2];
2665 bez = pb[2] - pe[2];
2666 cez = pc[2] - pe[2];
2667 dez = pd[2] - pe[2];
2669 aexbey = aex * bey;
2670 bexaey = bex * aey;
2671 ab = aexbey - bexaey;
2672 bexcey = bex * cey;
2673 cexbey = cex * bey;
2674 bc = bexcey - cexbey;
2675 cexdey = cex * dey;
2676 dexcey = dex * cey;
2677 cd = cexdey - dexcey;
2678 dexaey = dex * aey;
2679 aexdey = aex * dey;
2680 da = dexaey - aexdey;
2682 aexcey = aex * cey;
2683 cexaey = cex * aey;
2684 ac = aexcey - cexaey;
2685 bexdey = bex * dey;
2686 dexbey = dex * bey;
2687 bd = bexdey - dexbey;
2689 abc = aez * bc - bez * ac + cez * ab;
2690 bcd = bez * cd - cez * bd + dez * bc;
2691 cda = cez * da + dez * ac + aez * cd;
2692 dab = dez * ab + aez * bd + bez * da;
2694 alift = aex * aex + aey * aey + aez * aez;
2695 blift = bex * bex + bey * bey + bez * bez;
2696 clift = cex * cex + cey * cey + cez * cez;
2697 dlift = dex * dex + dey * dey + dez * dez;
2699 det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd);
2701 aezplus = Absolute(aez);
2702 bezplus = Absolute(bez);
2703 cezplus = Absolute(cez);
2704 dezplus = Absolute(dez);
2705 aexbeyplus = Absolute(aexbey);
2706 bexaeyplus = Absolute(bexaey);
2707 bexceyplus = Absolute(bexcey);
2708 cexbeyplus = Absolute(cexbey);
2709 cexdeyplus = Absolute(cexdey);
2710 dexceyplus = Absolute(dexcey);
2711 dexaeyplus = Absolute(dexaey);
2712 aexdeyplus = Absolute(aexdey);
2713 aexceyplus = Absolute(aexcey);
2714 cexaeyplus = Absolute(cexaey);
2715 bexdeyplus = Absolute(bexdey);
2716 dexbeyplus = Absolute(dexbey);
2717 permanent = ((cexdeyplus + dexceyplus) * bezplus
2718 + (dexbeyplus + bexdeyplus) * cezplus
2719 + (bexceyplus + cexbeyplus) * dezplus)
2720 * alift
2721 + ((dexaeyplus + aexdeyplus) * cezplus
2722 + (aexceyplus + cexaeyplus) * dezplus
2723 + (cexdeyplus + dexceyplus) * aezplus)
2724 * blift
2725 + ((aexbeyplus + bexaeyplus) * dezplus
2726 + (bexdeyplus + dexbeyplus) * aezplus
2727 + (dexaeyplus + aexdeyplus) * bezplus)
2728 * clift
2729 + ((bexceyplus + cexbeyplus) * aezplus
2730 + (cexaeyplus + aexceyplus) * bezplus
2731 + (aexbeyplus + bexaeyplus) * cezplus)
2732 * dlift;
2733 errbound = isperrboundA * permanent;
2734 if ((det > errbound) || (-det > errbound)) {
2735 FPU_RESTORE;
2736 return det;
2739 ins = insphereadapt(pa, pb, pc, pd, pe, permanent);
2740 FPU_RESTORE;
2741 return ins;