pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 /*****************************************************************************/ 00002 /* */ 00003 /* Routines for Arbitrary Precision Floating-point Arithmetic */ 00004 /* and Fast Robust Geometric Predicates */ 00005 /* (predicates.c) */ 00006 /* */ 00007 /* May 18, 1996 */ 00008 /* */ 00009 /* Placed in the public domain by */ 00010 /* Jonathan Richard Shewchuk */ 00011 /* School of Computer Science */ 00012 /* Carnegie Mellon University */ 00013 /* 5000 Forbes Avenue */ 00014 /* Pittsburgh, Pennsylvania 15213-3891 */ 00015 /* jrs@cs.cmu.edu */ 00016 /* */ 00017 /* This file contains C implementation of algorithms for exact addition */ 00018 /* and multiplication of floating-point numbers, and predicates for */ 00019 /* robustly performing the orientation and incircle tests used in */ 00020 /* computational geometry. The algorithms and underlying theory are */ 00021 /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ 00022 /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ 00023 /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ 00024 /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ 00025 /* Discrete & Computational Geometry.) */ 00026 /* */ 00027 /* This file, the paper listed above, and other information are available */ 00028 /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ 00029 /* */ 00030 /*****************************************************************************/ 00031 00032 /*****************************************************************************/ 00033 /* */ 00034 /* Using this code: */ 00035 /* */ 00036 /* First, read the short or long version of the paper (from the Web page */ 00037 /* above). */ 00038 /* */ 00039 /* Be sure to call exactinit() once, before calling any of the arithmetic */ 00040 /* functions or geometric predicates. Also be sure to turn on the */ 00041 /* optimizer when compiling this file. */ 00042 /* */ 00043 /* */ 00044 /* Several geometric predicates are defined. Their parameters are all */ 00045 /* points. Each point is an array of two or three floating-point */ 00046 /* numbers. The geometric predicates, described in the papers, are */ 00047 /* */ 00048 /* orient2d(pa, pb, pc) */ 00049 /* orient2dfast(pa, pb, pc) */ 00050 /* orient3d(pa, pb, pc, pd) */ 00051 /* orient3dfast(pa, pb, pc, pd) */ 00052 /* incircle(pa, pb, pc, pd) */ 00053 /* incirclefast(pa, pb, pc, pd) */ 00054 /* insphere(pa, pb, pc, pd, pe) */ 00055 /* inspherefast(pa, pb, pc, pd, pe) */ 00056 /* */ 00057 /* Those with suffix "fast" are approximate, non-robust versions. Those */ 00058 /* without the suffix are adaptive precision, robust versions. There */ 00059 /* are also versions with the suffices "exact" and "slow", which are */ 00060 /* non-adaptive, exact arithmetic versions, which I use only for timings */ 00061 /* in my arithmetic papers. */ 00062 /* */ 00063 /* */ 00064 /* An expansion is represented by an array of floating-point numbers, */ 00065 /* sorted from smallest to largest magnitude (possibly with interspersed */ 00066 /* zeros). The length of each expansion is stored as a separate integer, */ 00067 /* and each arithmetic function returns an integer which is the length */ 00068 /* of the expansion it created. */ 00069 /* */ 00070 /* Several arithmetic functions are defined. Their parameters are */ 00071 /* */ 00072 /* e, f Input expansions */ 00073 /* elen, flen Lengths of input expansions (must be >= 1) */ 00074 /* h Output expansion */ 00075 /* b Input scalar */ 00076 /* */ 00077 /* The arithmetic functions are */ 00078 /* */ 00079 /* grow_expansion(elen, e, b, h) */ 00080 /* grow_expansion_zeroelim(elen, e, b, h) */ 00081 /* expansion_sum(elen, e, flen, f, h) */ 00082 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */ 00083 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */ 00084 /* fast_expansion_sum(elen, e, flen, f, h) */ 00085 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ 00086 /* linear_expansion_sum(elen, e, flen, f, h) */ 00087 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ 00088 /* scale_expansion(elen, e, b, h) */ 00089 /* scale_expansion_zeroelim(elen, e, b, h) */ 00090 /* compress(elen, e, h) */ 00091 /* */ 00092 /* All of these are described in the long version of the paper; some are */ 00093 /* described in the short version. All return an integer that is the */ 00094 /* length of h. Those with suffix _zeroelim perform zero elimination, */ 00095 /* and are recommended over their counterparts. The procedure */ 00096 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ 00097 /* processors that do not use the round-to-even tiebreaking rule) is */ 00098 /* recommended over expansion_sum_zeroelim(). Each procedure has a */ 00099 /* little note next to it (in the code below) that tells you whether or */ 00100 /* not the output expansion may be the same array as one of the input */ 00101 /* expansions. */ 00102 /* */ 00103 /* */ 00104 /* If you look around below, you'll also find macros for a bunch of */ 00105 /* simple unrolled arithmetic operations, and procedures for printing */ 00106 /* expansions (commented out because they don't work with all C */ 00107 /* compilers) and for generating random floating-point numbers whose */ 00108 /* significand bits are all random. Most of the macros have undocumented */ 00109 /* requirements that certain of their parameters should not be the same */ 00110 /* variable; for safety, better to make sure all the parameters are */ 00111 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ 00112 /* have questions. */ 00113 /* */ 00114 /*****************************************************************************/ 00115 00116 #include <stdio.h> 00117 #include <stdlib.h> 00118 #include <math.h> 00119 #include "predicates.h" 00120 00121 /* Use header file generated automatically by predicates_init. */ 00122 //#define USE_PREDICATES_INIT 00123 00124 #ifdef USE_PREDICATES_INIT 00125 #include "predicates_init.h" 00126 #endif /* USE_PREDICATES_INIT */ 00127 00128 /* FPU control. We MUST have only double precision (not extended precision) */ 00129 #include "rounding.h" 00130 00131 /* On some machines, the exact arithmetic routines might be defeated by the */ 00132 /* use of internal extended precision floating-point registers. Sometimes */ 00133 /* this problem can be fixed by defining certain values to be volatile, */ 00134 /* thus forcing them to be stored to memory and rounded off. This isn't */ 00135 /* a great solution, though, as it slows the arithmetic down. */ 00136 /* */ 00137 /* To try this out, write "#define INEXACT volatile" below. Normally, */ 00138 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */ 00139 00140 #define INEXACT /* Nothing */ 00141 /* #define INEXACT volatile */ 00142 00143 #define REAL double /* float or double */ 00144 #define REALPRINT doubleprint 00145 #define REALRAND doublerand 00146 #define NARROWRAND narrowdoublerand 00147 #define UNIFORMRAND uniformdoublerand 00148 00149 /* Which of the following two methods of finding the absolute values is */ 00150 /* fastest is compiler-dependent. A few compilers can inline and optimize */ 00151 /* the fabs() call; but most will incur the overhead of a function call, */ 00152 /* which is disastrously slow. A faster way on IEEE machines might be to */ 00153 /* mask the appropriate bit, but that's difficult to do in C. */ 00154 00155 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) 00156 /* #define Absolute(a) fabs(a) */ 00157 00158 /* Many of the operations are broken up into two pieces, a main part that */ 00159 /* performs an approximate operation, and a "tail" that computes the */ 00160 /* roundoff error of that operation. */ 00161 /* */ 00162 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ 00163 /* Split(), and Two_Product() are all implemented as described in the */ 00164 /* reference. Each of these macros requires certain variables to be */ 00165 /* defined in the calling routine. The variables `bvirt', `c', `abig', */ 00166 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ 00167 /* they store the result of an operation that may incur roundoff error. */ 00168 /* The input parameter `x' (or the highest numbered `x_' parameter) must */ 00169 /* also be declared `INEXACT'. */ 00170 00171 #define Fast_Two_Sum_Tail(a, b, x, y) \ 00172 bvirt = x - a; \ 00173 y = b - bvirt 00174 00175 #define Fast_Two_Sum(a, b, x, y) \ 00176 x = (REAL) (a + b); \ 00177 Fast_Two_Sum_Tail(a, b, x, y) 00178 00179 #define Fast_Two_Diff_Tail(a, b, x, y) \ 00180 bvirt = a - x; \ 00181 y = bvirt - b 00182 00183 #define Fast_Two_Diff(a, b, x, y) \ 00184 x = (REAL) (a - b); \ 00185 Fast_Two_Diff_Tail(a, b, x, y) 00186 00187 #define Two_Sum_Tail(a, b, x, y) \ 00188 bvirt = (REAL) (x - a); \ 00189 avirt = x - bvirt; \ 00190 bround = b - bvirt; \ 00191 around = a - avirt; \ 00192 y = around + bround 00193 00194 #define Two_Sum(a, b, x, y) \ 00195 x = (REAL) (a + b); \ 00196 Two_Sum_Tail(a, b, x, y) 00197 00198 #define Two_Diff_Tail(a, b, x, y) \ 00199 bvirt = (REAL) (a - x); \ 00200 avirt = x + bvirt; \ 00201 bround = bvirt - b; \ 00202 around = a - avirt; \ 00203 y = around + bround 00204 00205 #define Two_Diff(a, b, x, y) \ 00206 x = (REAL) (a - b); \ 00207 Two_Diff_Tail(a, b, x, y) 00208 00209 #define Split(a, ahi, alo) \ 00210 c = (REAL) (splitter * a); \ 00211 abig = (REAL) (c - a); \ 00212 ahi = c - abig; \ 00213 alo = a - ahi 00214 00215 #define Two_Product_Tail(a, b, x, y) \ 00216 Split(a, ahi, alo); \ 00217 Split(b, bhi, blo); \ 00218 err1 = x - (ahi * bhi); \ 00219 err2 = err1 - (alo * bhi); \ 00220 err3 = err2 - (ahi * blo); \ 00221 y = (alo * blo) - err3 00222 00223 #define Two_Product(a, b, x, y) \ 00224 x = (REAL) (a * b); \ 00225 Two_Product_Tail(a, b, x, y) 00226 00227 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */ 00228 /* already been split. Avoids redundant splitting. */ 00229 00230 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \ 00231 x = (REAL) (a * b); \ 00232 Split(a, ahi, alo); \ 00233 err1 = x - (ahi * bhi); \ 00234 err2 = err1 - (alo * bhi); \ 00235 err3 = err2 - (ahi * blo); \ 00236 y = (alo * blo) - err3 00237 00238 /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ 00239 /* already been split. Avoids redundant splitting. */ 00240 00241 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ 00242 x = (REAL) (a * b); \ 00243 err1 = x - (ahi * bhi); \ 00244 err2 = err1 - (alo * bhi); \ 00245 err3 = err2 - (ahi * blo); \ 00246 y = (alo * blo) - err3 00247 00248 /* Square() can be done more quickly than Two_Product(). */ 00249 00250 #define Square_Tail(a, x, y) \ 00251 Split(a, ahi, alo); \ 00252 err1 = x - (ahi * ahi); \ 00253 err3 = err1 - ((ahi + ahi) * alo); \ 00254 y = (alo * alo) - err3 00255 00256 #define Square(a, x, y) \ 00257 x = (REAL) (a * a); \ 00258 Square_Tail(a, x, y) 00259 00260 /* Macros for summing expansions of various fixed lengths. These are all */ 00261 /* unrolled versions of Expansion_Sum(). */ 00262 00263 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \ 00264 Two_Sum(a0, b , _i, x0); \ 00265 Two_Sum(a1, _i, x2, x1) 00266 00267 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \ 00268 Two_Diff(a0, b , _i, x0); \ 00269 Two_Sum( a1, _i, x2, x1) 00270 00271 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ 00272 Two_One_Sum(a1, a0, b0, _j, _0, x0); \ 00273 Two_One_Sum(_j, _0, b1, x3, x2, x1) 00274 00275 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ 00276 Two_One_Diff(a1, a0, b0, _j, _0, x0); \ 00277 Two_One_Diff(_j, _0, b1, x3, x2, x1) 00278 00279 #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ 00280 Two_One_Sum(a1, a0, b , _j, x1, x0); \ 00281 Two_One_Sum(a3, a2, _j, x4, x3, x2) 00282 00283 #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ 00284 Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ 00285 Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) 00286 00287 #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ 00288 x1, x0) \ 00289 Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ 00290 Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) 00291 00292 #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ 00293 x3, x2, x1, x0) \ 00294 Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ 00295 Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) 00296 00297 #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ 00298 x6, x5, x4, x3, x2, x1, x0) \ 00299 Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ 00300 _1, _0, x0); \ 00301 Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ 00302 x3, x2, x1) 00303 00304 #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ 00305 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ 00306 Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ 00307 _2, _1, _0, x1, x0); \ 00308 Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ 00309 x7, x6, x5, x4, x3, x2) 00310 00311 /* Macros for multiplying expansions of various fixed lengths. */ 00312 00313 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ 00314 Split(b, bhi, blo); \ 00315 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ 00316 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ 00317 Two_Sum(_i, _0, _k, x1); \ 00318 Fast_Two_Sum(_j, _k, x3, x2) 00319 00320 #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ 00321 Split(b, bhi, blo); \ 00322 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ 00323 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ 00324 Two_Sum(_i, _0, _k, x1); \ 00325 Fast_Two_Sum(_j, _k, _i, x2); \ 00326 Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ 00327 Two_Sum(_i, _0, _k, x3); \ 00328 Fast_Two_Sum(_j, _k, _i, x4); \ 00329 Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ 00330 Two_Sum(_i, _0, _k, x5); \ 00331 Fast_Two_Sum(_j, _k, x7, x6) 00332 00333 #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ 00334 Split(a0, a0hi, a0lo); \ 00335 Split(b0, bhi, blo); \ 00336 Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ 00337 Split(a1, a1hi, a1lo); \ 00338 Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ 00339 Two_Sum(_i, _0, _k, _1); \ 00340 Fast_Two_Sum(_j, _k, _l, _2); \ 00341 Split(b1, bhi, blo); \ 00342 Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ 00343 Two_Sum(_1, _0, _k, x1); \ 00344 Two_Sum(_2, _k, _j, _1); \ 00345 Two_Sum(_l, _j, _m, _2); \ 00346 Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ 00347 Two_Sum(_i, _0, _n, _0); \ 00348 Two_Sum(_1, _0, _i, x2); \ 00349 Two_Sum(_2, _i, _k, _1); \ 00350 Two_Sum(_m, _k, _l, _2); \ 00351 Two_Sum(_j, _n, _k, _0); \ 00352 Two_Sum(_1, _0, _j, x3); \ 00353 Two_Sum(_2, _j, _i, _1); \ 00354 Two_Sum(_l, _i, _m, _2); \ 00355 Two_Sum(_1, _k, _i, x4); \ 00356 Two_Sum(_2, _i, _k, x5); \ 00357 Two_Sum(_m, _k, x7, x6) 00358 00359 /* An expansion of length two can be squared more quickly than finding the */ 00360 /* product of two different expansions of length two, and the result is */ 00361 /* guaranteed to have no more than six (rather than eight) components. */ 00362 00363 #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ 00364 Square(a0, _j, x0); \ 00365 _0 = a0 + a0; \ 00366 Two_Product(a1, _0, _k, _1); \ 00367 Two_One_Sum(_k, _1, _j, _l, _2, x1); \ 00368 Square(a1, _j, _1); \ 00369 Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) 00370 00371 #ifndef USE_PREDICATES_INIT 00372 00373 static REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */ 00374 /* A set of coefficients used to calculate maximum roundoff errors. */ 00375 static REAL resulterrbound; 00376 static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; 00377 static REAL o3derrboundA, o3derrboundB, o3derrboundC; 00378 static REAL iccerrboundA, iccerrboundB, iccerrboundC; 00379 static REAL isperrboundA, isperrboundB, isperrboundC; 00380 00381 void 00382 gts_predicates_init() 00383 { 00384 double half = 0.5; 00385 double check = 1.0, lastcheck; 00386 int every_other = 1; 00387 /* epsilon = 2^(-p). Used to estimate roundoff errors. */ 00388 double epsilon = 1.0; 00389 00390 FPU_ROUND_DOUBLE; 00391 00392 splitter = 1.; 00393 00394 /* Repeatedly divide `epsilon' by two until it is too small to add to */ 00395 /* one without causing roundoff. (Also check if the sum is equal to */ 00396 /* the previous sum, for machines that round up instead of using exact */ 00397 /* rounding. Not that this library will work on such machines anyway). */ 00398 do { 00399 lastcheck = check; 00400 epsilon *= half; 00401 if (every_other) { 00402 splitter *= 2.0; 00403 } 00404 every_other = !every_other; 00405 check = 1.0 + epsilon; 00406 } while ((check != 1.0) && (check != lastcheck)); 00407 splitter += 1.0; 00408 /* Error bounds for orientation and incircle tests. */ 00409 resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; 00410 ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; 00411 ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; 00412 ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; 00413 o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; 00414 o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; 00415 o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; 00416 iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; 00417 iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; 00418 iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; 00419 isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; 00420 isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; 00421 isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; 00422 00423 00424 FPU_RESTORE; 00425 } 00426 00427 #endif /* USE_PREDICATES_INIT */ 00428 00429 /*****************************************************************************/ 00430 /* */ 00431 /* doubleprint() Print the bit representation of a double. */ 00432 /* */ 00433 /* Useful for debugging exact arithmetic routines. */ 00434 /* */ 00435 /*****************************************************************************/ 00436 00437 /* 00438 void doubleprint(number) 00439 double number; 00440 { 00441 unsigned long long no; 00442 unsigned long long sign, expo; 00443 int exponent; 00444 int i, bottomi; 00445 00446 no = *(unsigned long long *) &number; 00447 sign = no & 0x8000000000000000ll; 00448 expo = (no >> 52) & 0x7ffll; 00449 exponent = (int) expo; 00450 exponent = exponent - 1023; 00451 if (sign) { 00452 printf("-"); 00453 } else { 00454 printf(" "); 00455 } 00456 if (exponent == -1023) { 00457 printf( 00458 "0.0000000000000000000000000000000000000000000000000000_ ( )"); 00459 } else { 00460 printf("1."); 00461 bottomi = -1; 00462 for (i = 0; i < 52; i++) { 00463 if (no & 0x0008000000000000ll) { 00464 printf("1"); 00465 bottomi = i; 00466 } else { 00467 printf("0"); 00468 } 00469 no <<= 1; 00470 } 00471 printf("_%d (%d)", exponent, exponent - 1 - bottomi); 00472 } 00473 } 00474 */ 00475 00476 /*****************************************************************************/ 00477 /* */ 00478 /* floatprint() Print the bit representation of a float. */ 00479 /* */ 00480 /* Useful for debugging exact arithmetic routines. */ 00481 /* */ 00482 /*****************************************************************************/ 00483 00484 /* 00485 void floatprint(number) 00486 float number; 00487 { 00488 unsigned no; 00489 unsigned sign, expo; 00490 int exponent; 00491 int i, bottomi; 00492 00493 no = *(unsigned *) &number; 00494 sign = no & 0x80000000; 00495 expo = (no >> 23) & 0xff; 00496 exponent = (int) expo; 00497 exponent = exponent - 127; 00498 if (sign) { 00499 printf("-"); 00500 } else { 00501 printf(" "); 00502 } 00503 if (exponent == -127) { 00504 printf("0.00000000000000000000000_ ( )"); 00505 } else { 00506 printf("1."); 00507 bottomi = -1; 00508 for (i = 0; i < 23; i++) { 00509 if (no & 0x00400000) { 00510 printf("1"); 00511 bottomi = i; 00512 } else { 00513 printf("0"); 00514 } 00515 no <<= 1; 00516 } 00517 printf("_%3d (%3d)", exponent, exponent - 1 - bottomi); 00518 } 00519 } 00520 */ 00521 00522 /*****************************************************************************/ 00523 /* */ 00524 /* expansion_print() Print the bit representation of an expansion. */ 00525 /* */ 00526 /* Useful for debugging exact arithmetic routines. */ 00527 /* */ 00528 /*****************************************************************************/ 00529 00530 /* 00531 void expansion_print(elen, e) 00532 int elen; 00533 REAL *e; 00534 { 00535 int i; 00536 00537 for (i = elen - 1; i >= 0; i--) { 00538 REALPRINT(e[i]); 00539 if (i > 0) { 00540 printf(" +\n"); 00541 } else { 00542 printf("\n"); 00543 } 00544 } 00545 } 00546 */ 00547 00548 /*****************************************************************************/ 00549 /* */ 00550 /* doublerand() Generate a double with random 53-bit significand and a */ 00551 /* random exponent in [0, 511]. */ 00552 /* */ 00553 /*****************************************************************************/ 00554 00555 /* 00556 static double doublerand() 00557 { 00558 double result; 00559 double expo; 00560 long a, b, c; 00561 long i; 00562 00563 a = random(); 00564 b = random(); 00565 c = random(); 00566 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00567 for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) { 00568 if (c & i) { 00569 result *= expo; 00570 } 00571 } 00572 return result; 00573 } 00574 */ 00575 00576 /*****************************************************************************/ 00577 /* */ 00578 /* narrowdoublerand() Generate a double with random 53-bit significand */ 00579 /* and a random exponent in [0, 7]. */ 00580 /* */ 00581 /*****************************************************************************/ 00582 00583 /* 00584 static double narrowdoublerand() 00585 { 00586 double result; 00587 double expo; 00588 long a, b, c; 00589 long i; 00590 00591 a = random(); 00592 b = random(); 00593 c = random(); 00594 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00595 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { 00596 if (c & i) { 00597 result *= expo; 00598 } 00599 } 00600 return result; 00601 } 00602 */ 00603 00604 /*****************************************************************************/ 00605 /* */ 00606 /* uniformdoublerand() Generate a double with random 53-bit significand. */ 00607 /* */ 00608 /*****************************************************************************/ 00609 00610 /* 00611 static double uniformdoublerand() 00612 { 00613 double result; 00614 long a, b; 00615 00616 a = random(); 00617 b = random(); 00618 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00619 return result; 00620 } 00621 */ 00622 00623 /*****************************************************************************/ 00624 /* */ 00625 /* floatrand() Generate a float with random 24-bit significand and a */ 00626 /* random exponent in [0, 63]. */ 00627 /* */ 00628 /*****************************************************************************/ 00629 00630 /* 00631 static float floatrand() 00632 { 00633 float result; 00634 float expo; 00635 long a, c; 00636 long i; 00637 00638 a = random(); 00639 c = random(); 00640 result = (float) ((a - 1073741824) >> 6); 00641 for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) { 00642 if (c & i) { 00643 result *= expo; 00644 } 00645 } 00646 return result; 00647 } 00648 */ 00649 00650 /*****************************************************************************/ 00651 /* */ 00652 /* narrowfloatrand() Generate a float with random 24-bit significand and */ 00653 /* a random exponent in [0, 7]. */ 00654 /* */ 00655 /*****************************************************************************/ 00656 00657 /* 00658 static float narrowfloatrand() 00659 { 00660 float result; 00661 float expo; 00662 long a, c; 00663 long i; 00664 00665 a = random(); 00666 c = random(); 00667 result = (float) ((a - 1073741824) >> 6); 00668 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { 00669 if (c & i) { 00670 result *= expo; 00671 } 00672 } 00673 return result; 00674 } 00675 */ 00676 00677 /*****************************************************************************/ 00678 /* */ 00679 /* uniformfloatrand() Generate a float with random 24-bit significand. */ 00680 /* */ 00681 /*****************************************************************************/ 00682 00683 /* 00684 static float uniformfloatrand() 00685 { 00686 float result; 00687 long a; 00688 00689 a = random(); 00690 result = (float) ((a - 1073741824) >> 6); 00691 return result; 00692 } 00693 */ 00694 00695 /*****************************************************************************/ 00696 /* */ 00697 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ 00698 /* components from the output expansion. */ 00699 /* */ 00700 /* Sets h = e + f. See the long version of my paper for details. */ 00701 /* */ 00702 /* If round-to-even is used (as with IEEE 754), maintains the strongly */ 00703 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ 00704 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ 00705 /* properties. */ 00706 /* */ 00707 /*****************************************************************************/ 00708 00709 static int fast_expansion_sum_zeroelim(int elen, REAL *e, 00710 int flen, REAL *f, REAL *h) 00711 /* h cannot be e or f. */ 00712 { 00713 REAL Q; 00714 INEXACT REAL Qnew; 00715 INEXACT REAL hh; 00716 INEXACT REAL bvirt; 00717 REAL avirt, bround, around; 00718 int eindex, findex, hindex; 00719 REAL enow, fnow; 00720 00721 enow = e[0]; 00722 fnow = f[0]; 00723 eindex = findex = 0; 00724 if ((fnow > enow) == (fnow > -enow)) { 00725 Q = enow; 00726 enow = e[++eindex]; 00727 } else { 00728 Q = fnow; 00729 fnow = f[++findex]; 00730 } 00731 hindex = 0; 00732 if ((eindex < elen) && (findex < flen)) { 00733 if ((fnow > enow) == (fnow > -enow)) { 00734 Fast_Two_Sum(enow, Q, Qnew, hh); 00735 enow = e[++eindex]; 00736 } else { 00737 Fast_Two_Sum(fnow, Q, Qnew, hh); 00738 fnow = f[++findex]; 00739 } 00740 Q = Qnew; 00741 if (hh != 0.0) { 00742 h[hindex++] = hh; 00743 } 00744 while ((eindex < elen) && (findex < flen)) { 00745 if ((fnow > enow) == (fnow > -enow)) { 00746 Two_Sum(Q, enow, Qnew, hh); 00747 enow = e[++eindex]; 00748 } else { 00749 Two_Sum(Q, fnow, Qnew, hh); 00750 fnow = f[++findex]; 00751 } 00752 Q = Qnew; 00753 if (hh != 0.0) { 00754 h[hindex++] = hh; 00755 } 00756 } 00757 } 00758 while (eindex < elen) { 00759 Two_Sum(Q, enow, Qnew, hh); 00760 enow = e[++eindex]; 00761 Q = Qnew; 00762 if (hh != 0.0) { 00763 h[hindex++] = hh; 00764 } 00765 } 00766 while (findex < flen) { 00767 Two_Sum(Q, fnow, Qnew, hh); 00768 fnow = f[++findex]; 00769 Q = Qnew; 00770 if (hh != 0.0) { 00771 h[hindex++] = hh; 00772 } 00773 } 00774 if ((Q != 0.0) || (hindex == 0)) { 00775 h[hindex++] = Q; 00776 } 00777 return hindex; 00778 } 00779 00780 /*****************************************************************************/ 00781 /* */ 00782 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ 00783 /* eliminating zero components from the */ 00784 /* output expansion. */ 00785 /* */ 00786 /* Sets h = be. See either version of my paper for details. */ 00787 /* */ 00788 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00789 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ 00790 /* properties as well. (That is, if e has one of these properties, so */ 00791 /* will h.) */ 00792 /* */ 00793 /*****************************************************************************/ 00794 00795 static int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) 00796 /* e and h cannot be the same. */ 00797 { 00798 INEXACT REAL Q, sum; 00799 REAL hh; 00800 INEXACT REAL product1; 00801 REAL product0; 00802 int eindex, hindex; 00803 REAL enow; 00804 INEXACT REAL bvirt; 00805 REAL avirt, bround, around; 00806 INEXACT REAL c; 00807 INEXACT REAL abig; 00808 REAL ahi, alo, bhi, blo; 00809 REAL err1, err2, err3; 00810 00811 Split(b, bhi, blo); 00812 Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); 00813 hindex = 0; 00814 if (hh != 0) { 00815 h[hindex++] = hh; 00816 } 00817 for (eindex = 1; eindex < elen; eindex++) { 00818 enow = e[eindex]; 00819 Two_Product_Presplit(enow, b, bhi, blo, product1, product0); 00820 Two_Sum(Q, product0, sum, hh); 00821 if (hh != 0) { 00822 h[hindex++] = hh; 00823 } 00824 Fast_Two_Sum(product1, sum, Q, hh); 00825 if (hh != 0) { 00826 h[hindex++] = hh; 00827 } 00828 } 00829 if ((Q != 0.0) || (hindex == 0)) { 00830 h[hindex++] = Q; 00831 } 00832 return hindex; 00833 } 00834 00835 /*****************************************************************************/ 00836 /* */ 00837 /* estimate() Produce a one-word estimate of an expansion's value. */ 00838 /* */ 00839 /* See either version of my paper for details. */ 00840 /* */ 00841 /*****************************************************************************/ 00842 00843 static REAL estimate(int elen, REAL *e) 00844 { 00845 REAL Q; 00846 int eindex; 00847 00848 Q = e[0]; 00849 for (eindex = 1; eindex < elen; eindex++) { 00850 Q += e[eindex]; 00851 } 00852 return Q; 00853 } 00854 00855 /*****************************************************************************/ 00856 /* */ 00857 /* orient2dfast() Approximate 2D orientation test. Nonrobust. */ 00858 /* orient2dexact() Exact 2D orientation test. Robust. */ 00859 /* orient2dslow() Another exact 2D orientation test. Robust. */ 00860 /* orient2d() Adaptive exact 2D orientation test. Robust. */ 00861 /* */ 00862 /* Return a positive value if the points pa, pb, and pc occur */ 00863 /* in counterclockwise order; a negative value if they occur */ 00864 /* in clockwise order; and zero if they are collinear. The */ 00865 /* result is also a rough approximation of twice the signed */ 00866 /* area of the triangle defined by the three points. */ 00867 /* */ 00868 /* Only the first and last routine should be used; the middle two are for */ 00869 /* timings. */ 00870 /* */ 00871 /* The last three use exact arithmetic to ensure a correct answer. The */ 00872 /* result returned is the determinant of a matrix. In orient2d() only, */ 00873 /* this determinant is computed adaptively, in the sense that exact */ 00874 /* arithmetic is used only to the degree it is needed to ensure that the */ 00875 /* returned value has the correct sign. Hence, orient2d() is usually quite */ 00876 /* fast, but will run more slowly when the input points are collinear or */ 00877 /* nearly so. */ 00878 /* */ 00879 /*****************************************************************************/ 00880 00881 static REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum) 00882 { 00883 INEXACT REAL acx, acy, bcx, bcy; 00884 REAL acxtail, acytail, bcxtail, bcytail; 00885 INEXACT REAL detleft, detright; 00886 REAL detlefttail, detrighttail; 00887 REAL det, errbound; 00888 REAL B[4], C1[8], C2[12], D[16]; 00889 INEXACT REAL B3; 00890 int C1length, C2length, Dlength; 00891 REAL u[4]; 00892 INEXACT REAL u3; 00893 INEXACT REAL s1, t1; 00894 REAL s0, t0; 00895 00896 INEXACT REAL bvirt; 00897 REAL avirt, bround, around; 00898 INEXACT REAL c; 00899 INEXACT REAL abig; 00900 REAL ahi, alo, bhi, blo; 00901 REAL err1, err2, err3; 00902 INEXACT REAL _i, _j; 00903 REAL _0; 00904 00905 acx = (REAL) (pa[0] - pc[0]); 00906 bcx = (REAL) (pb[0] - pc[0]); 00907 acy = (REAL) (pa[1] - pc[1]); 00908 bcy = (REAL) (pb[1] - pc[1]); 00909 00910 Two_Product(acx, bcy, detleft, detlefttail); 00911 Two_Product(acy, bcx, detright, detrighttail); 00912 00913 Two_Two_Diff(detleft, detlefttail, detright, detrighttail, 00914 B3, B[2], B[1], B[0]); 00915 B[3] = B3; 00916 00917 det = estimate(4, B); 00918 errbound = ccwerrboundB * detsum; 00919 if ((det >= errbound) || (-det >= errbound)) { 00920 return det; 00921 } 00922 00923 Two_Diff_Tail(pa[0], pc[0], acx, acxtail); 00924 Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); 00925 Two_Diff_Tail(pa[1], pc[1], acy, acytail); 00926 Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); 00927 00928 if ((acxtail == 0.0) && (acytail == 0.0) 00929 && (bcxtail == 0.0) && (bcytail == 0.0)) { 00930 return det; 00931 } 00932 00933 errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); 00934 det += (acx * bcytail + bcy * acxtail) 00935 - (acy * bcxtail + bcx * acytail); 00936 if ((det >= errbound) || (-det >= errbound)) { 00937 return det; 00938 } 00939 00940 Two_Product(acxtail, bcy, s1, s0); 00941 Two_Product(acytail, bcx, t1, t0); 00942 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 00943 u[3] = u3; 00944 C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); 00945 00946 Two_Product(acx, bcytail, s1, s0); 00947 Two_Product(acy, bcxtail, t1, t0); 00948 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 00949 u[3] = u3; 00950 C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); 00951 00952 Two_Product(acxtail, bcytail, s1, s0); 00953 Two_Product(acytail, bcxtail, t1, t0); 00954 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 00955 u[3] = u3; 00956 Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); 00957 00958 return(D[Dlength - 1]); 00959 } 00960 00961 REAL orient2d(pa, pb, pc) 00962 REAL *pa; 00963 REAL *pb; 00964 REAL *pc; 00965 { 00966 REAL detleft, detright, det; 00967 REAL detsum, errbound; 00968 REAL orient; 00969 00970 FPU_ROUND_DOUBLE; 00971 00972 detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); 00973 detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); 00974 det = detleft - detright; 00975 00976 if (detleft > 0.0) { 00977 if (detright <= 0.0) { 00978 FPU_RESTORE; 00979 return det; 00980 } else { 00981 detsum = detleft + detright; 00982 } 00983 } else if (detleft < 0.0) { 00984 if (detright >= 0.0) { 00985 FPU_RESTORE; 00986 return det; 00987 } else { 00988 detsum = -detleft - detright; 00989 } 00990 } else { 00991 FPU_RESTORE; 00992 return det; 00993 } 00994 00995 errbound = ccwerrboundA * detsum; 00996 if ((det >= errbound) || (-det >= errbound)) { 00997 FPU_RESTORE; 00998 return det; 00999 } 01000 01001 orient = orient2dadapt(pa, pb, pc, detsum); 01002 FPU_RESTORE; 01003 return orient; 01004 } 01005 01006 /*****************************************************************************/ 01007 /* */ 01008 /* orient3dfast() Approximate 3D orientation test. Nonrobust. */ 01009 /* orient3dexact() Exact 3D orientation test. Robust. */ 01010 /* orient3dslow() Another exact 3D orientation test. Robust. */ 01011 /* orient3d() Adaptive exact 3D orientation test. Robust. */ 01012 /* */ 01013 /* Return a positive value if the point pd lies below the */ 01014 /* plane passing through pa, pb, and pc; "below" is defined so */ 01015 /* that pa, pb, and pc appear in counterclockwise order when */ 01016 /* viewed from above the plane. Returns a negative value if */ 01017 /* pd lies above the plane. Returns zero if the points are */ 01018 /* coplanar. The result is also a rough approximation of six */ 01019 /* times the signed volume of the tetrahedron defined by the */ 01020 /* four points. */ 01021 /* */ 01022 /* Only the first and last routine should be used; the middle two are for */ 01023 /* timings. */ 01024 /* */ 01025 /* The last three use exact arithmetic to ensure a correct answer. The */ 01026 /* result returned is the determinant of a matrix. In orient3d() only, */ 01027 /* this determinant is computed adaptively, in the sense that exact */ 01028 /* arithmetic is used only to the degree it is needed to ensure that the */ 01029 /* returned value has the correct sign. Hence, orient3d() is usually quite */ 01030 /* fast, but will run more slowly when the input points are coplanar or */ 01031 /* nearly so. */ 01032 /* */ 01033 /*****************************************************************************/ 01034 01035 static REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, 01036 REAL permanent) 01037 { 01038 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; 01039 REAL det, errbound; 01040 01041 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; 01042 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; 01043 REAL bc[4], ca[4], ab[4]; 01044 INEXACT REAL bc3, ca3, ab3; 01045 REAL adet[8], bdet[8], cdet[8]; 01046 int alen, blen, clen; 01047 REAL abdet[16]; 01048 int ablen; 01049 REAL *finnow, *finother, *finswap; 01050 REAL fin1[192], fin2[192]; 01051 int finlength; 01052 01053 REAL adxtail, bdxtail, cdxtail; 01054 REAL adytail, bdytail, cdytail; 01055 REAL adztail, bdztail, cdztail; 01056 INEXACT REAL at_blarge, at_clarge; 01057 INEXACT REAL bt_clarge, bt_alarge; 01058 INEXACT REAL ct_alarge, ct_blarge; 01059 REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; 01060 int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; 01061 INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; 01062 INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; 01063 REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; 01064 REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; 01065 INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; 01066 INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; 01067 REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; 01068 REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; 01069 REAL bct[8], cat[8], abt[8]; 01070 int bctlen, catlen, abtlen; 01071 INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; 01072 INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; 01073 REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; 01074 REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; 01075 REAL u[4], v[12], w[16]; 01076 INEXACT REAL u3; 01077 int vlength, wlength; 01078 REAL negate; 01079 01080 INEXACT REAL bvirt; 01081 REAL avirt, bround, around; 01082 INEXACT REAL c; 01083 INEXACT REAL abig; 01084 REAL ahi, alo, bhi, blo; 01085 REAL err1, err2, err3; 01086 INEXACT REAL _i, _j, _k; 01087 REAL _0; 01088 01089 adx = (REAL) (pa[0] - pd[0]); 01090 bdx = (REAL) (pb[0] - pd[0]); 01091 cdx = (REAL) (pc[0] - pd[0]); 01092 ady = (REAL) (pa[1] - pd[1]); 01093 bdy = (REAL) (pb[1] - pd[1]); 01094 cdy = (REAL) (pc[1] - pd[1]); 01095 adz = (REAL) (pa[2] - pd[2]); 01096 bdz = (REAL) (pb[2] - pd[2]); 01097 cdz = (REAL) (pc[2] - pd[2]); 01098 01099 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); 01100 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); 01101 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); 01102 bc[3] = bc3; 01103 alen = scale_expansion_zeroelim(4, bc, adz, adet); 01104 01105 Two_Product(cdx, ady, cdxady1, cdxady0); 01106 Two_Product(adx, cdy, adxcdy1, adxcdy0); 01107 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); 01108 ca[3] = ca3; 01109 blen = scale_expansion_zeroelim(4, ca, bdz, bdet); 01110 01111 Two_Product(adx, bdy, adxbdy1, adxbdy0); 01112 Two_Product(bdx, ady, bdxady1, bdxady0); 01113 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); 01114 ab[3] = ab3; 01115 clen = scale_expansion_zeroelim(4, ab, cdz, cdet); 01116 01117 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 01118 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); 01119 01120 det = estimate(finlength, fin1); 01121 errbound = o3derrboundB * permanent; 01122 if ((det >= errbound) || (-det >= errbound)) { 01123 return det; 01124 } 01125 01126 Two_Diff_Tail(pa[0], pd[0], adx, adxtail); 01127 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); 01128 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); 01129 Two_Diff_Tail(pa[1], pd[1], ady, adytail); 01130 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); 01131 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); 01132 Two_Diff_Tail(pa[2], pd[2], adz, adztail); 01133 Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); 01134 Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); 01135 01136 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) 01137 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) 01138 && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { 01139 return det; 01140 } 01141 01142 errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); 01143 det += (adz * ((bdx * cdytail + cdy * bdxtail) 01144 - (bdy * cdxtail + cdx * bdytail)) 01145 + adztail * (bdx * cdy - bdy * cdx)) 01146 + (bdz * ((cdx * adytail + ady * cdxtail) 01147 - (cdy * adxtail + adx * cdytail)) 01148 + bdztail * (cdx * ady - cdy * adx)) 01149 + (cdz * ((adx * bdytail + bdy * adxtail) 01150 - (ady * bdxtail + bdx * adytail)) 01151 + cdztail * (adx * bdy - ady * bdx)); 01152 if ((det >= errbound) || (-det >= errbound)) { 01153 return det; 01154 } 01155 01156 finnow = fin1; 01157 finother = fin2; 01158 01159 if (adxtail == 0.0) { 01160 if (adytail == 0.0) { 01161 at_b[0] = 0.0; 01162 at_blen = 1; 01163 at_c[0] = 0.0; 01164 at_clen = 1; 01165 } else { 01166 negate = -adytail; 01167 Two_Product(negate, bdx, at_blarge, at_b[0]); 01168 at_b[1] = at_blarge; 01169 at_blen = 2; 01170 Two_Product(adytail, cdx, at_clarge, at_c[0]); 01171 at_c[1] = at_clarge; 01172 at_clen = 2; 01173 } 01174 } else { 01175 if (adytail == 0.0) { 01176 Two_Product(adxtail, bdy, at_blarge, at_b[0]); 01177 at_b[1] = at_blarge; 01178 at_blen = 2; 01179 negate = -adxtail; 01180 Two_Product(negate, cdy, at_clarge, at_c[0]); 01181 at_c[1] = at_clarge; 01182 at_clen = 2; 01183 } else { 01184 Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); 01185 Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); 01186 Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, 01187 at_blarge, at_b[2], at_b[1], at_b[0]); 01188 at_b[3] = at_blarge; 01189 at_blen = 4; 01190 Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); 01191 Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); 01192 Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, 01193 at_clarge, at_c[2], at_c[1], at_c[0]); 01194 at_c[3] = at_clarge; 01195 at_clen = 4; 01196 } 01197 } 01198 if (bdxtail == 0.0) { 01199 if (bdytail == 0.0) { 01200 bt_c[0] = 0.0; 01201 bt_clen = 1; 01202 bt_a[0] = 0.0; 01203 bt_alen = 1; 01204 } else { 01205 negate = -bdytail; 01206 Two_Product(negate, cdx, bt_clarge, bt_c[0]); 01207 bt_c[1] = bt_clarge; 01208 bt_clen = 2; 01209 Two_Product(bdytail, adx, bt_alarge, bt_a[0]); 01210 bt_a[1] = bt_alarge; 01211 bt_alen = 2; 01212 } 01213 } else { 01214 if (bdytail == 0.0) { 01215 Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); 01216 bt_c[1] = bt_clarge; 01217 bt_clen = 2; 01218 negate = -bdxtail; 01219 Two_Product(negate, ady, bt_alarge, bt_a[0]); 01220 bt_a[1] = bt_alarge; 01221 bt_alen = 2; 01222 } else { 01223 Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); 01224 Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); 01225 Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, 01226 bt_clarge, bt_c[2], bt_c[1], bt_c[0]); 01227 bt_c[3] = bt_clarge; 01228 bt_clen = 4; 01229 Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); 01230 Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); 01231 Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, 01232 bt_alarge, bt_a[2], bt_a[1], bt_a[0]); 01233 bt_a[3] = bt_alarge; 01234 bt_alen = 4; 01235 } 01236 } 01237 if (cdxtail == 0.0) { 01238 if (cdytail == 0.0) { 01239 ct_a[0] = 0.0; 01240 ct_alen = 1; 01241 ct_b[0] = 0.0; 01242 ct_blen = 1; 01243 } else { 01244 negate = -cdytail; 01245 Two_Product(negate, adx, ct_alarge, ct_a[0]); 01246 ct_a[1] = ct_alarge; 01247 ct_alen = 2; 01248 Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); 01249 ct_b[1] = ct_blarge; 01250 ct_blen = 2; 01251 } 01252 } else { 01253 if (cdytail == 0.0) { 01254 Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); 01255 ct_a[1] = ct_alarge; 01256 ct_alen = 2; 01257 negate = -cdxtail; 01258 Two_Product(negate, bdy, ct_blarge, ct_b[0]); 01259 ct_b[1] = ct_blarge; 01260 ct_blen = 2; 01261 } else { 01262 Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); 01263 Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); 01264 Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, 01265 ct_alarge, ct_a[2], ct_a[1], ct_a[0]); 01266 ct_a[3] = ct_alarge; 01267 ct_alen = 4; 01268 Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); 01269 Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); 01270 Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, 01271 ct_blarge, ct_b[2], ct_b[1], ct_b[0]); 01272 ct_b[3] = ct_blarge; 01273 ct_blen = 4; 01274 } 01275 } 01276 01277 bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); 01278 wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); 01279 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01280 finother); 01281 finswap = finnow; finnow = finother; finother = finswap; 01282 01283 catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); 01284 wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); 01285 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01286 finother); 01287 finswap = finnow; finnow = finother; finother = finswap; 01288 01289 abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); 01290 wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); 01291 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01292 finother); 01293 finswap = finnow; finnow = finother; finother = finswap; 01294 01295 if (adztail != 0.0) { 01296 vlength = scale_expansion_zeroelim(4, bc, adztail, v); 01297 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 01298 finother); 01299 finswap = finnow; finnow = finother; finother = finswap; 01300 } 01301 if (bdztail != 0.0) { 01302 vlength = scale_expansion_zeroelim(4, ca, bdztail, v); 01303 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 01304 finother); 01305 finswap = finnow; finnow = finother; finother = finswap; 01306 } 01307 if (cdztail != 0.0) { 01308 vlength = scale_expansion_zeroelim(4, ab, cdztail, v); 01309 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 01310 finother); 01311 finswap = finnow; finnow = finother; finother = finswap; 01312 } 01313 01314 if (adxtail != 0.0) { 01315 if (bdytail != 0.0) { 01316 Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); 01317 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); 01318 u[3] = u3; 01319 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01320 finother); 01321 finswap = finnow; finnow = finother; finother = finswap; 01322 if (cdztail != 0.0) { 01323 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); 01324 u[3] = u3; 01325 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01326 finother); 01327 finswap = finnow; finnow = finother; finother = finswap; 01328 } 01329 } 01330 if (cdytail != 0.0) { 01331 negate = -adxtail; 01332 Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); 01333 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); 01334 u[3] = u3; 01335 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01336 finother); 01337 finswap = finnow; finnow = finother; finother = finswap; 01338 if (bdztail != 0.0) { 01339 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); 01340 u[3] = u3; 01341 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01342 finother); 01343 finswap = finnow; finnow = finother; finother = finswap; 01344 } 01345 } 01346 } 01347 if (bdxtail != 0.0) { 01348 if (cdytail != 0.0) { 01349 Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); 01350 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); 01351 u[3] = u3; 01352 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01353 finother); 01354 finswap = finnow; finnow = finother; finother = finswap; 01355 if (adztail != 0.0) { 01356 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); 01357 u[3] = u3; 01358 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01359 finother); 01360 finswap = finnow; finnow = finother; finother = finswap; 01361 } 01362 } 01363 if (adytail != 0.0) { 01364 negate = -bdxtail; 01365 Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); 01366 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); 01367 u[3] = u3; 01368 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01369 finother); 01370 finswap = finnow; finnow = finother; finother = finswap; 01371 if (cdztail != 0.0) { 01372 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); 01373 u[3] = u3; 01374 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01375 finother); 01376 finswap = finnow; finnow = finother; finother = finswap; 01377 } 01378 } 01379 } 01380 if (cdxtail != 0.0) { 01381 if (adytail != 0.0) { 01382 Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); 01383 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); 01384 u[3] = u3; 01385 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01386 finother); 01387 finswap = finnow; finnow = finother; finother = finswap; 01388 if (bdztail != 0.0) { 01389 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); 01390 u[3] = u3; 01391 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01392 finother); 01393 finswap = finnow; finnow = finother; finother = finswap; 01394 } 01395 } 01396 if (bdytail != 0.0) { 01397 negate = -cdxtail; 01398 Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); 01399 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); 01400 u[3] = u3; 01401 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01402 finother); 01403 finswap = finnow; finnow = finother; finother = finswap; 01404 if (adztail != 0.0) { 01405 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); 01406 u[3] = u3; 01407 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 01408 finother); 01409 finswap = finnow; finnow = finother; finother = finswap; 01410 } 01411 } 01412 } 01413 01414 if (adztail != 0.0) { 01415 wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); 01416 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01417 finother); 01418 finswap = finnow; finnow = finother; finother = finswap; 01419 } 01420 if (bdztail != 0.0) { 01421 wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); 01422 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01423 finother); 01424 finswap = finnow; finnow = finother; finother = finswap; 01425 } 01426 if (cdztail != 0.0) { 01427 wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); 01428 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 01429 finother); 01430 finswap = finnow; finnow = finother; finother = finswap; 01431 } 01432 01433 return finnow[finlength - 1]; 01434 } 01435 01436 REAL orient3d(pa, pb, pc, pd) 01437 REAL *pa; 01438 REAL *pb; 01439 REAL *pc; 01440 REAL *pd; 01441 { 01442 REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; 01443 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; 01444 REAL det; 01445 REAL permanent, errbound; 01446 REAL orient; 01447 01448 FPU_ROUND_DOUBLE; 01449 01450 adx = pa[0] - pd[0]; 01451 bdx = pb[0] - pd[0]; 01452 cdx = pc[0] - pd[0]; 01453 ady = pa[1] - pd[1]; 01454 bdy = pb[1] - pd[1]; 01455 cdy = pc[1] - pd[1]; 01456 adz = pa[2] - pd[2]; 01457 bdz = pb[2] - pd[2]; 01458 cdz = pc[2] - pd[2]; 01459 01460 bdxcdy = bdx * cdy; 01461 cdxbdy = cdx * bdy; 01462 01463 cdxady = cdx * ady; 01464 adxcdy = adx * cdy; 01465 01466 adxbdy = adx * bdy; 01467 bdxady = bdx * ady; 01468 01469 det = adz * (bdxcdy - cdxbdy) 01470 + bdz * (cdxady - adxcdy) 01471 + cdz * (adxbdy - bdxady); 01472 01473 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) 01474 + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) 01475 + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); 01476 errbound = o3derrboundA * permanent; 01477 if ((det > errbound) || (-det > errbound)) { 01478 FPU_RESTORE; 01479 return det; 01480 } 01481 01482 orient = orient3dadapt(pa, pb, pc, pd, permanent); 01483 FPU_RESTORE; 01484 return orient; 01485 } 01486 01487 /*****************************************************************************/ 01488 /* */ 01489 /* incirclefast() Approximate 2D incircle test. Nonrobust. */ 01490 /* incircleexact() Exact 2D incircle test. Robust. */ 01491 /* incircleslow() Another exact 2D incircle test. Robust. */ 01492 /* incircle() Adaptive exact 2D incircle test. Robust. */ 01493 /* */ 01494 /* Return a positive value if the point pd lies inside the */ 01495 /* circle passing through pa, pb, and pc; a negative value if */ 01496 /* it lies outside; and zero if the four points are cocircular.*/ 01497 /* The points pa, pb, and pc must be in counterclockwise */ 01498 /* order, or the sign of the result will be reversed. */ 01499 /* */ 01500 /* Only the first and last routine should be used; the middle two are for */ 01501 /* timings. */ 01502 /* */ 01503 /* The last three use exact arithmetic to ensure a correct answer. The */ 01504 /* result returned is the determinant of a matrix. In incircle() only, */ 01505 /* this determinant is computed adaptively, in the sense that exact */ 01506 /* arithmetic is used only to the degree it is needed to ensure that the */ 01507 /* returned value has the correct sign. Hence, incircle() is usually quite */ 01508 /* fast, but will run more slowly when the input points are cocircular or */ 01509 /* nearly so. */ 01510 /* */ 01511 /*****************************************************************************/ 01512 01513 static REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, 01514 REAL permanent) 01515 { 01516 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; 01517 REAL det, errbound; 01518 01519 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; 01520 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; 01521 REAL bc[4], ca[4], ab[4]; 01522 INEXACT REAL bc3, ca3, ab3; 01523 REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; 01524 int axbclen, axxbclen, aybclen, ayybclen, alen; 01525 REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; 01526 int bxcalen, bxxcalen, bycalen, byycalen, blen; 01527 REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; 01528 int cxablen, cxxablen, cyablen, cyyablen, clen; 01529 REAL abdet[64]; 01530 int ablen; 01531 REAL fin1[1152], fin2[1152]; 01532 REAL *finnow, *finother, *finswap; 01533 int finlength; 01534 01535 REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; 01536 INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; 01537 REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; 01538 REAL aa[4], bb[4], cc[4]; 01539 INEXACT REAL aa3, bb3, cc3; 01540 INEXACT REAL ti1, tj1; 01541 REAL ti0, tj0; 01542 REAL u[4], v[4]; 01543 INEXACT REAL u3, v3; 01544 REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; 01545 REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; 01546 int temp8len, temp16alen, temp16blen, temp16clen; 01547 int temp32alen, temp32blen, temp48len, temp64len; 01548 REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; 01549 int axtbblen, axtcclen, aytbblen, aytcclen; 01550 REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; 01551 int bxtaalen, bxtcclen, bytaalen, bytcclen; 01552 REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; 01553 int cxtaalen, cxtbblen, cytaalen, cytbblen; 01554 REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; 01555 int axtbclen = 0, aytbclen = 0; 01556 int bxtcalen = 0, bytcalen = 0; 01557 int cxtablen = 0, cytablen = 0; 01558 REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; 01559 int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; 01560 REAL axtbctt[8], aytbctt[8], bxtcatt[8]; 01561 REAL bytcatt[8], cxtabtt[8], cytabtt[8]; 01562 int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; 01563 REAL abt[8], bct[8], cat[8]; 01564 int abtlen, bctlen, catlen; 01565 REAL abtt[4], bctt[4], catt[4]; 01566 int abttlen, bcttlen, cattlen; 01567 INEXACT REAL abtt3, bctt3, catt3; 01568 REAL negate; 01569 01570 INEXACT REAL bvirt; 01571 REAL avirt, bround, around; 01572 INEXACT REAL c; 01573 INEXACT REAL abig; 01574 REAL ahi, alo, bhi, blo; 01575 REAL err1, err2, err3; 01576 INEXACT REAL _i, _j; 01577 REAL _0; 01578 01579 adx = (REAL) (pa[0] - pd[0]); 01580 bdx = (REAL) (pb[0] - pd[0]); 01581 cdx = (REAL) (pc[0] - pd[0]); 01582 ady = (REAL) (pa[1] - pd[1]); 01583 bdy = (REAL) (pb[1] - pd[1]); 01584 cdy = (REAL) (pc[1] - pd[1]); 01585 01586 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); 01587 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); 01588 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); 01589 bc[3] = bc3; 01590 axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); 01591 axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); 01592 aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); 01593 ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); 01594 alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); 01595 01596 Two_Product(cdx, ady, cdxady1, cdxady0); 01597 Two_Product(adx, cdy, adxcdy1, adxcdy0); 01598 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); 01599 ca[3] = ca3; 01600 bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); 01601 bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); 01602 bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); 01603 byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); 01604 blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); 01605 01606 Two_Product(adx, bdy, adxbdy1, adxbdy0); 01607 Two_Product(bdx, ady, bdxady1, bdxady0); 01608 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); 01609 ab[3] = ab3; 01610 cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); 01611 cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); 01612 cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); 01613 cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); 01614 clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); 01615 01616 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 01617 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); 01618 01619 det = estimate(finlength, fin1); 01620 errbound = iccerrboundB * permanent; 01621 if ((det >= errbound) || (-det >= errbound)) { 01622 return det; 01623 } 01624 01625 Two_Diff_Tail(pa[0], pd[0], adx, adxtail); 01626 Two_Diff_Tail(pa[1], pd[1], ady, adytail); 01627 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); 01628 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); 01629 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); 01630 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); 01631 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) 01632 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { 01633 return det; 01634 } 01635 01636 errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); 01637 det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) 01638 - (bdy * cdxtail + cdx * bdytail)) 01639 + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) 01640 + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) 01641 - (cdy * adxtail + adx * cdytail)) 01642 + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) 01643 + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) 01644 - (ady * bdxtail + bdx * adytail)) 01645 + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); 01646 if ((det >= errbound) || (-det >= errbound)) { 01647 return det; 01648 } 01649 01650 finnow = fin1; 01651 finother = fin2; 01652 01653 if ((bdxtail != 0.0) || (bdytail != 0.0) 01654 || (cdxtail != 0.0) || (cdytail != 0.0)) { 01655 Square(adx, adxadx1, adxadx0); 01656 Square(ady, adyady1, adyady0); 01657 Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); 01658 aa[3] = aa3; 01659 } 01660 if ((cdxtail != 0.0) || (cdytail != 0.0) 01661 || (adxtail != 0.0) || (adytail != 0.0)) { 01662 Square(bdx, bdxbdx1, bdxbdx0); 01663 Square(bdy, bdybdy1, bdybdy0); 01664 Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); 01665 bb[3] = bb3; 01666 } 01667 if ((adxtail != 0.0) || (adytail != 0.0) 01668 || (bdxtail != 0.0) || (bdytail != 0.0)) { 01669 Square(cdx, cdxcdx1, cdxcdx0); 01670 Square(cdy, cdycdy1, cdycdy0); 01671 Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); 01672 cc[3] = cc3; 01673 } 01674 01675 if (adxtail != 0.0) { 01676 axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); 01677 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, 01678 temp16a); 01679 01680 axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); 01681 temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); 01682 01683 axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); 01684 temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); 01685 01686 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01687 temp16blen, temp16b, temp32a); 01688 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01689 temp32alen, temp32a, temp48); 01690 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01691 temp48, finother); 01692 finswap = finnow; finnow = finother; finother = finswap; 01693 } 01694 if (adytail != 0.0) { 01695 aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); 01696 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, 01697 temp16a); 01698 01699 aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); 01700 temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); 01701 01702 aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); 01703 temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); 01704 01705 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01706 temp16blen, temp16b, temp32a); 01707 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01708 temp32alen, temp32a, temp48); 01709 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01710 temp48, finother); 01711 finswap = finnow; finnow = finother; finother = finswap; 01712 } 01713 if (bdxtail != 0.0) { 01714 bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); 01715 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, 01716 temp16a); 01717 01718 bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); 01719 temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); 01720 01721 bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); 01722 temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); 01723 01724 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01725 temp16blen, temp16b, temp32a); 01726 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01727 temp32alen, temp32a, temp48); 01728 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01729 temp48, finother); 01730 finswap = finnow; finnow = finother; finother = finswap; 01731 } 01732 if (bdytail != 0.0) { 01733 bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); 01734 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, 01735 temp16a); 01736 01737 bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); 01738 temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); 01739 01740 bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); 01741 temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); 01742 01743 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01744 temp16blen, temp16b, temp32a); 01745 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01746 temp32alen, temp32a, temp48); 01747 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01748 temp48, finother); 01749 finswap = finnow; finnow = finother; finother = finswap; 01750 } 01751 if (cdxtail != 0.0) { 01752 cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); 01753 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, 01754 temp16a); 01755 01756 cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); 01757 temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); 01758 01759 cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); 01760 temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); 01761 01762 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01763 temp16blen, temp16b, temp32a); 01764 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01765 temp32alen, temp32a, temp48); 01766 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01767 temp48, finother); 01768 finswap = finnow; finnow = finother; finother = finswap; 01769 } 01770 if (cdytail != 0.0) { 01771 cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); 01772 temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, 01773 temp16a); 01774 01775 cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); 01776 temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); 01777 01778 cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); 01779 temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); 01780 01781 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01782 temp16blen, temp16b, temp32a); 01783 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 01784 temp32alen, temp32a, temp48); 01785 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01786 temp48, finother); 01787 finswap = finnow; finnow = finother; finother = finswap; 01788 } 01789 01790 if ((adxtail != 0.0) || (adytail != 0.0)) { 01791 if ((bdxtail != 0.0) || (bdytail != 0.0) 01792 || (cdxtail != 0.0) || (cdytail != 0.0)) { 01793 Two_Product(bdxtail, cdy, ti1, ti0); 01794 Two_Product(bdx, cdytail, tj1, tj0); 01795 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 01796 u[3] = u3; 01797 negate = -bdy; 01798 Two_Product(cdxtail, negate, ti1, ti0); 01799 negate = -bdytail; 01800 Two_Product(cdx, negate, tj1, tj0); 01801 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 01802 v[3] = v3; 01803 bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); 01804 01805 Two_Product(bdxtail, cdytail, ti1, ti0); 01806 Two_Product(cdxtail, bdytail, tj1, tj0); 01807 Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); 01808 bctt[3] = bctt3; 01809 bcttlen = 4; 01810 } else { 01811 bct[0] = 0.0; 01812 bctlen = 1; 01813 bctt[0] = 0.0; 01814 bcttlen = 1; 01815 } 01816 01817 if (adxtail != 0.0) { 01818 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); 01819 axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); 01820 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, 01821 temp32a); 01822 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01823 temp32alen, temp32a, temp48); 01824 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01825 temp48, finother); 01826 finswap = finnow; finnow = finother; finother = finswap; 01827 if (bdytail != 0.0) { 01828 temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); 01829 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, 01830 temp16a); 01831 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 01832 temp16a, finother); 01833 finswap = finnow; finnow = finother; finother = finswap; 01834 } 01835 if (cdytail != 0.0) { 01836 temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); 01837 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, 01838 temp16a); 01839 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 01840 temp16a, finother); 01841 finswap = finnow; finnow = finother; finother = finswap; 01842 } 01843 01844 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, 01845 temp32a); 01846 axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); 01847 temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, 01848 temp16a); 01849 temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, 01850 temp16b); 01851 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01852 temp16blen, temp16b, temp32b); 01853 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 01854 temp32blen, temp32b, temp64); 01855 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 01856 temp64, finother); 01857 finswap = finnow; finnow = finother; finother = finswap; 01858 } 01859 if (adytail != 0.0) { 01860 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); 01861 aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); 01862 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, 01863 temp32a); 01864 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01865 temp32alen, temp32a, temp48); 01866 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01867 temp48, finother); 01868 finswap = finnow; finnow = finother; finother = finswap; 01869 01870 01871 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, 01872 temp32a); 01873 aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); 01874 temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, 01875 temp16a); 01876 temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, 01877 temp16b); 01878 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01879 temp16blen, temp16b, temp32b); 01880 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 01881 temp32blen, temp32b, temp64); 01882 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 01883 temp64, finother); 01884 finswap = finnow; finnow = finother; finother = finswap; 01885 } 01886 } 01887 if ((bdxtail != 0.0) || (bdytail != 0.0)) { 01888 if ((cdxtail != 0.0) || (cdytail != 0.0) 01889 || (adxtail != 0.0) || (adytail != 0.0)) { 01890 Two_Product(cdxtail, ady, ti1, ti0); 01891 Two_Product(cdx, adytail, tj1, tj0); 01892 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 01893 u[3] = u3; 01894 negate = -cdy; 01895 Two_Product(adxtail, negate, ti1, ti0); 01896 negate = -cdytail; 01897 Two_Product(adx, negate, tj1, tj0); 01898 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 01899 v[3] = v3; 01900 catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); 01901 01902 Two_Product(cdxtail, adytail, ti1, ti0); 01903 Two_Product(adxtail, cdytail, tj1, tj0); 01904 Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); 01905 catt[3] = catt3; 01906 cattlen = 4; 01907 } else { 01908 cat[0] = 0.0; 01909 catlen = 1; 01910 catt[0] = 0.0; 01911 cattlen = 1; 01912 } 01913 01914 if (bdxtail != 0.0) { 01915 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); 01916 bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); 01917 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, 01918 temp32a); 01919 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01920 temp32alen, temp32a, temp48); 01921 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01922 temp48, finother); 01923 finswap = finnow; finnow = finother; finother = finswap; 01924 if (cdytail != 0.0) { 01925 temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); 01926 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, 01927 temp16a); 01928 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 01929 temp16a, finother); 01930 finswap = finnow; finnow = finother; finother = finswap; 01931 } 01932 if (adytail != 0.0) { 01933 temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); 01934 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, 01935 temp16a); 01936 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 01937 temp16a, finother); 01938 finswap = finnow; finnow = finother; finother = finswap; 01939 } 01940 01941 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, 01942 temp32a); 01943 bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); 01944 temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, 01945 temp16a); 01946 temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, 01947 temp16b); 01948 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01949 temp16blen, temp16b, temp32b); 01950 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 01951 temp32blen, temp32b, temp64); 01952 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 01953 temp64, finother); 01954 finswap = finnow; finnow = finother; finother = finswap; 01955 } 01956 if (bdytail != 0.0) { 01957 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); 01958 bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); 01959 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, 01960 temp32a); 01961 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01962 temp32alen, temp32a, temp48); 01963 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 01964 temp48, finother); 01965 finswap = finnow; finnow = finother; finother = finswap; 01966 01967 01968 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, 01969 temp32a); 01970 bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); 01971 temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, 01972 temp16a); 01973 temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, 01974 temp16b); 01975 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 01976 temp16blen, temp16b, temp32b); 01977 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 01978 temp32blen, temp32b, temp64); 01979 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 01980 temp64, finother); 01981 finswap = finnow; finnow = finother; finother = finswap; 01982 } 01983 } 01984 if ((cdxtail != 0.0) || (cdytail != 0.0)) { 01985 if ((adxtail != 0.0) || (adytail != 0.0) 01986 || (bdxtail != 0.0) || (bdytail != 0.0)) { 01987 Two_Product(adxtail, bdy, ti1, ti0); 01988 Two_Product(adx, bdytail, tj1, tj0); 01989 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 01990 u[3] = u3; 01991 negate = -ady; 01992 Two_Product(bdxtail, negate, ti1, ti0); 01993 negate = -adytail; 01994 Two_Product(bdx, negate, tj1, tj0); 01995 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 01996 v[3] = v3; 01997 abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); 01998 01999 Two_Product(adxtail, bdytail, ti1, ti0); 02000 Two_Product(bdxtail, adytail, tj1, tj0); 02001 Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); 02002 abtt[3] = abtt3; 02003 abttlen = 4; 02004 } else { 02005 abt[0] = 0.0; 02006 abtlen = 1; 02007 abtt[0] = 0.0; 02008 abttlen = 1; 02009 } 02010 02011 if (cdxtail != 0.0) { 02012 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); 02013 cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); 02014 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, 02015 temp32a); 02016 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02017 temp32alen, temp32a, temp48); 02018 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02019 temp48, finother); 02020 finswap = finnow; finnow = finother; finother = finswap; 02021 if (adytail != 0.0) { 02022 temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); 02023 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, 02024 temp16a); 02025 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 02026 temp16a, finother); 02027 finswap = finnow; finnow = finother; finother = finswap; 02028 } 02029 if (bdytail != 0.0) { 02030 temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); 02031 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, 02032 temp16a); 02033 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 02034 temp16a, finother); 02035 finswap = finnow; finnow = finother; finother = finswap; 02036 } 02037 02038 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, 02039 temp32a); 02040 cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); 02041 temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, 02042 temp16a); 02043 temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, 02044 temp16b); 02045 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02046 temp16blen, temp16b, temp32b); 02047 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 02048 temp32blen, temp32b, temp64); 02049 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 02050 temp64, finother); 02051 finswap = finnow; finnow = finother; finother = finswap; 02052 } 02053 if (cdytail != 0.0) { 02054 temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); 02055 cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); 02056 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, 02057 temp32a); 02058 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02059 temp32alen, temp32a, temp48); 02060 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02061 temp48, finother); 02062 finswap = finnow; finnow = finother; finother = finswap; 02063 02064 02065 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, 02066 temp32a); 02067 cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); 02068 temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, 02069 temp16a); 02070 temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, 02071 temp16b); 02072 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02073 temp16blen, temp16b, temp32b); 02074 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 02075 temp32blen, temp32b, temp64); 02076 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 02077 temp64, finother); 02078 finswap = finnow; finnow = finother; finother = finswap; 02079 } 02080 } 02081 02082 return finnow[finlength - 1]; 02083 } 02084 02085 REAL incircle(pa, pb, pc, pd) 02086 REAL *pa; 02087 REAL *pb; 02088 REAL *pc; 02089 REAL *pd; 02090 { 02091 REAL adx, bdx, cdx, ady, bdy, cdy; 02092 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; 02093 REAL alift, blift, clift; 02094 REAL det; 02095 REAL permanent, errbound; 02096 REAL inc; 02097 02098 FPU_ROUND_DOUBLE; 02099 02100 adx = pa[0] - pd[0]; 02101 bdx = pb[0] - pd[0]; 02102 cdx = pc[0] - pd[0]; 02103 ady = pa[1] - pd[1]; 02104 bdy = pb[1] - pd[1]; 02105 cdy = pc[1] - pd[1]; 02106 02107 bdxcdy = bdx * cdy; 02108 cdxbdy = cdx * bdy; 02109 alift = adx * adx + ady * ady; 02110 02111 cdxady = cdx * ady; 02112 adxcdy = adx * cdy; 02113 blift = bdx * bdx + bdy * bdy; 02114 02115 adxbdy = adx * bdy; 02116 bdxady = bdx * ady; 02117 clift = cdx * cdx + cdy * cdy; 02118 02119 det = alift * (bdxcdy - cdxbdy) 02120 + blift * (cdxady - adxcdy) 02121 + clift * (adxbdy - bdxady); 02122 02123 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift 02124 + (Absolute(cdxady) + Absolute(adxcdy)) * blift 02125 + (Absolute(adxbdy) + Absolute(bdxady)) * clift; 02126 errbound = iccerrboundA * permanent; 02127 if ((det > errbound) || (-det > errbound)) { 02128 FPU_RESTORE; 02129 return det; 02130 } 02131 02132 inc = incircleadapt(pa, pb, pc, pd, permanent); 02133 FPU_RESTORE; 02134 return inc; 02135 } 02136 02137 /*****************************************************************************/ 02138 /* */ 02139 /* inspherefast() Approximate 3D insphere test. Nonrobust. */ 02140 /* insphereexact() Exact 3D insphere test. Robust. */ 02141 /* insphereslow() Another exact 3D insphere test. Robust. */ 02142 /* insphere() Adaptive exact 3D insphere test. Robust. */ 02143 /* */ 02144 /* Return a positive value if the point pe lies inside the */ 02145 /* sphere passing through pa, pb, pc, and pd; a negative value */ 02146 /* if it lies outside; and zero if the five points are */ 02147 /* cospherical. The points pa, pb, pc, and pd must be ordered */ 02148 /* so that they have a positive orientation (as defined by */ 02149 /* orient3d()), or the sign of the result will be reversed. */ 02150 /* */ 02151 /* Only the first and last routine should be used; the middle two are for */ 02152 /* timings. */ 02153 /* */ 02154 /* The last three use exact arithmetic to ensure a correct answer. The */ 02155 /* result returned is the determinant of a matrix. In insphere() only, */ 02156 /* this determinant is computed adaptively, in the sense that exact */ 02157 /* arithmetic is used only to the degree it is needed to ensure that the */ 02158 /* returned value has the correct sign. Hence, insphere() is usually quite */ 02159 /* fast, but will run more slowly when the input points are cospherical or */ 02160 /* nearly so. */ 02161 /* */ 02162 /*****************************************************************************/ 02163 02164 static REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) 02165 { 02166 INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; 02167 INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; 02168 INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; 02169 INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; 02170 REAL axby0, bxcy0, cxdy0, dxey0, exay0; 02171 REAL bxay0, cxby0, dxcy0, exdy0, axey0; 02172 REAL axcy0, bxdy0, cxey0, dxay0, exby0; 02173 REAL cxay0, dxby0, excy0, axdy0, bxey0; 02174 REAL ab[4], bc[4], cd[4], de[4], ea[4]; 02175 REAL ac[4], bd[4], ce[4], da[4], eb[4]; 02176 REAL temp8a[8], temp8b[8], temp16[16]; 02177 int temp8alen, temp8blen, temp16len; 02178 REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; 02179 REAL abd[24], bce[24], cda[24], deb[24], eac[24]; 02180 int abclen, bcdlen, cdelen, dealen, eablen; 02181 int abdlen, bcelen, cdalen, deblen, eaclen; 02182 REAL temp48a[48], temp48b[48]; 02183 int temp48alen, temp48blen; 02184 REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; 02185 int abcdlen, bcdelen, cdealen, deablen, eabclen; 02186 REAL temp192[192]; 02187 REAL det384x[384], det384y[384], det384z[384]; 02188 int xlen, ylen, zlen; 02189 REAL detxy[768]; 02190 int xylen; 02191 REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; 02192 int alen, blen, clen, dlen, elen; 02193 REAL abdet[2304], cddet[2304], cdedet[3456]; 02194 int ablen, cdlen; 02195 REAL deter[5760]; 02196 int deterlen; 02197 int i; 02198 02199 INEXACT REAL bvirt; 02200 REAL avirt, bround, around; 02201 INEXACT REAL c; 02202 INEXACT REAL abig; 02203 REAL ahi, alo, bhi, blo; 02204 REAL err1, err2, err3; 02205 INEXACT REAL _i, _j; 02206 REAL _0; 02207 02208 Two_Product(pa[0], pb[1], axby1, axby0); 02209 Two_Product(pb[0], pa[1], bxay1, bxay0); 02210 Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); 02211 02212 Two_Product(pb[0], pc[1], bxcy1, bxcy0); 02213 Two_Product(pc[0], pb[1], cxby1, cxby0); 02214 Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); 02215 02216 Two_Product(pc[0], pd[1], cxdy1, cxdy0); 02217 Two_Product(pd[0], pc[1], dxcy1, dxcy0); 02218 Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); 02219 02220 Two_Product(pd[0], pe[1], dxey1, dxey0); 02221 Two_Product(pe[0], pd[1], exdy1, exdy0); 02222 Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); 02223 02224 Two_Product(pe[0], pa[1], exay1, exay0); 02225 Two_Product(pa[0], pe[1], axey1, axey0); 02226 Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); 02227 02228 Two_Product(pa[0], pc[1], axcy1, axcy0); 02229 Two_Product(pc[0], pa[1], cxay1, cxay0); 02230 Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); 02231 02232 Two_Product(pb[0], pd[1], bxdy1, bxdy0); 02233 Two_Product(pd[0], pb[1], dxby1, dxby0); 02234 Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); 02235 02236 Two_Product(pc[0], pe[1], cxey1, cxey0); 02237 Two_Product(pe[0], pc[1], excy1, excy0); 02238 Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); 02239 02240 Two_Product(pd[0], pa[1], dxay1, dxay0); 02241 Two_Product(pa[0], pd[1], axdy1, axdy0); 02242 Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); 02243 02244 Two_Product(pe[0], pb[1], exby1, exby0); 02245 Two_Product(pb[0], pe[1], bxey1, bxey0); 02246 Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); 02247 02248 temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); 02249 temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); 02250 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02251 temp16); 02252 temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); 02253 abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02254 abc); 02255 02256 temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); 02257 temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); 02258 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02259 temp16); 02260 temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); 02261 bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02262 bcd); 02263 02264 temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); 02265 temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); 02266 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02267 temp16); 02268 temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); 02269 cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02270 cde); 02271 02272 temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); 02273 temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); 02274 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02275 temp16); 02276 temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); 02277 dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02278 dea); 02279 02280 temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); 02281 temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); 02282 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02283 temp16); 02284 temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); 02285 eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02286 eab); 02287 02288 temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); 02289 temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); 02290 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02291 temp16); 02292 temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); 02293 abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02294 abd); 02295 02296 temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); 02297 temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); 02298 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02299 temp16); 02300 temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); 02301 bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02302 bce); 02303 02304 temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); 02305 temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); 02306 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02307 temp16); 02308 temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); 02309 cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02310 cda); 02311 02312 temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); 02313 temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); 02314 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02315 temp16); 02316 temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); 02317 deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02318 deb); 02319 02320 temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); 02321 temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); 02322 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 02323 temp16); 02324 temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); 02325 eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 02326 eac); 02327 02328 temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); 02329 temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); 02330 for (i = 0; i < temp48blen; i++) { 02331 temp48b[i] = -temp48b[i]; 02332 } 02333 bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 02334 temp48blen, temp48b, bcde); 02335 xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); 02336 xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); 02337 ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); 02338 ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); 02339 zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); 02340 zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); 02341 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 02342 alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); 02343 02344 temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); 02345 temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); 02346 for (i = 0; i < temp48blen; i++) { 02347 temp48b[i] = -temp48b[i]; 02348 } 02349 cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 02350 temp48blen, temp48b, cdea); 02351 xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); 02352 xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); 02353 ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); 02354 ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); 02355 zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); 02356 zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); 02357 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 02358 blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); 02359 02360 temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); 02361 temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); 02362 for (i = 0; i < temp48blen; i++) { 02363 temp48b[i] = -temp48b[i]; 02364 } 02365 deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 02366 temp48blen, temp48b, deab); 02367 xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); 02368 xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); 02369 ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); 02370 ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); 02371 zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); 02372 zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); 02373 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 02374 clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); 02375 02376 temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); 02377 temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); 02378 for (i = 0; i < temp48blen; i++) { 02379 temp48b[i] = -temp48b[i]; 02380 } 02381 eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 02382 temp48blen, temp48b, eabc); 02383 xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); 02384 xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); 02385 ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); 02386 ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); 02387 zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); 02388 zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); 02389 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 02390 dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); 02391 02392 temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); 02393 temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); 02394 for (i = 0; i < temp48blen; i++) { 02395 temp48b[i] = -temp48b[i]; 02396 } 02397 abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 02398 temp48blen, temp48b, abcd); 02399 xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); 02400 xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); 02401 ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); 02402 ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); 02403 zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); 02404 zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); 02405 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 02406 elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); 02407 02408 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 02409 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 02410 cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); 02411 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); 02412 02413 return deter[deterlen - 1]; 02414 } 02415 02416 static REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe, 02417 REAL permanent) 02418 { 02419 INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; 02420 REAL det, errbound; 02421 02422 INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; 02423 INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; 02424 INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; 02425 REAL aexbey0, bexaey0, bexcey0, cexbey0; 02426 REAL cexdey0, dexcey0, dexaey0, aexdey0; 02427 REAL aexcey0, cexaey0, bexdey0, dexbey0; 02428 REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; 02429 INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; 02430 REAL abeps, bceps, cdeps, daeps, aceps, bdeps; 02431 REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; 02432 int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len; 02433 REAL xdet[96], ydet[96], zdet[96], xydet[192]; 02434 int xlen, ylen, zlen, xylen; 02435 REAL adet[288], bdet[288], cdet[288], ddet[288]; 02436 int alen, blen, clen, dlen; 02437 REAL abdet[576], cddet[576]; 02438 int ablen, cdlen; 02439 REAL fin1[1152]; 02440 int finlength; 02441 02442 REAL aextail, bextail, cextail, dextail; 02443 REAL aeytail, beytail, ceytail, deytail; 02444 REAL aeztail, beztail, ceztail, deztail; 02445 02446 INEXACT REAL bvirt; 02447 REAL avirt, bround, around; 02448 INEXACT REAL c; 02449 INEXACT REAL abig; 02450 REAL ahi, alo, bhi, blo; 02451 REAL err1, err2, err3; 02452 INEXACT REAL _i, _j; 02453 REAL _0; 02454 02455 aex = (REAL) (pa[0] - pe[0]); 02456 bex = (REAL) (pb[0] - pe[0]); 02457 cex = (REAL) (pc[0] - pe[0]); 02458 dex = (REAL) (pd[0] - pe[0]); 02459 aey = (REAL) (pa[1] - pe[1]); 02460 bey = (REAL) (pb[1] - pe[1]); 02461 cey = (REAL) (pc[1] - pe[1]); 02462 dey = (REAL) (pd[1] - pe[1]); 02463 aez = (REAL) (pa[2] - pe[2]); 02464 bez = (REAL) (pb[2] - pe[2]); 02465 cez = (REAL) (pc[2] - pe[2]); 02466 dez = (REAL) (pd[2] - pe[2]); 02467 02468 Two_Product(aex, bey, aexbey1, aexbey0); 02469 Two_Product(bex, aey, bexaey1, bexaey0); 02470 Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); 02471 ab[3] = ab3; 02472 02473 Two_Product(bex, cey, bexcey1, bexcey0); 02474 Two_Product(cex, bey, cexbey1, cexbey0); 02475 Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); 02476 bc[3] = bc3; 02477 02478 Two_Product(cex, dey, cexdey1, cexdey0); 02479 Two_Product(dex, cey, dexcey1, dexcey0); 02480 Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); 02481 cd[3] = cd3; 02482 02483 Two_Product(dex, aey, dexaey1, dexaey0); 02484 Two_Product(aex, dey, aexdey1, aexdey0); 02485 Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); 02486 da[3] = da3; 02487 02488 Two_Product(aex, cey, aexcey1, aexcey0); 02489 Two_Product(cex, aey, cexaey1, cexaey0); 02490 Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); 02491 ac[3] = ac3; 02492 02493 Two_Product(bex, dey, bexdey1, bexdey0); 02494 Two_Product(dex, bey, dexbey1, dexbey0); 02495 Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); 02496 bd[3] = bd3; 02497 02498 temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); 02499 temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); 02500 temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); 02501 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 02502 temp8blen, temp8b, temp16); 02503 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 02504 temp16len, temp16, temp24); 02505 temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); 02506 xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); 02507 temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); 02508 ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); 02509 temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); 02510 zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); 02511 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 02512 alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); 02513 02514 temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); 02515 temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); 02516 temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); 02517 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 02518 temp8blen, temp8b, temp16); 02519 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 02520 temp16len, temp16, temp24); 02521 temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); 02522 xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); 02523 temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); 02524 ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); 02525 temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); 02526 zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); 02527 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 02528 blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); 02529 02530 temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); 02531 temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); 02532 temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); 02533 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 02534 temp8blen, temp8b, temp16); 02535 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 02536 temp16len, temp16, temp24); 02537 temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); 02538 xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); 02539 temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); 02540 ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); 02541 temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); 02542 zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); 02543 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 02544 clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); 02545 02546 temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); 02547 temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); 02548 temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); 02549 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 02550 temp8blen, temp8b, temp16); 02551 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 02552 temp16len, temp16, temp24); 02553 temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); 02554 xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); 02555 temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); 02556 ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); 02557 temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); 02558 zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); 02559 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 02560 dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); 02561 02562 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 02563 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 02564 finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); 02565 02566 det = estimate(finlength, fin1); 02567 errbound = isperrboundB * permanent; 02568 if ((det >= errbound) || (-det >= errbound)) { 02569 return det; 02570 } 02571 02572 Two_Diff_Tail(pa[0], pe[0], aex, aextail); 02573 Two_Diff_Tail(pa[1], pe[1], aey, aeytail); 02574 Two_Diff_Tail(pa[2], pe[2], aez, aeztail); 02575 Two_Diff_Tail(pb[0], pe[0], bex, bextail); 02576 Two_Diff_Tail(pb[1], pe[1], bey, beytail); 02577 Two_Diff_Tail(pb[2], pe[2], bez, beztail); 02578 Two_Diff_Tail(pc[0], pe[0], cex, cextail); 02579 Two_Diff_Tail(pc[1], pe[1], cey, ceytail); 02580 Two_Diff_Tail(pc[2], pe[2], cez, ceztail); 02581 Two_Diff_Tail(pd[0], pe[0], dex, dextail); 02582 Two_Diff_Tail(pd[1], pe[1], dey, deytail); 02583 Two_Diff_Tail(pd[2], pe[2], dez, deztail); 02584 if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) 02585 && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) 02586 && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) 02587 && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { 02588 return det; 02589 } 02590 02591 errbound = isperrboundC * permanent + resulterrbound * Absolute(det); 02592 abeps = (aex * beytail + bey * aextail) 02593 - (aey * bextail + bex * aeytail); 02594 bceps = (bex * ceytail + cey * bextail) 02595 - (bey * cextail + cex * beytail); 02596 cdeps = (cex * deytail + dey * cextail) 02597 - (cey * dextail + dex * ceytail); 02598 daeps = (dex * aeytail + aey * dextail) 02599 - (dey * aextail + aex * deytail); 02600 aceps = (aex * ceytail + cey * aextail) 02601 - (aey * cextail + cex * aeytail); 02602 bdeps = (bex * deytail + dey * bextail) 02603 - (bey * dextail + dex * beytail); 02604 det += (((bex * bex + bey * bey + bez * bez) 02605 * ((cez * daeps + dez * aceps + aez * cdeps) 02606 + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) 02607 + (dex * dex + dey * dey + dez * dez) 02608 * ((aez * bceps - bez * aceps + cez * abeps) 02609 + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) 02610 - ((aex * aex + aey * aey + aez * aez) 02611 * ((bez * cdeps - cez * bdeps + dez * bceps) 02612 + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) 02613 + (cex * cex + cey * cey + cez * cez) 02614 * ((dez * abeps + aez * bdeps + bez * daeps) 02615 + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) 02616 + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) 02617 * (cez * da3 + dez * ac3 + aez * cd3) 02618 + (dex * dextail + dey * deytail + dez * deztail) 02619 * (aez * bc3 - bez * ac3 + cez * ab3)) 02620 - ((aex * aextail + aey * aeytail + aez * aeztail) 02621 * (bez * cd3 - cez * bd3 + dez * bc3) 02622 + (cex * cextail + cey * ceytail + cez * ceztail) 02623 * (dez * ab3 + aez * bd3 + bez * da3))); 02624 if ((det >= errbound) || (-det >= errbound)) { 02625 return det; 02626 } 02627 02628 return insphereexact(pa, pb, pc, pd, pe); 02629 } 02630 02631 REAL insphere(pa, pb, pc, pd, pe) 02632 REAL *pa; 02633 REAL *pb; 02634 REAL *pc; 02635 REAL *pd; 02636 REAL *pe; 02637 { 02638 REAL aex, bex, cex, dex; 02639 REAL aey, bey, cey, dey; 02640 REAL aez, bez, cez, dez; 02641 REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; 02642 REAL aexcey, cexaey, bexdey, dexbey; 02643 REAL alift, blift, clift, dlift; 02644 REAL ab, bc, cd, da, ac, bd; 02645 REAL abc, bcd, cda, dab; 02646 REAL aezplus, bezplus, cezplus, dezplus; 02647 REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; 02648 REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; 02649 REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; 02650 REAL det; 02651 REAL permanent, errbound; 02652 REAL ins; 02653 02654 FPU_ROUND_DOUBLE; 02655 02656 aex = pa[0] - pe[0]; 02657 bex = pb[0] - pe[0]; 02658 cex = pc[0] - pe[0]; 02659 dex = pd[0] - pe[0]; 02660 aey = pa[1] - pe[1]; 02661 bey = pb[1] - pe[1]; 02662 cey = pc[1] - pe[1]; 02663 dey = pd[1] - pe[1]; 02664 aez = pa[2] - pe[2]; 02665 bez = pb[2] - pe[2]; 02666 cez = pc[2] - pe[2]; 02667 dez = pd[2] - pe[2]; 02668 02669 aexbey = aex * bey; 02670 bexaey = bex * aey; 02671 ab = aexbey - bexaey; 02672 bexcey = bex * cey; 02673 cexbey = cex * bey; 02674 bc = bexcey - cexbey; 02675 cexdey = cex * dey; 02676 dexcey = dex * cey; 02677 cd = cexdey - dexcey; 02678 dexaey = dex * aey; 02679 aexdey = aex * dey; 02680 da = dexaey - aexdey; 02681 02682 aexcey = aex * cey; 02683 cexaey = cex * aey; 02684 ac = aexcey - cexaey; 02685 bexdey = bex * dey; 02686 dexbey = dex * bey; 02687 bd = bexdey - dexbey; 02688 02689 abc = aez * bc - bez * ac + cez * ab; 02690 bcd = bez * cd - cez * bd + dez * bc; 02691 cda = cez * da + dez * ac + aez * cd; 02692 dab = dez * ab + aez * bd + bez * da; 02693 02694 alift = aex * aex + aey * aey + aez * aez; 02695 blift = bex * bex + bey * bey + bez * bez; 02696 clift = cex * cex + cey * cey + cez * cez; 02697 dlift = dex * dex + dey * dey + dez * dez; 02698 02699 det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); 02700 02701 aezplus = Absolute(aez); 02702 bezplus = Absolute(bez); 02703 cezplus = Absolute(cez); 02704 dezplus = Absolute(dez); 02705 aexbeyplus = Absolute(aexbey); 02706 bexaeyplus = Absolute(bexaey); 02707 bexceyplus = Absolute(bexcey); 02708 cexbeyplus = Absolute(cexbey); 02709 cexdeyplus = Absolute(cexdey); 02710 dexceyplus = Absolute(dexcey); 02711 dexaeyplus = Absolute(dexaey); 02712 aexdeyplus = Absolute(aexdey); 02713 aexceyplus = Absolute(aexcey); 02714 cexaeyplus = Absolute(cexaey); 02715 bexdeyplus = Absolute(bexdey); 02716 dexbeyplus = Absolute(dexbey); 02717 permanent = ((cexdeyplus + dexceyplus) * bezplus 02718 + (dexbeyplus + bexdeyplus) * cezplus 02719 + (bexceyplus + cexbeyplus) * dezplus) 02720 * alift 02721 + ((dexaeyplus + aexdeyplus) * cezplus 02722 + (aexceyplus + cexaeyplus) * dezplus 02723 + (cexdeyplus + dexceyplus) * aezplus) 02724 * blift 02725 + ((aexbeyplus + bexaeyplus) * dezplus 02726 + (bexdeyplus + dexbeyplus) * aezplus 02727 + (dexaeyplus + aexdeyplus) * bezplus) 02728 * clift 02729 + ((bexceyplus + cexbeyplus) * aezplus 02730 + (cexaeyplus + aexceyplus) * bezplus 02731 + (aexbeyplus + bexaeyplus) * cezplus) 02732 * dlift; 02733 errbound = isperrboundA * permanent; 02734 if ((det > errbound) || (-det > errbound)) { 02735 FPU_RESTORE; 02736 return det; 02737 } 02738 02739 ins = insphereadapt(pa, pb, pc, pd, pe, permanent); 02740 FPU_RESTORE; 02741 return ins; 02742 }