| 1 | /*****************************************************************************/ |
| 2 | /* */ |
| 3 | /* Routines for Arbitrary Precision Floating-point Arithmetic */ |
| 4 | /* and Fast Robust Geometric Predicates */ |
| 5 | /* (predicates.c) */ |
| 6 | /* */ |
| 7 | /* May 18, 1996 */ |
| 8 | /* */ |
| 9 | /* Placed in the public domain by */ |
| 10 | /* Jonathan Richard Shewchuk */ |
| 11 | /* School of Computer Science */ |
| 12 | /* Carnegie Mellon University */ |
| 13 | /* 5000 Forbes Avenue */ |
| 14 | /* Pittsburgh, Pennsylvania 15213-3891 */ |
| 15 | /* jrs@cs.cmu.edu */ |
| 16 | /* */ |
| 17 | /* This file contains C implementation of algorithms for exact addition */ |
| 18 | /* and multiplication of floating-point numbers, and predicates for */ |
| 19 | /* robustly performing the orientation and incircle tests used in */ |
| 20 | /* computational geometry. The algorithms and underlying theory are */ |
| 21 | /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ |
| 22 | /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ |
| 23 | /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ |
| 24 | /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ |
| 25 | /* Discrete & Computational Geometry.) */ |
| 26 | /* */ |
| 27 | /* This file, the paper listed above, and other information are available */ |
| 28 | /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ |
| 29 | /* */ |
| 30 | /*****************************************************************************/ |
| 31 | |
| 32 | /*****************************************************************************/ |
| 33 | /* */ |
| 34 | /* Using this code: */ |
| 35 | /* */ |
| 36 | /* First, read the short or long version of the paper (from the Web page */ |
| 37 | /* above). */ |
| 38 | /* */ |
| 39 | /* Be sure to call exactinit() once, before calling any of the arithmetic */ |
| 40 | /* functions or geometric predicates. Also be sure to turn on the */ |
| 41 | /* optimizer when compiling this file. */ |
| 42 | /* */ |
| 43 | /* */ |
| 44 | /* Several geometric predicates are defined. Their parameters are all */ |
| 45 | /* points. Each point is an array of two or three floating-point */ |
| 46 | /* numbers. The geometric predicates, described in the papers, are */ |
| 47 | /* */ |
| 48 | /* orient2d(pa, pb, pc) */ |
| 49 | /* orient2dfast(pa, pb, pc) */ |
| 50 | /* orient3d(pa, pb, pc, pd) */ |
| 51 | /* orient3dfast(pa, pb, pc, pd) */ |
| 52 | /* incircle(pa, pb, pc, pd) */ |
| 53 | /* incirclefast(pa, pb, pc, pd) */ |
| 54 | /* insphere(pa, pb, pc, pd, pe) */ |
| 55 | /* inspherefast(pa, pb, pc, pd, pe) */ |
| 56 | /* */ |
| 57 | /* Those with suffix "fast" are approximate, non-robust versions. Those */ |
| 58 | /* without the suffix are adaptive precision, robust versions. There */ |
| 59 | /* are also versions with the suffices "exact" and "slow", which are */ |
| 60 | /* non-adaptive, exact arithmetic versions, which I use only for timings */ |
| 61 | /* in my arithmetic papers. */ |
| 62 | /* */ |
| 63 | /* */ |
| 64 | /* An expansion is represented by an array of floating-point numbers, */ |
| 65 | /* sorted from smallest to largest magnitude (possibly with interspersed */ |
| 66 | /* zeros). The length of each expansion is stored as a separate integer, */ |
| 67 | /* and each arithmetic function returns an integer which is the length */ |
| 68 | /* of the expansion it created. */ |
| 69 | /* */ |
| 70 | /* Several arithmetic functions are defined. Their parameters are */ |
| 71 | /* */ |
| 72 | /* e, f Input expansions */ |
| 73 | /* elen, flen Lengths of input expansions (must be >= 1) */ |
| 74 | /* h Output expansion */ |
| 75 | /* b Input scalar */ |
| 76 | /* */ |
| 77 | /* The arithmetic functions are */ |
| 78 | /* */ |
| 79 | /* grow_expansion(elen, e, b, h) */ |
| 80 | /* grow_expansion_zeroelim(elen, e, b, h) */ |
| 81 | /* expansion_sum(elen, e, flen, f, h) */ |
| 82 | /* expansion_sum_zeroelim1(elen, e, flen, f, h) */ |
| 83 | /* expansion_sum_zeroelim2(elen, e, flen, f, h) */ |
| 84 | /* fast_expansion_sum(elen, e, flen, f, h) */ |
| 85 | /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ |
| 86 | /* linear_expansion_sum(elen, e, flen, f, h) */ |
| 87 | /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ |
| 88 | /* scale_expansion(elen, e, b, h) */ |
| 89 | /* scale_expansion_zeroelim(elen, e, b, h) */ |
| 90 | /* compress(elen, e, h) */ |
| 91 | /* */ |
| 92 | /* All of these are described in the long version of the paper; some are */ |
| 93 | /* described in the short version. All return an integer that is the */ |
| 94 | /* length of h. Those with suffix _zeroelim perform zero elimination, */ |
| 95 | /* and are recommended over their counterparts. The procedure */ |
| 96 | /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ |
| 97 | /* processors that do not use the round-to-even tiebreaking rule) is */ |
| 98 | /* recommended over expansion_sum_zeroelim(). Each procedure has a */ |
| 99 | /* little note next to it (in the code below) that tells you whether or */ |
| 100 | /* not the output expansion may be the same array as one of the input */ |
| 101 | /* expansions. */ |
| 102 | /* */ |
| 103 | /* */ |
| 104 | /* If you look around below, you'll also find macros for a bunch of */ |
| 105 | /* simple unrolled arithmetic operations, and procedures for printing */ |
| 106 | /* expansions (commented out because they don't work with all C */ |
| 107 | /* compilers) and for generating random floating-point numbers whose */ |
| 108 | /* significand bits are all random. Most of the macros have undocumented */ |
| 109 | /* requirements that certain of their parameters should not be the same */ |
| 110 | /* variable; for safety, better to make sure all the parameters are */ |
| 111 | /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ |
| 112 | /* have questions. */ |
| 113 | /* */ |
| 114 | /*****************************************************************************/ |
| 115 | |
| 116 | #include <stdio.h> |
| 117 | #include <stdlib.h> |
| 118 | #include <math.h> |
| 119 | #ifdef CPU86 |
| 120 | #include <float.h> |
| 121 | #endif /* CPU86 */ |
| 122 | #ifdef LINUX |
| 123 | #include <fpu_control.h> |
| 124 | #endif /* LINUX */ |
| 125 | |
| 126 | #include "TetGen/tetgen.h" // Defines the symbol REAL (float or double). |
| 127 | |
| 128 | #ifdef USE_CGAL_PREDICATES |
| 129 | #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> |
| 130 | typedef CGAL::Exact_predicates_inexact_constructions_kernel cgalEpick; |
| 131 | typedef cgalEpick::Point_3 Point; |
| 132 | cgalEpick cgal_pred_obj; |
| 133 | #endif // #ifdef USE_CGAL_PREDICATES |
| 134 | |
| 135 | /* On some machines, the exact arithmetic routines might be defeated by the */ |
| 136 | /* use of internal extended precision floating-point registers. Sometimes */ |
| 137 | /* this problem can be fixed by defining certain values to be volatile, */ |
| 138 | /* thus forcing them to be stored to memory and rounded off. This isn't */ |
| 139 | /* a great solution, though, as it slows the arithmetic down. */ |
| 140 | /* */ |
| 141 | /* To try this out, write "#define INEXACT volatile" below. Normally, */ |
| 142 | /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */ |
| 143 | |
| 144 | #define INEXACT /* Nothing */ |
| 145 | /* #define INEXACT volatile */ |
| 146 | |
| 147 | /* #define REAL double */ /* float or double */ |
| 148 | #define REALPRINT doubleprint |
| 149 | #define REALRAND doublerand |
| 150 | #define NARROWRAND narrowdoublerand |
| 151 | #define UNIFORMRAND uniformdoublerand |
| 152 | |
| 153 | /* Which of the following two methods of finding the absolute values is */ |
| 154 | /* fastest is compiler-dependent. A few compilers can inline and optimize */ |
| 155 | /* the fabs() call; but most will incur the overhead of a function call, */ |
| 156 | /* which is disastrously slow. A faster way on IEEE machines might be to */ |
| 157 | /* mask the appropriate bit, but that's difficult to do in C. */ |
| 158 | |
| 159 | //#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) |
| 160 | #define Absolute(a) fabs(a) |
| 161 | |
| 162 | /* Many of the operations are broken up into two pieces, a main part that */ |
| 163 | /* performs an approximate operation, and a "tail" that computes the */ |
| 164 | /* roundoff error of that operation. */ |
| 165 | /* */ |
| 166 | /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ |
| 167 | /* Split(), and Two_Product() are all implemented as described in the */ |
| 168 | /* reference. Each of these macros requires certain variables to be */ |
| 169 | /* defined in the calling routine. The variables `bvirt', `c', `abig', */ |
| 170 | /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ |
| 171 | /* they store the result of an operation that may incur roundoff error. */ |
| 172 | /* The input parameter `x' (or the highest numbered `x_' parameter) must */ |
| 173 | /* also be declared `INEXACT'. */ |
| 174 | |
| 175 | #define Fast_Two_Sum_Tail(a, b, x, y) \ |
| 176 | bvirt = x - a; \ |
| 177 | y = b - bvirt |
| 178 | |
| 179 | #define Fast_Two_Sum(a, b, x, y) \ |
| 180 | x = (REAL) (a + b); \ |
| 181 | Fast_Two_Sum_Tail(a, b, x, y) |
| 182 | |
| 183 | #define Fast_Two_Diff_Tail(a, b, x, y) \ |
| 184 | bvirt = a - x; \ |
| 185 | y = bvirt - b |
| 186 | |
| 187 | #define Fast_Two_Diff(a, b, x, y) \ |
| 188 | x = (REAL) (a - b); \ |
| 189 | Fast_Two_Diff_Tail(a, b, x, y) |
| 190 | |
| 191 | #define Two_Sum_Tail(a, b, x, y) \ |
| 192 | bvirt = (REAL) (x - a); \ |
| 193 | avirt = x - bvirt; \ |
| 194 | bround = b - bvirt; \ |
| 195 | around = a - avirt; \ |
| 196 | y = around + bround |
| 197 | |
| 198 | #define Two_Sum(a, b, x, y) \ |
| 199 | x = (REAL) (a + b); \ |
| 200 | Two_Sum_Tail(a, b, x, y) |
| 201 | |
| 202 | #define Two_Diff_Tail(a, b, x, y) \ |
| 203 | bvirt = (REAL) (a - x); \ |
| 204 | avirt = x + bvirt; \ |
| 205 | bround = bvirt - b; \ |
| 206 | around = a - avirt; \ |
| 207 | y = around + bround |
| 208 | |
| 209 | #define Two_Diff(a, b, x, y) \ |
| 210 | x = (REAL) (a - b); \ |
| 211 | Two_Diff_Tail(a, b, x, y) |
| 212 | |
| 213 | #define Split(a, ahi, alo) \ |
| 214 | c = (REAL) (splitter * a); \ |
| 215 | abig = (REAL) (c - a); \ |
| 216 | ahi = c - abig; \ |
| 217 | alo = a - ahi |
| 218 | |
| 219 | #define Two_Product_Tail(a, b, x, y) \ |
| 220 | Split(a, ahi, alo); \ |
| 221 | Split(b, bhi, blo); \ |
| 222 | err1 = x - (ahi * bhi); \ |
| 223 | err2 = err1 - (alo * bhi); \ |
| 224 | err3 = err2 - (ahi * blo); \ |
| 225 | y = (alo * blo) - err3 |
| 226 | |
| 227 | #define Two_Product(a, b, x, y) \ |
| 228 | x = (REAL) (a * b); \ |
| 229 | Two_Product_Tail(a, b, x, y) |
| 230 | |
| 231 | /* Two_Product_Presplit() is Two_Product() where one of the inputs has */ |
| 232 | /* already been split. Avoids redundant splitting. */ |
| 233 | |
| 234 | #define Two_Product_Presplit(a, b, bhi, blo, x, y) \ |
| 235 | x = (REAL) (a * b); \ |
| 236 | Split(a, ahi, alo); \ |
| 237 | err1 = x - (ahi * bhi); \ |
| 238 | err2 = err1 - (alo * bhi); \ |
| 239 | err3 = err2 - (ahi * blo); \ |
| 240 | y = (alo * blo) - err3 |
| 241 | |
| 242 | /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ |
| 243 | /* already been split. Avoids redundant splitting. */ |
| 244 | |
| 245 | #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ |
| 246 | x = (REAL) (a * b); \ |
| 247 | err1 = x - (ahi * bhi); \ |
| 248 | err2 = err1 - (alo * bhi); \ |
| 249 | err3 = err2 - (ahi * blo); \ |
| 250 | y = (alo * blo) - err3 |
| 251 | |
| 252 | /* Square() can be done more quickly than Two_Product(). */ |
| 253 | |
| 254 | #define Square_Tail(a, x, y) \ |
| 255 | Split(a, ahi, alo); \ |
| 256 | err1 = x - (ahi * ahi); \ |
| 257 | err3 = err1 - ((ahi + ahi) * alo); \ |
| 258 | y = (alo * alo) - err3 |
| 259 | |
| 260 | #define Square(a, x, y) \ |
| 261 | x = (REAL) (a * a); \ |
| 262 | Square_Tail(a, x, y) |
| 263 | |
| 264 | /* Macros for summing expansions of various fixed lengths. These are all */ |
| 265 | /* unrolled versions of Expansion_Sum(). */ |
| 266 | |
| 267 | #define Two_One_Sum(a1, a0, b, x2, x1, x0) \ |
| 268 | Two_Sum(a0, b , _i, x0); \ |
| 269 | Two_Sum(a1, _i, x2, x1) |
| 270 | |
| 271 | #define Two_One_Diff(a1, a0, b, x2, x1, x0) \ |
| 272 | Two_Diff(a0, b , _i, x0); \ |
| 273 | Two_Sum( a1, _i, x2, x1) |
| 274 | |
| 275 | #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ |
| 276 | Two_One_Sum(a1, a0, b0, _j, _0, x0); \ |
| 277 | Two_One_Sum(_j, _0, b1, x3, x2, x1) |
| 278 | |
| 279 | #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ |
| 280 | Two_One_Diff(a1, a0, b0, _j, _0, x0); \ |
| 281 | Two_One_Diff(_j, _0, b1, x3, x2, x1) |
| 282 | |
| 283 | #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ |
| 284 | Two_One_Sum(a1, a0, b , _j, x1, x0); \ |
| 285 | Two_One_Sum(a3, a2, _j, x4, x3, x2) |
| 286 | |
| 287 | #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ |
| 288 | Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ |
| 289 | Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) |
| 290 | |
| 291 | #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ |
| 292 | x1, x0) \ |
| 293 | Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ |
| 294 | Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) |
| 295 | |
| 296 | #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ |
| 297 | x3, x2, x1, x0) \ |
| 298 | Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ |
| 299 | Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) |
| 300 | |
| 301 | #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ |
| 302 | x6, x5, x4, x3, x2, x1, x0) \ |
| 303 | Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ |
| 304 | _1, _0, x0); \ |
| 305 | Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ |
| 306 | x3, x2, x1) |
| 307 | |
| 308 | #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ |
| 309 | x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ |
| 310 | Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ |
| 311 | _2, _1, _0, x1, x0); \ |
| 312 | Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ |
| 313 | x7, x6, x5, x4, x3, x2) |
| 314 | |
| 315 | /* Macros for multiplying expansions of various fixed lengths. */ |
| 316 | |
| 317 | #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ |
| 318 | Split(b, bhi, blo); \ |
| 319 | Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ |
| 320 | Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ |
| 321 | Two_Sum(_i, _0, _k, x1); \ |
| 322 | Fast_Two_Sum(_j, _k, x3, x2) |
| 323 | |
| 324 | #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ |
| 325 | Split(b, bhi, blo); \ |
| 326 | Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ |
| 327 | Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ |
| 328 | Two_Sum(_i, _0, _k, x1); \ |
| 329 | Fast_Two_Sum(_j, _k, _i, x2); \ |
| 330 | Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ |
| 331 | Two_Sum(_i, _0, _k, x3); \ |
| 332 | Fast_Two_Sum(_j, _k, _i, x4); \ |
| 333 | Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ |
| 334 | Two_Sum(_i, _0, _k, x5); \ |
| 335 | Fast_Two_Sum(_j, _k, x7, x6) |
| 336 | |
| 337 | #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ |
| 338 | Split(a0, a0hi, a0lo); \ |
| 339 | Split(b0, bhi, blo); \ |
| 340 | Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ |
| 341 | Split(a1, a1hi, a1lo); \ |
| 342 | Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ |
| 343 | Two_Sum(_i, _0, _k, _1); \ |
| 344 | Fast_Two_Sum(_j, _k, _l, _2); \ |
| 345 | Split(b1, bhi, blo); \ |
| 346 | Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ |
| 347 | Two_Sum(_1, _0, _k, x1); \ |
| 348 | Two_Sum(_2, _k, _j, _1); \ |
| 349 | Two_Sum(_l, _j, _m, _2); \ |
| 350 | Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ |
| 351 | Two_Sum(_i, _0, _n, _0); \ |
| 352 | Two_Sum(_1, _0, _i, x2); \ |
| 353 | Two_Sum(_2, _i, _k, _1); \ |
| 354 | Two_Sum(_m, _k, _l, _2); \ |
| 355 | Two_Sum(_j, _n, _k, _0); \ |
| 356 | Two_Sum(_1, _0, _j, x3); \ |
| 357 | Two_Sum(_2, _j, _i, _1); \ |
| 358 | Two_Sum(_l, _i, _m, _2); \ |
| 359 | Two_Sum(_1, _k, _i, x4); \ |
| 360 | Two_Sum(_2, _i, _k, x5); \ |
| 361 | Two_Sum(_m, _k, x7, x6) |
| 362 | |
| 363 | /* An expansion of length two can be squared more quickly than finding the */ |
| 364 | /* product of two different expansions of length two, and the result is */ |
| 365 | /* guaranteed to have no more than six (rather than eight) components. */ |
| 366 | |
| 367 | #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ |
| 368 | Square(a0, _j, x0); \ |
| 369 | _0 = a0 + a0; \ |
| 370 | Two_Product(a1, _0, _k, _1); \ |
| 371 | Two_One_Sum(_k, _1, _j, _l, _2, x1); \ |
| 372 | Square(a1, _j, _1); \ |
| 373 | Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) |
| 374 | |
| 375 | /* splitter = 2^ceiling(p / 2) + 1. Used to split floats in half. */ |
| 376 | static REAL splitter; |
| 377 | static REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ |
| 378 | /* A set of coefficients used to calculate maximum roundoff errors. */ |
| 379 | static REAL resulterrbound; |
| 380 | static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; |
| 381 | static REAL o3derrboundA, o3derrboundB, o3derrboundC; |
| 382 | static REAL iccerrboundA, iccerrboundB, iccerrboundC; |
| 383 | static REAL isperrboundA, isperrboundB, isperrboundC; |
| 384 | |
| 385 | // Options to choose types of geometric computtaions. |
| 386 | // Added by H. Si, 2012-08-23. |
| 387 | static int _use_inexact_arith; // -X option. |
| 388 | static int _use_static_filter; // Default option, disable it by -X1 |
| 389 | |
| 390 | // Static filters for orient3d() and insphere(). |
| 391 | // They are pre-calcualted and set in exactinit(). |
| 392 | // Added by H. Si, 2012-08-23. |
| 393 | static REAL o3dstaticfilter; |
| 394 | static REAL ispstaticfilter; |
| 395 | |
| 396 | |
| 397 | |
| 398 | // The following codes were part of "IEEE 754 floating-point test software" |
| 399 | // http://www.math.utah.edu/~beebe/software/ieee/ |
| 400 | // The original program was "fpinfo2.c". |
| 401 | |
| 402 | double fppow2(int n) |
| 403 | { |
| 404 | double x, power; |
| 405 | x = (n < 0) ? ((double)1.0/(double)2.0) : (double)2.0; |
| 406 | n = (n < 0) ? -n : n; |
| 407 | power = (double)1.0; |
| 408 | while (n-- > 0) |
| 409 | power *= x; |
| 410 | return (power); |
| 411 | } |
| 412 | |
| 413 | #ifdef SINGLE |
| 414 | |
| 415 | float fstore(float x) |
| 416 | { |
| 417 | return (x); |
| 418 | } |
| 419 | |
| 420 | int test_float(int verbose) |
| 421 | { |
| 422 | float x; |
| 423 | int pass = 1; |
| 424 | |
| 425 | //(void)printf("float:\n"); |
| 426 | |
| 427 | if (verbose) { |
| 428 | (void)printf(" sizeof(float) = %2u\n" , (unsigned int)sizeof(float)); |
| 429 | #ifdef CPU86 // <float.h> |
| 430 | (void)printf(" FLT_MANT_DIG = %2d\n" , FLT_MANT_DIG); |
| 431 | #endif |
| 432 | } |
| 433 | |
| 434 | x = (float)1.0; |
| 435 | while (fstore((float)1.0 + x/(float)2.0) != (float)1.0) |
| 436 | x /= (float)2.0; |
| 437 | if (verbose) |
| 438 | (void)printf(" machine epsilon = %13.5e " , x); |
| 439 | |
| 440 | if (x == (float)fppow2(-23)) { |
| 441 | if (verbose) |
| 442 | (void)printf("[IEEE 754 32-bit macheps]\n" ); |
| 443 | } else { |
| 444 | (void)printf("[not IEEE 754 conformant] !!\n" ); |
| 445 | pass = 0; |
| 446 | } |
| 447 | |
| 448 | x = (float)1.0; |
| 449 | while (fstore(x / (float)2.0) != (float)0.0) |
| 450 | x /= (float)2.0; |
| 451 | if (verbose) |
| 452 | (void)printf(" smallest positive number = %13.5e " , x); |
| 453 | |
| 454 | if (x == (float)fppow2(-149)) { |
| 455 | if (verbose) |
| 456 | (void)printf("[smallest 32-bit subnormal]\n" ); |
| 457 | } else if (x == (float)fppow2(-126)) { |
| 458 | if (verbose) |
| 459 | (void)printf("[smallest 32-bit normal]\n" ); |
| 460 | } else { |
| 461 | (void)printf("[not IEEE 754 conformant] !!\n" ); |
| 462 | pass = 0; |
| 463 | } |
| 464 | |
| 465 | return pass; |
| 466 | } |
| 467 | |
| 468 | # else |
| 469 | |
| 470 | double dstore(double x) |
| 471 | { |
| 472 | return (x); |
| 473 | } |
| 474 | |
| 475 | int test_double(int verbose) |
| 476 | { |
| 477 | double x; |
| 478 | int pass = 1; |
| 479 | |
| 480 | // (void)printf("double:\n"); |
| 481 | if (verbose) { |
| 482 | (void)printf(" sizeof(double) = %2u\n" , (unsigned int)sizeof(double)); |
| 483 | #ifdef CPU86 // <float.h> |
| 484 | (void)printf(" DBL_MANT_DIG = %2d\n" , DBL_MANT_DIG); |
| 485 | #endif |
| 486 | } |
| 487 | |
| 488 | x = 1.0; |
| 489 | while (dstore(1.0 + x/2.0) != 1.0) |
| 490 | x /= 2.0; |
| 491 | if (verbose) |
| 492 | (void)printf(" machine epsilon = %13.5le " , x); |
| 493 | |
| 494 | if (x == (double)fppow2(-52)) { |
| 495 | if (verbose) |
| 496 | (void)printf("[IEEE 754 64-bit macheps]\n" ); |
| 497 | } else { |
| 498 | (void)printf("[not IEEE 754 conformant] !!\n" ); |
| 499 | pass = 0; |
| 500 | } |
| 501 | |
| 502 | x = 1.0; |
| 503 | while (dstore(x / 2.0) != 0.0) |
| 504 | x /= 2.0; |
| 505 | //if (verbose) |
| 506 | // (void)printf(" smallest positive number = %13.5le ", x); |
| 507 | |
| 508 | if (x == (double)fppow2(-1074)) { |
| 509 | //if (verbose) |
| 510 | // (void)printf("[smallest 64-bit subnormal]\n"); |
| 511 | } else if (x == (double)fppow2(-1022)) { |
| 512 | //if (verbose) |
| 513 | // (void)printf("[smallest 64-bit normal]\n"); |
| 514 | } else { |
| 515 | (void)printf("[not IEEE 754 conformant] !!\n" ); |
| 516 | pass = 0; |
| 517 | } |
| 518 | |
| 519 | return pass; |
| 520 | } |
| 521 | |
| 522 | #endif |
| 523 | |
| 524 | /*****************************************************************************/ |
| 525 | /* */ |
| 526 | /* exactinit() Initialize the variables used for exact arithmetic. */ |
| 527 | /* */ |
| 528 | /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ |
| 529 | /* floating-point arithmetic. `epsilon' bounds the relative roundoff */ |
| 530 | /* error. It is used for floating-point error analysis. */ |
| 531 | /* */ |
| 532 | /* `splitter' is used to split floating-point numbers into two half- */ |
| 533 | /* length significands for exact multiplication. */ |
| 534 | /* */ |
| 535 | /* I imagine that a highly optimizing compiler might be too smart for its */ |
| 536 | /* own good, and somehow cause this routine to fail, if it pretends that */ |
| 537 | /* floating-point arithmetic is too much like real arithmetic. */ |
| 538 | /* */ |
| 539 | /* Don't change this routine unless you fully understand it. */ |
| 540 | /* */ |
| 541 | /*****************************************************************************/ |
| 542 | |
| 543 | void exactinit(int verbose, int noexact, int nofilter, REAL maxx, REAL maxy, |
| 544 | REAL maxz) |
| 545 | { |
| 546 | REAL half; |
| 547 | REAL check, lastcheck; |
| 548 | int every_other; |
| 549 | #ifdef LINUX |
| 550 | int cword; |
| 551 | #endif /* LINUX */ |
| 552 | |
| 553 | #ifdef CPU86 |
| 554 | #ifdef SINGLE |
| 555 | _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ |
| 556 | #else /* not SINGLE */ |
| 557 | _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ |
| 558 | #endif /* not SINGLE */ |
| 559 | #endif /* CPU86 */ |
| 560 | #ifdef LINUX |
| 561 | #ifdef SINGLE |
| 562 | /* cword = 4223; */ |
| 563 | cword = 4210; /* set FPU control word for single precision */ |
| 564 | #else /* not SINGLE */ |
| 565 | /* cword = 4735; */ |
| 566 | cword = 4722; /* set FPU control word for double precision */ |
| 567 | #endif /* not SINGLE */ |
| 568 | _FPU_SETCW(cword); |
| 569 | #endif /* LINUX */ |
| 570 | |
| 571 | if (verbose) { |
| 572 | printf(" Initializing robust predicates.\n" ); |
| 573 | } |
| 574 | |
| 575 | #ifdef USE_CGAL_PREDICATES |
| 576 | if (cgal_pred_obj.Has_static_filters) { |
| 577 | printf(" Use static filter.\n" ); |
| 578 | } else { |
| 579 | printf(" No static filter.\n" ); |
| 580 | } |
| 581 | #endif // USE_CGAL_PREDICATES |
| 582 | |
| 583 | #ifdef SINGLE |
| 584 | test_float(verbose); |
| 585 | #else |
| 586 | test_double(verbose); |
| 587 | #endif |
| 588 | |
| 589 | every_other = 1; |
| 590 | half = 0.5; |
| 591 | epsilon = 1.0; |
| 592 | splitter = 1.0; |
| 593 | check = 1.0; |
| 594 | /* Repeatedly divide `epsilon' by two until it is too small to add to */ |
| 595 | /* one without causing roundoff. (Also check if the sum is equal to */ |
| 596 | /* the previous sum, for machines that round up instead of using exact */ |
| 597 | /* rounding. Not that this library will work on such machines anyway. */ |
| 598 | do { |
| 599 | lastcheck = check; |
| 600 | epsilon *= half; |
| 601 | if (every_other) { |
| 602 | splitter *= 2.0; |
| 603 | } |
| 604 | every_other = !every_other; |
| 605 | check = 1.0 + epsilon; |
| 606 | } while ((check != 1.0) && (check != lastcheck)); |
| 607 | splitter += 1.0; |
| 608 | |
| 609 | /* Error bounds for orientation and incircle tests. */ |
| 610 | resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; |
| 611 | ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; |
| 612 | ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; |
| 613 | ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; |
| 614 | o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; |
| 615 | o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; |
| 616 | o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; |
| 617 | iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; |
| 618 | iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; |
| 619 | iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; |
| 620 | isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; |
| 621 | isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; |
| 622 | isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; |
| 623 | |
| 624 | // Set TetGen options. Added by H. Si, 2012-08-23. |
| 625 | _use_inexact_arith = noexact; |
| 626 | _use_static_filter = !nofilter; |
| 627 | |
| 628 | // Calculate the two static filters for orient3d() and insphere() tests. |
| 629 | // Added by H. Si, 2012-08-23. |
| 630 | |
| 631 | // Sort maxx < maxy < maxz. Re-use 'half' for swapping. |
| 632 | assert(maxx > 0); |
| 633 | assert(maxy > 0); |
| 634 | assert(maxz > 0); |
| 635 | |
| 636 | if (maxx > maxz) { |
| 637 | half = maxx; maxx = maxz; maxz = half; |
| 638 | } |
| 639 | if (maxy > maxz) { |
| 640 | half = maxy; maxy = maxz; maxz = half; |
| 641 | } |
| 642 | else if (maxy < maxx) { |
| 643 | half = maxy; maxy = maxx; maxx = half; |
| 644 | } |
| 645 | |
| 646 | o3dstaticfilter = 5.1107127829973299e-15 * maxx * maxy * maxz; |
| 647 | ispstaticfilter = 1.2466136531027298e-13 * maxx * maxy * maxz * (maxz * maxz); |
| 648 | |
| 649 | } |
| 650 | |
| 651 | /*****************************************************************************/ |
| 652 | /* */ |
| 653 | /* grow_expansion() Add a scalar to an expansion. */ |
| 654 | /* */ |
| 655 | /* Sets h = e + b. See the long version of my paper for details. */ |
| 656 | /* */ |
| 657 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 658 | /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ |
| 659 | /* properties as well. (That is, if e has one of these properties, so */ |
| 660 | /* will h.) */ |
| 661 | /* */ |
| 662 | /*****************************************************************************/ |
| 663 | |
| 664 | int grow_expansion(int elen, REAL *e, REAL b, REAL *h) |
| 665 | /* e and h can be the same. */ |
| 666 | { |
| 667 | REAL Q; |
| 668 | INEXACT REAL Qnew; |
| 669 | int eindex; |
| 670 | REAL enow; |
| 671 | INEXACT REAL bvirt; |
| 672 | REAL avirt, bround, around; |
| 673 | |
| 674 | Q = b; |
| 675 | for (eindex = 0; eindex < elen; eindex++) { |
| 676 | enow = e[eindex]; |
| 677 | Two_Sum(Q, enow, Qnew, h[eindex]); |
| 678 | Q = Qnew; |
| 679 | } |
| 680 | h[eindex] = Q; |
| 681 | return eindex + 1; |
| 682 | } |
| 683 | |
| 684 | /*****************************************************************************/ |
| 685 | /* */ |
| 686 | /* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ |
| 687 | /* zero components from the output expansion. */ |
| 688 | /* */ |
| 689 | /* Sets h = e + b. See the long version of my paper for details. */ |
| 690 | /* */ |
| 691 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 692 | /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ |
| 693 | /* properties as well. (That is, if e has one of these properties, so */ |
| 694 | /* will h.) */ |
| 695 | /* */ |
| 696 | /*****************************************************************************/ |
| 697 | |
| 698 | int grow_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) |
| 699 | /* e and h can be the same. */ |
| 700 | { |
| 701 | REAL Q, hh; |
| 702 | INEXACT REAL Qnew; |
| 703 | int eindex, hindex; |
| 704 | REAL enow; |
| 705 | INEXACT REAL bvirt; |
| 706 | REAL avirt, bround, around; |
| 707 | |
| 708 | hindex = 0; |
| 709 | Q = b; |
| 710 | for (eindex = 0; eindex < elen; eindex++) { |
| 711 | enow = e[eindex]; |
| 712 | Two_Sum(Q, enow, Qnew, hh); |
| 713 | Q = Qnew; |
| 714 | if (hh != 0.0) { |
| 715 | h[hindex++] = hh; |
| 716 | } |
| 717 | } |
| 718 | if ((Q != 0.0) || (hindex == 0)) { |
| 719 | h[hindex++] = Q; |
| 720 | } |
| 721 | return hindex; |
| 722 | } |
| 723 | |
| 724 | /*****************************************************************************/ |
| 725 | /* */ |
| 726 | /* expansion_sum() Sum two expansions. */ |
| 727 | /* */ |
| 728 | /* Sets h = e + f. See the long version of my paper for details. */ |
| 729 | /* */ |
| 730 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 731 | /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ |
| 732 | /* if e has one of these properties, so will h.) Does NOT maintain the */ |
| 733 | /* strongly nonoverlapping property. */ |
| 734 | /* */ |
| 735 | /*****************************************************************************/ |
| 736 | |
| 737 | int expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 738 | /* e and h can be the same, but f and h cannot. */ |
| 739 | { |
| 740 | REAL Q; |
| 741 | INEXACT REAL Qnew; |
| 742 | int findex, hindex, hlast; |
| 743 | REAL hnow; |
| 744 | INEXACT REAL bvirt; |
| 745 | REAL avirt, bround, around; |
| 746 | |
| 747 | Q = f[0]; |
| 748 | for (hindex = 0; hindex < elen; hindex++) { |
| 749 | hnow = e[hindex]; |
| 750 | Two_Sum(Q, hnow, Qnew, h[hindex]); |
| 751 | Q = Qnew; |
| 752 | } |
| 753 | h[hindex] = Q; |
| 754 | hlast = hindex; |
| 755 | for (findex = 1; findex < flen; findex++) { |
| 756 | Q = f[findex]; |
| 757 | for (hindex = findex; hindex <= hlast; hindex++) { |
| 758 | hnow = h[hindex]; |
| 759 | Two_Sum(Q, hnow, Qnew, h[hindex]); |
| 760 | Q = Qnew; |
| 761 | } |
| 762 | h[++hlast] = Q; |
| 763 | } |
| 764 | return hlast + 1; |
| 765 | } |
| 766 | |
| 767 | /*****************************************************************************/ |
| 768 | /* */ |
| 769 | /* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ |
| 770 | /* components from the output expansion. */ |
| 771 | /* */ |
| 772 | /* Sets h = e + f. See the long version of my paper for details. */ |
| 773 | /* */ |
| 774 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 775 | /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ |
| 776 | /* if e has one of these properties, so will h.) Does NOT maintain the */ |
| 777 | /* strongly nonoverlapping property. */ |
| 778 | /* */ |
| 779 | /*****************************************************************************/ |
| 780 | |
| 781 | int expansion_sum_zeroelim1(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 782 | /* e and h can be the same, but f and h cannot. */ |
| 783 | { |
| 784 | REAL Q; |
| 785 | INEXACT REAL Qnew; |
| 786 | int index, findex, hindex, hlast; |
| 787 | REAL hnow; |
| 788 | INEXACT REAL bvirt; |
| 789 | REAL avirt, bround, around; |
| 790 | |
| 791 | Q = f[0]; |
| 792 | for (hindex = 0; hindex < elen; hindex++) { |
| 793 | hnow = e[hindex]; |
| 794 | Two_Sum(Q, hnow, Qnew, h[hindex]); |
| 795 | Q = Qnew; |
| 796 | } |
| 797 | h[hindex] = Q; |
| 798 | hlast = hindex; |
| 799 | for (findex = 1; findex < flen; findex++) { |
| 800 | Q = f[findex]; |
| 801 | for (hindex = findex; hindex <= hlast; hindex++) { |
| 802 | hnow = h[hindex]; |
| 803 | Two_Sum(Q, hnow, Qnew, h[hindex]); |
| 804 | Q = Qnew; |
| 805 | } |
| 806 | h[++hlast] = Q; |
| 807 | } |
| 808 | hindex = -1; |
| 809 | for (index = 0; index <= hlast; index++) { |
| 810 | hnow = h[index]; |
| 811 | if (hnow != 0.0) { |
| 812 | h[++hindex] = hnow; |
| 813 | } |
| 814 | } |
| 815 | if (hindex == -1) { |
| 816 | return 1; |
| 817 | } else { |
| 818 | return hindex + 1; |
| 819 | } |
| 820 | } |
| 821 | |
| 822 | /*****************************************************************************/ |
| 823 | /* */ |
| 824 | /* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ |
| 825 | /* components from the output expansion. */ |
| 826 | /* */ |
| 827 | /* Sets h = e + f. See the long version of my paper for details. */ |
| 828 | /* */ |
| 829 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 830 | /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ |
| 831 | /* if e has one of these properties, so will h.) Does NOT maintain the */ |
| 832 | /* strongly nonoverlapping property. */ |
| 833 | /* */ |
| 834 | /*****************************************************************************/ |
| 835 | |
| 836 | int expansion_sum_zeroelim2(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 837 | /* e and h can be the same, but f and h cannot. */ |
| 838 | { |
| 839 | REAL Q, hh; |
| 840 | INEXACT REAL Qnew; |
| 841 | int eindex, findex, hindex, hlast; |
| 842 | REAL enow; |
| 843 | INEXACT REAL bvirt; |
| 844 | REAL avirt, bround, around; |
| 845 | |
| 846 | hindex = 0; |
| 847 | Q = f[0]; |
| 848 | for (eindex = 0; eindex < elen; eindex++) { |
| 849 | enow = e[eindex]; |
| 850 | Two_Sum(Q, enow, Qnew, hh); |
| 851 | Q = Qnew; |
| 852 | if (hh != 0.0) { |
| 853 | h[hindex++] = hh; |
| 854 | } |
| 855 | } |
| 856 | h[hindex] = Q; |
| 857 | hlast = hindex; |
| 858 | for (findex = 1; findex < flen; findex++) { |
| 859 | hindex = 0; |
| 860 | Q = f[findex]; |
| 861 | for (eindex = 0; eindex <= hlast; eindex++) { |
| 862 | enow = h[eindex]; |
| 863 | Two_Sum(Q, enow, Qnew, hh); |
| 864 | Q = Qnew; |
| 865 | if (hh != 0) { |
| 866 | h[hindex++] = hh; |
| 867 | } |
| 868 | } |
| 869 | h[hindex] = Q; |
| 870 | hlast = hindex; |
| 871 | } |
| 872 | return hlast + 1; |
| 873 | } |
| 874 | |
| 875 | /*****************************************************************************/ |
| 876 | /* */ |
| 877 | /* fast_expansion_sum() Sum two expansions. */ |
| 878 | /* */ |
| 879 | /* Sets h = e + f. See the long version of my paper for details. */ |
| 880 | /* */ |
| 881 | /* If round-to-even is used (as with IEEE 754), maintains the strongly */ |
| 882 | /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ |
| 883 | /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ |
| 884 | /* properties. */ |
| 885 | /* */ |
| 886 | /*****************************************************************************/ |
| 887 | |
| 888 | int fast_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 889 | /* h cannot be e or f. */ |
| 890 | { |
| 891 | REAL Q; |
| 892 | INEXACT REAL Qnew; |
| 893 | INEXACT REAL bvirt; |
| 894 | REAL avirt, bround, around; |
| 895 | int eindex, findex, hindex; |
| 896 | REAL enow, fnow; |
| 897 | |
| 898 | enow = e[0]; |
| 899 | fnow = f[0]; |
| 900 | eindex = findex = 0; |
| 901 | if ((fnow > enow) == (fnow > -enow)) { |
| 902 | Q = enow; |
| 903 | enow = e[++eindex]; |
| 904 | } else { |
| 905 | Q = fnow; |
| 906 | fnow = f[++findex]; |
| 907 | } |
| 908 | hindex = 0; |
| 909 | if ((eindex < elen) && (findex < flen)) { |
| 910 | if ((fnow > enow) == (fnow > -enow)) { |
| 911 | Fast_Two_Sum(enow, Q, Qnew, h[0]); |
| 912 | enow = e[++eindex]; |
| 913 | } else { |
| 914 | Fast_Two_Sum(fnow, Q, Qnew, h[0]); |
| 915 | fnow = f[++findex]; |
| 916 | } |
| 917 | Q = Qnew; |
| 918 | hindex = 1; |
| 919 | while ((eindex < elen) && (findex < flen)) { |
| 920 | if ((fnow > enow) == (fnow > -enow)) { |
| 921 | Two_Sum(Q, enow, Qnew, h[hindex]); |
| 922 | enow = e[++eindex]; |
| 923 | } else { |
| 924 | Two_Sum(Q, fnow, Qnew, h[hindex]); |
| 925 | fnow = f[++findex]; |
| 926 | } |
| 927 | Q = Qnew; |
| 928 | hindex++; |
| 929 | } |
| 930 | } |
| 931 | while (eindex < elen) { |
| 932 | Two_Sum(Q, enow, Qnew, h[hindex]); |
| 933 | enow = e[++eindex]; |
| 934 | Q = Qnew; |
| 935 | hindex++; |
| 936 | } |
| 937 | while (findex < flen) { |
| 938 | Two_Sum(Q, fnow, Qnew, h[hindex]); |
| 939 | fnow = f[++findex]; |
| 940 | Q = Qnew; |
| 941 | hindex++; |
| 942 | } |
| 943 | h[hindex] = Q; |
| 944 | return hindex + 1; |
| 945 | } |
| 946 | |
| 947 | /*****************************************************************************/ |
| 948 | /* */ |
| 949 | /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ |
| 950 | /* components from the output expansion. */ |
| 951 | /* */ |
| 952 | /* Sets h = e + f. See the long version of my paper for details. */ |
| 953 | /* */ |
| 954 | /* If round-to-even is used (as with IEEE 754), maintains the strongly */ |
| 955 | /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ |
| 956 | /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ |
| 957 | /* properties. */ |
| 958 | /* */ |
| 959 | /*****************************************************************************/ |
| 960 | |
| 961 | int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 962 | /* h cannot be e or f. */ |
| 963 | { |
| 964 | REAL Q; |
| 965 | INEXACT REAL Qnew; |
| 966 | INEXACT REAL hh; |
| 967 | INEXACT REAL bvirt; |
| 968 | REAL avirt, bround, around; |
| 969 | int eindex, findex, hindex; |
| 970 | REAL enow, fnow; |
| 971 | |
| 972 | enow = e[0]; |
| 973 | fnow = f[0]; |
| 974 | eindex = findex = 0; |
| 975 | if ((fnow > enow) == (fnow > -enow)) { |
| 976 | Q = enow; |
| 977 | enow = e[++eindex]; |
| 978 | } else { |
| 979 | Q = fnow; |
| 980 | fnow = f[++findex]; |
| 981 | } |
| 982 | hindex = 0; |
| 983 | if ((eindex < elen) && (findex < flen)) { |
| 984 | if ((fnow > enow) == (fnow > -enow)) { |
| 985 | Fast_Two_Sum(enow, Q, Qnew, hh); |
| 986 | enow = e[++eindex]; |
| 987 | } else { |
| 988 | Fast_Two_Sum(fnow, Q, Qnew, hh); |
| 989 | fnow = f[++findex]; |
| 990 | } |
| 991 | Q = Qnew; |
| 992 | if (hh != 0.0) { |
| 993 | h[hindex++] = hh; |
| 994 | } |
| 995 | while ((eindex < elen) && (findex < flen)) { |
| 996 | if ((fnow > enow) == (fnow > -enow)) { |
| 997 | Two_Sum(Q, enow, Qnew, hh); |
| 998 | enow = e[++eindex]; |
| 999 | } else { |
| 1000 | Two_Sum(Q, fnow, Qnew, hh); |
| 1001 | fnow = f[++findex]; |
| 1002 | } |
| 1003 | Q = Qnew; |
| 1004 | if (hh != 0.0) { |
| 1005 | h[hindex++] = hh; |
| 1006 | } |
| 1007 | } |
| 1008 | } |
| 1009 | while (eindex < elen) { |
| 1010 | Two_Sum(Q, enow, Qnew, hh); |
| 1011 | enow = e[++eindex]; |
| 1012 | Q = Qnew; |
| 1013 | if (hh != 0.0) { |
| 1014 | h[hindex++] = hh; |
| 1015 | } |
| 1016 | } |
| 1017 | while (findex < flen) { |
| 1018 | Two_Sum(Q, fnow, Qnew, hh); |
| 1019 | fnow = f[++findex]; |
| 1020 | Q = Qnew; |
| 1021 | if (hh != 0.0) { |
| 1022 | h[hindex++] = hh; |
| 1023 | } |
| 1024 | } |
| 1025 | if ((Q != 0.0) || (hindex == 0)) { |
| 1026 | h[hindex++] = Q; |
| 1027 | } |
| 1028 | return hindex; |
| 1029 | } |
| 1030 | |
| 1031 | /*****************************************************************************/ |
| 1032 | /* */ |
| 1033 | /* linear_expansion_sum() Sum two expansions. */ |
| 1034 | /* */ |
| 1035 | /* Sets h = e + f. See either version of my paper for details. */ |
| 1036 | /* */ |
| 1037 | /* Maintains the nonoverlapping property. (That is, if e is */ |
| 1038 | /* nonoverlapping, h will be also.) */ |
| 1039 | /* */ |
| 1040 | /*****************************************************************************/ |
| 1041 | |
| 1042 | int linear_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) |
| 1043 | /* h cannot be e or f. */ |
| 1044 | { |
| 1045 | REAL Q, q; |
| 1046 | INEXACT REAL Qnew; |
| 1047 | INEXACT REAL R; |
| 1048 | INEXACT REAL bvirt; |
| 1049 | REAL avirt, bround, around; |
| 1050 | int eindex, findex, hindex; |
| 1051 | REAL enow, fnow; |
| 1052 | REAL g0; |
| 1053 | |
| 1054 | enow = e[0]; |
| 1055 | fnow = f[0]; |
| 1056 | eindex = findex = 0; |
| 1057 | if ((fnow > enow) == (fnow > -enow)) { |
| 1058 | g0 = enow; |
| 1059 | enow = e[++eindex]; |
| 1060 | } else { |
| 1061 | g0 = fnow; |
| 1062 | fnow = f[++findex]; |
| 1063 | } |
| 1064 | if ((eindex < elen) && ((findex >= flen) |
| 1065 | || ((fnow > enow) == (fnow > -enow)))) { |
| 1066 | Fast_Two_Sum(enow, g0, Qnew, q); |
| 1067 | enow = e[++eindex]; |
| 1068 | } else { |
| 1069 | Fast_Two_Sum(fnow, g0, Qnew, q); |
| 1070 | fnow = f[++findex]; |
| 1071 | } |
| 1072 | Q = Qnew; |
| 1073 | for (hindex = 0; hindex < elen + flen - 2; hindex++) { |
| 1074 | if ((eindex < elen) && ((findex >= flen) |
| 1075 | || ((fnow > enow) == (fnow > -enow)))) { |
| 1076 | Fast_Two_Sum(enow, q, R, h[hindex]); |
| 1077 | enow = e[++eindex]; |
| 1078 | } else { |
| 1079 | Fast_Two_Sum(fnow, q, R, h[hindex]); |
| 1080 | fnow = f[++findex]; |
| 1081 | } |
| 1082 | Two_Sum(Q, R, Qnew, q); |
| 1083 | Q = Qnew; |
| 1084 | } |
| 1085 | h[hindex] = q; |
| 1086 | h[hindex + 1] = Q; |
| 1087 | return hindex + 2; |
| 1088 | } |
| 1089 | |
| 1090 | /*****************************************************************************/ |
| 1091 | /* */ |
| 1092 | /* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ |
| 1093 | /* components from the output expansion. */ |
| 1094 | /* */ |
| 1095 | /* Sets h = e + f. See either version of my paper for details. */ |
| 1096 | /* */ |
| 1097 | /* Maintains the nonoverlapping property. (That is, if e is */ |
| 1098 | /* nonoverlapping, h will be also.) */ |
| 1099 | /* */ |
| 1100 | /*****************************************************************************/ |
| 1101 | |
| 1102 | int linear_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, |
| 1103 | REAL *h) |
| 1104 | /* h cannot be e or f. */ |
| 1105 | { |
| 1106 | REAL Q, q, hh; |
| 1107 | INEXACT REAL Qnew; |
| 1108 | INEXACT REAL R; |
| 1109 | INEXACT REAL bvirt; |
| 1110 | REAL avirt, bround, around; |
| 1111 | int eindex, findex, hindex; |
| 1112 | int count; |
| 1113 | REAL enow, fnow; |
| 1114 | REAL g0; |
| 1115 | |
| 1116 | enow = e[0]; |
| 1117 | fnow = f[0]; |
| 1118 | eindex = findex = 0; |
| 1119 | hindex = 0; |
| 1120 | if ((fnow > enow) == (fnow > -enow)) { |
| 1121 | g0 = enow; |
| 1122 | enow = e[++eindex]; |
| 1123 | } else { |
| 1124 | g0 = fnow; |
| 1125 | fnow = f[++findex]; |
| 1126 | } |
| 1127 | if ((eindex < elen) && ((findex >= flen) |
| 1128 | || ((fnow > enow) == (fnow > -enow)))) { |
| 1129 | Fast_Two_Sum(enow, g0, Qnew, q); |
| 1130 | enow = e[++eindex]; |
| 1131 | } else { |
| 1132 | Fast_Two_Sum(fnow, g0, Qnew, q); |
| 1133 | fnow = f[++findex]; |
| 1134 | } |
| 1135 | Q = Qnew; |
| 1136 | for (count = 2; count < elen + flen; count++) { |
| 1137 | if ((eindex < elen) && ((findex >= flen) |
| 1138 | || ((fnow > enow) == (fnow > -enow)))) { |
| 1139 | Fast_Two_Sum(enow, q, R, hh); |
| 1140 | enow = e[++eindex]; |
| 1141 | } else { |
| 1142 | Fast_Two_Sum(fnow, q, R, hh); |
| 1143 | fnow = f[++findex]; |
| 1144 | } |
| 1145 | Two_Sum(Q, R, Qnew, q); |
| 1146 | Q = Qnew; |
| 1147 | if (hh != 0) { |
| 1148 | h[hindex++] = hh; |
| 1149 | } |
| 1150 | } |
| 1151 | if (q != 0) { |
| 1152 | h[hindex++] = q; |
| 1153 | } |
| 1154 | if ((Q != 0.0) || (hindex == 0)) { |
| 1155 | h[hindex++] = Q; |
| 1156 | } |
| 1157 | return hindex; |
| 1158 | } |
| 1159 | |
| 1160 | /*****************************************************************************/ |
| 1161 | /* */ |
| 1162 | /* scale_expansion() Multiply an expansion by a scalar. */ |
| 1163 | /* */ |
| 1164 | /* Sets h = be. See either version of my paper for details. */ |
| 1165 | /* */ |
| 1166 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 1167 | /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ |
| 1168 | /* properties as well. (That is, if e has one of these properties, so */ |
| 1169 | /* will h.) */ |
| 1170 | /* */ |
| 1171 | /*****************************************************************************/ |
| 1172 | |
| 1173 | int scale_expansion(int elen, REAL *e, REAL b, REAL *h) |
| 1174 | /* e and h cannot be the same. */ |
| 1175 | { |
| 1176 | INEXACT REAL Q; |
| 1177 | INEXACT REAL sum; |
| 1178 | INEXACT REAL product1; |
| 1179 | REAL product0; |
| 1180 | int eindex, hindex; |
| 1181 | REAL enow; |
| 1182 | INEXACT REAL bvirt; |
| 1183 | REAL avirt, bround, around; |
| 1184 | INEXACT REAL c; |
| 1185 | INEXACT REAL abig; |
| 1186 | REAL ahi, alo, bhi, blo; |
| 1187 | REAL err1, err2, err3; |
| 1188 | |
| 1189 | Split(b, bhi, blo); |
| 1190 | Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); |
| 1191 | hindex = 1; |
| 1192 | for (eindex = 1; eindex < elen; eindex++) { |
| 1193 | enow = e[eindex]; |
| 1194 | Two_Product_Presplit(enow, b, bhi, blo, product1, product0); |
| 1195 | Two_Sum(Q, product0, sum, h[hindex]); |
| 1196 | hindex++; |
| 1197 | Two_Sum(product1, sum, Q, h[hindex]); |
| 1198 | hindex++; |
| 1199 | } |
| 1200 | h[hindex] = Q; |
| 1201 | return elen + elen; |
| 1202 | } |
| 1203 | |
| 1204 | /*****************************************************************************/ |
| 1205 | /* */ |
| 1206 | /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ |
| 1207 | /* eliminating zero components from the */ |
| 1208 | /* output expansion. */ |
| 1209 | /* */ |
| 1210 | /* Sets h = be. See either version of my paper for details. */ |
| 1211 | /* */ |
| 1212 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 1213 | /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ |
| 1214 | /* properties as well. (That is, if e has one of these properties, so */ |
| 1215 | /* will h.) */ |
| 1216 | /* */ |
| 1217 | /*****************************************************************************/ |
| 1218 | |
| 1219 | int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) |
| 1220 | /* e and h cannot be the same. */ |
| 1221 | { |
| 1222 | INEXACT REAL Q, sum; |
| 1223 | REAL hh; |
| 1224 | INEXACT REAL product1; |
| 1225 | REAL product0; |
| 1226 | int eindex, hindex; |
| 1227 | REAL enow; |
| 1228 | INEXACT REAL bvirt; |
| 1229 | REAL avirt, bround, around; |
| 1230 | INEXACT REAL c; |
| 1231 | INEXACT REAL abig; |
| 1232 | REAL ahi, alo, bhi, blo; |
| 1233 | REAL err1, err2, err3; |
| 1234 | |
| 1235 | Split(b, bhi, blo); |
| 1236 | Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); |
| 1237 | hindex = 0; |
| 1238 | if (hh != 0) { |
| 1239 | h[hindex++] = hh; |
| 1240 | } |
| 1241 | for (eindex = 1; eindex < elen; eindex++) { |
| 1242 | enow = e[eindex]; |
| 1243 | Two_Product_Presplit(enow, b, bhi, blo, product1, product0); |
| 1244 | Two_Sum(Q, product0, sum, hh); |
| 1245 | if (hh != 0) { |
| 1246 | h[hindex++] = hh; |
| 1247 | } |
| 1248 | Fast_Two_Sum(product1, sum, Q, hh); |
| 1249 | if (hh != 0) { |
| 1250 | h[hindex++] = hh; |
| 1251 | } |
| 1252 | } |
| 1253 | if ((Q != 0.0) || (hindex == 0)) { |
| 1254 | h[hindex++] = Q; |
| 1255 | } |
| 1256 | return hindex; |
| 1257 | } |
| 1258 | |
| 1259 | /*****************************************************************************/ |
| 1260 | /* */ |
| 1261 | /* compress() Compress an expansion. */ |
| 1262 | /* */ |
| 1263 | /* See the long version of my paper for details. */ |
| 1264 | /* */ |
| 1265 | /* Maintains the nonoverlapping property. If round-to-even is used (as */ |
| 1266 | /* with IEEE 754), then any nonoverlapping expansion is converted to a */ |
| 1267 | /* nonadjacent expansion. */ |
| 1268 | /* */ |
| 1269 | /*****************************************************************************/ |
| 1270 | |
| 1271 | int compress(int elen, REAL *e, REAL *h) |
| 1272 | /* e and h may be the same. */ |
| 1273 | { |
| 1274 | REAL Q, q; |
| 1275 | INEXACT REAL Qnew; |
| 1276 | int eindex, hindex; |
| 1277 | INEXACT REAL bvirt; |
| 1278 | REAL enow, hnow; |
| 1279 | int top, bottom; |
| 1280 | |
| 1281 | bottom = elen - 1; |
| 1282 | Q = e[bottom]; |
| 1283 | for (eindex = elen - 2; eindex >= 0; eindex--) { |
| 1284 | enow = e[eindex]; |
| 1285 | Fast_Two_Sum(Q, enow, Qnew, q); |
| 1286 | if (q != 0) { |
| 1287 | h[bottom--] = Qnew; |
| 1288 | Q = q; |
| 1289 | } else { |
| 1290 | Q = Qnew; |
| 1291 | } |
| 1292 | } |
| 1293 | top = 0; |
| 1294 | for (hindex = bottom + 1; hindex < elen; hindex++) { |
| 1295 | hnow = h[hindex]; |
| 1296 | Fast_Two_Sum(hnow, Q, Qnew, q); |
| 1297 | if (q != 0) { |
| 1298 | h[top++] = q; |
| 1299 | } |
| 1300 | Q = Qnew; |
| 1301 | } |
| 1302 | h[top] = Q; |
| 1303 | return top + 1; |
| 1304 | } |
| 1305 | |
| 1306 | /*****************************************************************************/ |
| 1307 | /* */ |
| 1308 | /* estimate() Produce a one-word estimate of an expansion's value. */ |
| 1309 | /* */ |
| 1310 | /* See either version of my paper for details. */ |
| 1311 | /* */ |
| 1312 | /*****************************************************************************/ |
| 1313 | |
| 1314 | REAL estimate(int elen, REAL *e) |
| 1315 | { |
| 1316 | REAL Q; |
| 1317 | int eindex; |
| 1318 | |
| 1319 | Q = e[0]; |
| 1320 | for (eindex = 1; eindex < elen; eindex++) { |
| 1321 | Q += e[eindex]; |
| 1322 | } |
| 1323 | return Q; |
| 1324 | } |
| 1325 | |
| 1326 | /*****************************************************************************/ |
| 1327 | /* */ |
| 1328 | /* orient2dfast() Approximate 2D orientation test. Nonrobust. */ |
| 1329 | /* orient2dexact() Exact 2D orientation test. Robust. */ |
| 1330 | /* orient2dslow() Another exact 2D orientation test. Robust. */ |
| 1331 | /* orient2d() Adaptive exact 2D orientation test. Robust. */ |
| 1332 | /* */ |
| 1333 | /* Return a positive value if the points pa, pb, and pc occur */ |
| 1334 | /* in counterclockwise order; a negative value if they occur */ |
| 1335 | /* in clockwise order; and zero if they are collinear. The */ |
| 1336 | /* result is also a rough approximation of twice the signed */ |
| 1337 | /* area of the triangle defined by the three points. */ |
| 1338 | /* */ |
| 1339 | /* Only the first and last routine should be used; the middle two are for */ |
| 1340 | /* timings. */ |
| 1341 | /* */ |
| 1342 | /* The last three use exact arithmetic to ensure a correct answer. The */ |
| 1343 | /* result returned is the determinant of a matrix. In orient2d() only, */ |
| 1344 | /* this determinant is computed adaptively, in the sense that exact */ |
| 1345 | /* arithmetic is used only to the degree it is needed to ensure that the */ |
| 1346 | /* returned value has the correct sign. Hence, orient2d() is usually quite */ |
| 1347 | /* fast, but will run more slowly when the input points are collinear or */ |
| 1348 | /* nearly so. */ |
| 1349 | /* */ |
| 1350 | /*****************************************************************************/ |
| 1351 | |
| 1352 | REAL orient2dfast(REAL *pa, REAL *pb, REAL *pc) |
| 1353 | { |
| 1354 | REAL acx, bcx, acy, bcy; |
| 1355 | |
| 1356 | acx = pa[0] - pc[0]; |
| 1357 | bcx = pb[0] - pc[0]; |
| 1358 | acy = pa[1] - pc[1]; |
| 1359 | bcy = pb[1] - pc[1]; |
| 1360 | return acx * bcy - acy * bcx; |
| 1361 | } |
| 1362 | |
| 1363 | REAL orient2dexact(REAL *pa, REAL *pb, REAL *pc) |
| 1364 | { |
| 1365 | INEXACT REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; |
| 1366 | REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; |
| 1367 | REAL aterms[4], bterms[4], cterms[4]; |
| 1368 | INEXACT REAL aterms3, bterms3, cterms3; |
| 1369 | REAL v[8], w[12]; |
| 1370 | int vlength, wlength; |
| 1371 | |
| 1372 | INEXACT REAL bvirt; |
| 1373 | REAL avirt, bround, around; |
| 1374 | INEXACT REAL c; |
| 1375 | INEXACT REAL abig; |
| 1376 | REAL ahi, alo, bhi, blo; |
| 1377 | REAL err1, err2, err3; |
| 1378 | INEXACT REAL _i, _j; |
| 1379 | REAL _0; |
| 1380 | |
| 1381 | Two_Product(pa[0], pb[1], axby1, axby0); |
| 1382 | Two_Product(pa[0], pc[1], axcy1, axcy0); |
| 1383 | Two_Two_Diff(axby1, axby0, axcy1, axcy0, |
| 1384 | aterms3, aterms[2], aterms[1], aterms[0]); |
| 1385 | aterms[3] = aterms3; |
| 1386 | |
| 1387 | Two_Product(pb[0], pc[1], bxcy1, bxcy0); |
| 1388 | Two_Product(pb[0], pa[1], bxay1, bxay0); |
| 1389 | Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, |
| 1390 | bterms3, bterms[2], bterms[1], bterms[0]); |
| 1391 | bterms[3] = bterms3; |
| 1392 | |
| 1393 | Two_Product(pc[0], pa[1], cxay1, cxay0); |
| 1394 | Two_Product(pc[0], pb[1], cxby1, cxby0); |
| 1395 | Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, |
| 1396 | cterms3, cterms[2], cterms[1], cterms[0]); |
| 1397 | cterms[3] = cterms3; |
| 1398 | |
| 1399 | vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); |
| 1400 | wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); |
| 1401 | |
| 1402 | return w[wlength - 1]; |
| 1403 | } |
| 1404 | |
| 1405 | REAL orient2dslow(REAL *pa, REAL *pb, REAL *pc) |
| 1406 | { |
| 1407 | INEXACT REAL acx, acy, bcx, bcy; |
| 1408 | REAL acxtail, acytail; |
| 1409 | REAL bcxtail, bcytail; |
| 1410 | REAL negate, negatetail; |
| 1411 | REAL axby[8], bxay[8]; |
| 1412 | INEXACT REAL axby7, bxay7; |
| 1413 | REAL deter[16]; |
| 1414 | int deterlen; |
| 1415 | |
| 1416 | INEXACT REAL bvirt; |
| 1417 | REAL avirt, bround, around; |
| 1418 | INEXACT REAL c; |
| 1419 | INEXACT REAL abig; |
| 1420 | REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; |
| 1421 | REAL err1, err2, err3; |
| 1422 | INEXACT REAL _i, _j, _k, _l, _m, _n; |
| 1423 | REAL _0, _1, _2; |
| 1424 | |
| 1425 | Two_Diff(pa[0], pc[0], acx, acxtail); |
| 1426 | Two_Diff(pa[1], pc[1], acy, acytail); |
| 1427 | Two_Diff(pb[0], pc[0], bcx, bcxtail); |
| 1428 | Two_Diff(pb[1], pc[1], bcy, bcytail); |
| 1429 | |
| 1430 | Two_Two_Product(acx, acxtail, bcy, bcytail, |
| 1431 | axby7, axby[6], axby[5], axby[4], |
| 1432 | axby[3], axby[2], axby[1], axby[0]); |
| 1433 | axby[7] = axby7; |
| 1434 | negate = -acy; |
| 1435 | negatetail = -acytail; |
| 1436 | Two_Two_Product(bcx, bcxtail, negate, negatetail, |
| 1437 | bxay7, bxay[6], bxay[5], bxay[4], |
| 1438 | bxay[3], bxay[2], bxay[1], bxay[0]); |
| 1439 | bxay[7] = bxay7; |
| 1440 | |
| 1441 | deterlen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, deter); |
| 1442 | |
| 1443 | return deter[deterlen - 1]; |
| 1444 | } |
| 1445 | |
| 1446 | REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum) |
| 1447 | { |
| 1448 | INEXACT REAL acx, acy, bcx, bcy; |
| 1449 | REAL acxtail, acytail, bcxtail, bcytail; |
| 1450 | INEXACT REAL detleft, detright; |
| 1451 | REAL detlefttail, detrighttail; |
| 1452 | REAL det, errbound; |
| 1453 | REAL B[4], C1[8], C2[12], D[16]; |
| 1454 | INEXACT REAL B3; |
| 1455 | int C1length, C2length, Dlength; |
| 1456 | REAL u[4]; |
| 1457 | INEXACT REAL u3; |
| 1458 | INEXACT REAL s1, t1; |
| 1459 | REAL s0, t0; |
| 1460 | |
| 1461 | INEXACT REAL bvirt; |
| 1462 | REAL avirt, bround, around; |
| 1463 | INEXACT REAL c; |
| 1464 | INEXACT REAL abig; |
| 1465 | REAL ahi, alo, bhi, blo; |
| 1466 | REAL err1, err2, err3; |
| 1467 | INEXACT REAL _i, _j; |
| 1468 | REAL _0; |
| 1469 | |
| 1470 | acx = (REAL) (pa[0] - pc[0]); |
| 1471 | bcx = (REAL) (pb[0] - pc[0]); |
| 1472 | acy = (REAL) (pa[1] - pc[1]); |
| 1473 | bcy = (REAL) (pb[1] - pc[1]); |
| 1474 | |
| 1475 | Two_Product(acx, bcy, detleft, detlefttail); |
| 1476 | Two_Product(acy, bcx, detright, detrighttail); |
| 1477 | |
| 1478 | Two_Two_Diff(detleft, detlefttail, detright, detrighttail, |
| 1479 | B3, B[2], B[1], B[0]); |
| 1480 | B[3] = B3; |
| 1481 | |
| 1482 | det = estimate(4, B); |
| 1483 | errbound = ccwerrboundB * detsum; |
| 1484 | if ((det >= errbound) || (-det >= errbound)) { |
| 1485 | return det; |
| 1486 | } |
| 1487 | |
| 1488 | Two_Diff_Tail(pa[0], pc[0], acx, acxtail); |
| 1489 | Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); |
| 1490 | Two_Diff_Tail(pa[1], pc[1], acy, acytail); |
| 1491 | Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); |
| 1492 | |
| 1493 | if ((acxtail == 0.0) && (acytail == 0.0) |
| 1494 | && (bcxtail == 0.0) && (bcytail == 0.0)) { |
| 1495 | return det; |
| 1496 | } |
| 1497 | |
| 1498 | errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); |
| 1499 | det += (acx * bcytail + bcy * acxtail) |
| 1500 | - (acy * bcxtail + bcx * acytail); |
| 1501 | if ((det >= errbound) || (-det >= errbound)) { |
| 1502 | return det; |
| 1503 | } |
| 1504 | |
| 1505 | Two_Product(acxtail, bcy, s1, s0); |
| 1506 | Two_Product(acytail, bcx, t1, t0); |
| 1507 | Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); |
| 1508 | u[3] = u3; |
| 1509 | C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); |
| 1510 | |
| 1511 | Two_Product(acx, bcytail, s1, s0); |
| 1512 | Two_Product(acy, bcxtail, t1, t0); |
| 1513 | Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); |
| 1514 | u[3] = u3; |
| 1515 | C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); |
| 1516 | |
| 1517 | Two_Product(acxtail, bcytail, s1, s0); |
| 1518 | Two_Product(acytail, bcxtail, t1, t0); |
| 1519 | Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); |
| 1520 | u[3] = u3; |
| 1521 | Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); |
| 1522 | |
| 1523 | return(D[Dlength - 1]); |
| 1524 | } |
| 1525 | |
| 1526 | REAL orient2d(REAL *pa, REAL *pb, REAL *pc) |
| 1527 | { |
| 1528 | REAL detleft, detright, det; |
| 1529 | REAL detsum, errbound; |
| 1530 | |
| 1531 | detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); |
| 1532 | detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); |
| 1533 | det = detleft - detright; |
| 1534 | |
| 1535 | if (detleft > 0.0) { |
| 1536 | if (detright <= 0.0) { |
| 1537 | return det; |
| 1538 | } else { |
| 1539 | detsum = detleft + detright; |
| 1540 | } |
| 1541 | } else if (detleft < 0.0) { |
| 1542 | if (detright >= 0.0) { |
| 1543 | return det; |
| 1544 | } else { |
| 1545 | detsum = -detleft - detright; |
| 1546 | } |
| 1547 | } else { |
| 1548 | return det; |
| 1549 | } |
| 1550 | |
| 1551 | errbound = ccwerrboundA * detsum; |
| 1552 | if ((det >= errbound) || (-det >= errbound)) { |
| 1553 | return det; |
| 1554 | } |
| 1555 | |
| 1556 | return orient2dadapt(pa, pb, pc, detsum); |
| 1557 | } |
| 1558 | |
| 1559 | /*****************************************************************************/ |
| 1560 | /* */ |
| 1561 | /* orient3dfast() Approximate 3D orientation test. Nonrobust. */ |
| 1562 | /* orient3dexact() Exact 3D orientation test. Robust. */ |
| 1563 | /* orient3dslow() Another exact 3D orientation test. Robust. */ |
| 1564 | /* orient3d() Adaptive exact 3D orientation test. Robust. */ |
| 1565 | /* */ |
| 1566 | /* Return a positive value if the point pd lies below the */ |
| 1567 | /* plane passing through pa, pb, and pc; "below" is defined so */ |
| 1568 | /* that pa, pb, and pc appear in counterclockwise order when */ |
| 1569 | /* viewed from above the plane. Returns a negative value if */ |
| 1570 | /* pd lies above the plane. Returns zero if the points are */ |
| 1571 | /* coplanar. The result is also a rough approximation of six */ |
| 1572 | /* times the signed volume of the tetrahedron defined by the */ |
| 1573 | /* four points. */ |
| 1574 | /* */ |
| 1575 | /* Only the first and last routine should be used; the middle two are for */ |
| 1576 | /* timings. */ |
| 1577 | /* */ |
| 1578 | /* The last three use exact arithmetic to ensure a correct answer. The */ |
| 1579 | /* result returned is the determinant of a matrix. In orient3d() only, */ |
| 1580 | /* this determinant is computed adaptively, in the sense that exact */ |
| 1581 | /* arithmetic is used only to the degree it is needed to ensure that the */ |
| 1582 | /* returned value has the correct sign. Hence, orient3d() is usually quite */ |
| 1583 | /* fast, but will run more slowly when the input points are coplanar or */ |
| 1584 | /* nearly so. */ |
| 1585 | /* */ |
| 1586 | /*****************************************************************************/ |
| 1587 | |
| 1588 | REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 1589 | { |
| 1590 | REAL adx, bdx, cdx; |
| 1591 | REAL ady, bdy, cdy; |
| 1592 | REAL adz, bdz, cdz; |
| 1593 | |
| 1594 | adx = pa[0] - pd[0]; |
| 1595 | bdx = pb[0] - pd[0]; |
| 1596 | cdx = pc[0] - pd[0]; |
| 1597 | ady = pa[1] - pd[1]; |
| 1598 | bdy = pb[1] - pd[1]; |
| 1599 | cdy = pc[1] - pd[1]; |
| 1600 | adz = pa[2] - pd[2]; |
| 1601 | bdz = pb[2] - pd[2]; |
| 1602 | cdz = pc[2] - pd[2]; |
| 1603 | |
| 1604 | return adx * (bdy * cdz - bdz * cdy) |
| 1605 | + bdx * (cdy * adz - cdz * ady) |
| 1606 | + cdx * (ady * bdz - adz * bdy); |
| 1607 | } |
| 1608 | |
| 1609 | REAL orient3dexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 1610 | { |
| 1611 | INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; |
| 1612 | INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; |
| 1613 | REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; |
| 1614 | REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; |
| 1615 | REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; |
| 1616 | REAL temp8[8]; |
| 1617 | int templen; |
| 1618 | REAL abc[12], bcd[12], cda[12], dab[12]; |
| 1619 | int abclen, bcdlen, cdalen, dablen; |
| 1620 | REAL adet[24], bdet[24], cdet[24], ddet[24]; |
| 1621 | int alen, blen, clen, dlen; |
| 1622 | REAL abdet[48], cddet[48]; |
| 1623 | int ablen, cdlen; |
| 1624 | REAL deter[96]; |
| 1625 | int deterlen; |
| 1626 | int i; |
| 1627 | |
| 1628 | INEXACT REAL bvirt; |
| 1629 | REAL avirt, bround, around; |
| 1630 | INEXACT REAL c; |
| 1631 | INEXACT REAL abig; |
| 1632 | REAL ahi, alo, bhi, blo; |
| 1633 | REAL err1, err2, err3; |
| 1634 | INEXACT REAL _i, _j; |
| 1635 | REAL _0; |
| 1636 | |
| 1637 | Two_Product(pa[0], pb[1], axby1, axby0); |
| 1638 | Two_Product(pb[0], pa[1], bxay1, bxay0); |
| 1639 | Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); |
| 1640 | |
| 1641 | Two_Product(pb[0], pc[1], bxcy1, bxcy0); |
| 1642 | Two_Product(pc[0], pb[1], cxby1, cxby0); |
| 1643 | Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); |
| 1644 | |
| 1645 | Two_Product(pc[0], pd[1], cxdy1, cxdy0); |
| 1646 | Two_Product(pd[0], pc[1], dxcy1, dxcy0); |
| 1647 | Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); |
| 1648 | |
| 1649 | Two_Product(pd[0], pa[1], dxay1, dxay0); |
| 1650 | Two_Product(pa[0], pd[1], axdy1, axdy0); |
| 1651 | Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); |
| 1652 | |
| 1653 | Two_Product(pa[0], pc[1], axcy1, axcy0); |
| 1654 | Two_Product(pc[0], pa[1], cxay1, cxay0); |
| 1655 | Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); |
| 1656 | |
| 1657 | Two_Product(pb[0], pd[1], bxdy1, bxdy0); |
| 1658 | Two_Product(pd[0], pb[1], dxby1, dxby0); |
| 1659 | Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); |
| 1660 | |
| 1661 | templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); |
| 1662 | cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); |
| 1663 | templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); |
| 1664 | dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); |
| 1665 | for (i = 0; i < 4; i++) { |
| 1666 | bd[i] = -bd[i]; |
| 1667 | ac[i] = -ac[i]; |
| 1668 | } |
| 1669 | templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); |
| 1670 | abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); |
| 1671 | templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); |
| 1672 | bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); |
| 1673 | |
| 1674 | alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); |
| 1675 | blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); |
| 1676 | clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); |
| 1677 | dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); |
| 1678 | |
| 1679 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 1680 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 1681 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); |
| 1682 | |
| 1683 | return deter[deterlen - 1]; |
| 1684 | } |
| 1685 | |
| 1686 | REAL orient3dslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 1687 | { |
| 1688 | INEXACT REAL adx, ady, adz, bdx, bdy, bdz, cdx, cdy, cdz; |
| 1689 | REAL adxtail, adytail, adztail; |
| 1690 | REAL bdxtail, bdytail, bdztail; |
| 1691 | REAL cdxtail, cdytail, cdztail; |
| 1692 | REAL negate, negatetail; |
| 1693 | INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; |
| 1694 | REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; |
| 1695 | REAL temp16[16], temp32[32], temp32t[32]; |
| 1696 | int temp16len, temp32len, temp32tlen; |
| 1697 | REAL adet[64], bdet[64], cdet[64]; |
| 1698 | int alen, blen, clen; |
| 1699 | REAL abdet[128]; |
| 1700 | int ablen; |
| 1701 | REAL deter[192]; |
| 1702 | int deterlen; |
| 1703 | |
| 1704 | INEXACT REAL bvirt; |
| 1705 | REAL avirt, bround, around; |
| 1706 | INEXACT REAL c; |
| 1707 | INEXACT REAL abig; |
| 1708 | REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; |
| 1709 | REAL err1, err2, err3; |
| 1710 | INEXACT REAL _i, _j, _k, _l, _m, _n; |
| 1711 | REAL _0, _1, _2; |
| 1712 | |
| 1713 | Two_Diff(pa[0], pd[0], adx, adxtail); |
| 1714 | Two_Diff(pa[1], pd[1], ady, adytail); |
| 1715 | Two_Diff(pa[2], pd[2], adz, adztail); |
| 1716 | Two_Diff(pb[0], pd[0], bdx, bdxtail); |
| 1717 | Two_Diff(pb[1], pd[1], bdy, bdytail); |
| 1718 | Two_Diff(pb[2], pd[2], bdz, bdztail); |
| 1719 | Two_Diff(pc[0], pd[0], cdx, cdxtail); |
| 1720 | Two_Diff(pc[1], pd[1], cdy, cdytail); |
| 1721 | Two_Diff(pc[2], pd[2], cdz, cdztail); |
| 1722 | |
| 1723 | Two_Two_Product(adx, adxtail, bdy, bdytail, |
| 1724 | axby7, axby[6], axby[5], axby[4], |
| 1725 | axby[3], axby[2], axby[1], axby[0]); |
| 1726 | axby[7] = axby7; |
| 1727 | negate = -ady; |
| 1728 | negatetail = -adytail; |
| 1729 | Two_Two_Product(bdx, bdxtail, negate, negatetail, |
| 1730 | bxay7, bxay[6], bxay[5], bxay[4], |
| 1731 | bxay[3], bxay[2], bxay[1], bxay[0]); |
| 1732 | bxay[7] = bxay7; |
| 1733 | Two_Two_Product(bdx, bdxtail, cdy, cdytail, |
| 1734 | bxcy7, bxcy[6], bxcy[5], bxcy[4], |
| 1735 | bxcy[3], bxcy[2], bxcy[1], bxcy[0]); |
| 1736 | bxcy[7] = bxcy7; |
| 1737 | negate = -bdy; |
| 1738 | negatetail = -bdytail; |
| 1739 | Two_Two_Product(cdx, cdxtail, negate, negatetail, |
| 1740 | cxby7, cxby[6], cxby[5], cxby[4], |
| 1741 | cxby[3], cxby[2], cxby[1], cxby[0]); |
| 1742 | cxby[7] = cxby7; |
| 1743 | Two_Two_Product(cdx, cdxtail, ady, adytail, |
| 1744 | cxay7, cxay[6], cxay[5], cxay[4], |
| 1745 | cxay[3], cxay[2], cxay[1], cxay[0]); |
| 1746 | cxay[7] = cxay7; |
| 1747 | negate = -cdy; |
| 1748 | negatetail = -cdytail; |
| 1749 | Two_Two_Product(adx, adxtail, negate, negatetail, |
| 1750 | axcy7, axcy[6], axcy[5], axcy[4], |
| 1751 | axcy[3], axcy[2], axcy[1], axcy[0]); |
| 1752 | axcy[7] = axcy7; |
| 1753 | |
| 1754 | temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); |
| 1755 | temp32len = scale_expansion_zeroelim(temp16len, temp16, adz, temp32); |
| 1756 | temp32tlen = scale_expansion_zeroelim(temp16len, temp16, adztail, temp32t); |
| 1757 | alen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, |
| 1758 | adet); |
| 1759 | |
| 1760 | temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); |
| 1761 | temp32len = scale_expansion_zeroelim(temp16len, temp16, bdz, temp32); |
| 1762 | temp32tlen = scale_expansion_zeroelim(temp16len, temp16, bdztail, temp32t); |
| 1763 | blen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, |
| 1764 | bdet); |
| 1765 | |
| 1766 | temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); |
| 1767 | temp32len = scale_expansion_zeroelim(temp16len, temp16, cdz, temp32); |
| 1768 | temp32tlen = scale_expansion_zeroelim(temp16len, temp16, cdztail, temp32t); |
| 1769 | clen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, |
| 1770 | cdet); |
| 1771 | |
| 1772 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 1773 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); |
| 1774 | |
| 1775 | return deter[deterlen - 1]; |
| 1776 | } |
| 1777 | |
| 1778 | REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) |
| 1779 | { |
| 1780 | INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; |
| 1781 | REAL det, errbound; |
| 1782 | |
| 1783 | INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; |
| 1784 | REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; |
| 1785 | REAL bc[4], ca[4], ab[4]; |
| 1786 | INEXACT REAL bc3, ca3, ab3; |
| 1787 | REAL adet[8], bdet[8], cdet[8]; |
| 1788 | int alen, blen, clen; |
| 1789 | REAL abdet[16]; |
| 1790 | int ablen; |
| 1791 | REAL *finnow, *finother, *finswap; |
| 1792 | REAL fin1[192], fin2[192]; |
| 1793 | int finlength; |
| 1794 | |
| 1795 | |
| 1796 | REAL adxtail, bdxtail, cdxtail; |
| 1797 | REAL adytail, bdytail, cdytail; |
| 1798 | REAL adztail, bdztail, cdztail; |
| 1799 | INEXACT REAL at_blarge, at_clarge; |
| 1800 | INEXACT REAL bt_clarge, bt_alarge; |
| 1801 | INEXACT REAL ct_alarge, ct_blarge; |
| 1802 | REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; |
| 1803 | int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; |
| 1804 | INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; |
| 1805 | INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; |
| 1806 | REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; |
| 1807 | REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; |
| 1808 | INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; |
| 1809 | INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; |
| 1810 | REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; |
| 1811 | REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; |
| 1812 | REAL bct[8], cat[8], abt[8]; |
| 1813 | int bctlen, catlen, abtlen; |
| 1814 | INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; |
| 1815 | INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; |
| 1816 | REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; |
| 1817 | REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; |
| 1818 | REAL u[4], v[12], w[16]; |
| 1819 | INEXACT REAL u3; |
| 1820 | int vlength, wlength; |
| 1821 | REAL negate; |
| 1822 | |
| 1823 | INEXACT REAL bvirt; |
| 1824 | REAL avirt, bround, around; |
| 1825 | INEXACT REAL c; |
| 1826 | INEXACT REAL abig; |
| 1827 | REAL ahi, alo, bhi, blo; |
| 1828 | REAL err1, err2, err3; |
| 1829 | INEXACT REAL _i, _j, _k; |
| 1830 | REAL _0; |
| 1831 | |
| 1832 | |
| 1833 | adx = (REAL) (pa[0] - pd[0]); |
| 1834 | bdx = (REAL) (pb[0] - pd[0]); |
| 1835 | cdx = (REAL) (pc[0] - pd[0]); |
| 1836 | ady = (REAL) (pa[1] - pd[1]); |
| 1837 | bdy = (REAL) (pb[1] - pd[1]); |
| 1838 | cdy = (REAL) (pc[1] - pd[1]); |
| 1839 | adz = (REAL) (pa[2] - pd[2]); |
| 1840 | bdz = (REAL) (pb[2] - pd[2]); |
| 1841 | cdz = (REAL) (pc[2] - pd[2]); |
| 1842 | |
| 1843 | Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); |
| 1844 | Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); |
| 1845 | Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); |
| 1846 | bc[3] = bc3; |
| 1847 | alen = scale_expansion_zeroelim(4, bc, adz, adet); |
| 1848 | |
| 1849 | Two_Product(cdx, ady, cdxady1, cdxady0); |
| 1850 | Two_Product(adx, cdy, adxcdy1, adxcdy0); |
| 1851 | Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); |
| 1852 | ca[3] = ca3; |
| 1853 | blen = scale_expansion_zeroelim(4, ca, bdz, bdet); |
| 1854 | |
| 1855 | Two_Product(adx, bdy, adxbdy1, adxbdy0); |
| 1856 | Two_Product(bdx, ady, bdxady1, bdxady0); |
| 1857 | Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); |
| 1858 | ab[3] = ab3; |
| 1859 | clen = scale_expansion_zeroelim(4, ab, cdz, cdet); |
| 1860 | |
| 1861 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 1862 | finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); |
| 1863 | |
| 1864 | det = estimate(finlength, fin1); |
| 1865 | errbound = o3derrboundB * permanent; |
| 1866 | if ((det >= errbound) || (-det >= errbound)) { |
| 1867 | return det; |
| 1868 | } |
| 1869 | |
| 1870 | Two_Diff_Tail(pa[0], pd[0], adx, adxtail); |
| 1871 | Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); |
| 1872 | Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); |
| 1873 | Two_Diff_Tail(pa[1], pd[1], ady, adytail); |
| 1874 | Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); |
| 1875 | Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); |
| 1876 | Two_Diff_Tail(pa[2], pd[2], adz, adztail); |
| 1877 | Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); |
| 1878 | Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); |
| 1879 | |
| 1880 | if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) |
| 1881 | && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) |
| 1882 | && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { |
| 1883 | return det; |
| 1884 | } |
| 1885 | |
| 1886 | errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); |
| 1887 | det += (adz * ((bdx * cdytail + cdy * bdxtail) |
| 1888 | - (bdy * cdxtail + cdx * bdytail)) |
| 1889 | + adztail * (bdx * cdy - bdy * cdx)) |
| 1890 | + (bdz * ((cdx * adytail + ady * cdxtail) |
| 1891 | - (cdy * adxtail + adx * cdytail)) |
| 1892 | + bdztail * (cdx * ady - cdy * adx)) |
| 1893 | + (cdz * ((adx * bdytail + bdy * adxtail) |
| 1894 | - (ady * bdxtail + bdx * adytail)) |
| 1895 | + cdztail * (adx * bdy - ady * bdx)); |
| 1896 | if ((det >= errbound) || (-det >= errbound)) { |
| 1897 | return det; |
| 1898 | } |
| 1899 | |
| 1900 | finnow = fin1; |
| 1901 | finother = fin2; |
| 1902 | |
| 1903 | if (adxtail == 0.0) { |
| 1904 | if (adytail == 0.0) { |
| 1905 | at_b[0] = 0.0; |
| 1906 | at_blen = 1; |
| 1907 | at_c[0] = 0.0; |
| 1908 | at_clen = 1; |
| 1909 | } else { |
| 1910 | negate = -adytail; |
| 1911 | Two_Product(negate, bdx, at_blarge, at_b[0]); |
| 1912 | at_b[1] = at_blarge; |
| 1913 | at_blen = 2; |
| 1914 | Two_Product(adytail, cdx, at_clarge, at_c[0]); |
| 1915 | at_c[1] = at_clarge; |
| 1916 | at_clen = 2; |
| 1917 | } |
| 1918 | } else { |
| 1919 | if (adytail == 0.0) { |
| 1920 | Two_Product(adxtail, bdy, at_blarge, at_b[0]); |
| 1921 | at_b[1] = at_blarge; |
| 1922 | at_blen = 2; |
| 1923 | negate = -adxtail; |
| 1924 | Two_Product(negate, cdy, at_clarge, at_c[0]); |
| 1925 | at_c[1] = at_clarge; |
| 1926 | at_clen = 2; |
| 1927 | } else { |
| 1928 | Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); |
| 1929 | Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); |
| 1930 | Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, |
| 1931 | at_blarge, at_b[2], at_b[1], at_b[0]); |
| 1932 | at_b[3] = at_blarge; |
| 1933 | at_blen = 4; |
| 1934 | Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); |
| 1935 | Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); |
| 1936 | Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, |
| 1937 | at_clarge, at_c[2], at_c[1], at_c[0]); |
| 1938 | at_c[3] = at_clarge; |
| 1939 | at_clen = 4; |
| 1940 | } |
| 1941 | } |
| 1942 | if (bdxtail == 0.0) { |
| 1943 | if (bdytail == 0.0) { |
| 1944 | bt_c[0] = 0.0; |
| 1945 | bt_clen = 1; |
| 1946 | bt_a[0] = 0.0; |
| 1947 | bt_alen = 1; |
| 1948 | } else { |
| 1949 | negate = -bdytail; |
| 1950 | Two_Product(negate, cdx, bt_clarge, bt_c[0]); |
| 1951 | bt_c[1] = bt_clarge; |
| 1952 | bt_clen = 2; |
| 1953 | Two_Product(bdytail, adx, bt_alarge, bt_a[0]); |
| 1954 | bt_a[1] = bt_alarge; |
| 1955 | bt_alen = 2; |
| 1956 | } |
| 1957 | } else { |
| 1958 | if (bdytail == 0.0) { |
| 1959 | Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); |
| 1960 | bt_c[1] = bt_clarge; |
| 1961 | bt_clen = 2; |
| 1962 | negate = -bdxtail; |
| 1963 | Two_Product(negate, ady, bt_alarge, bt_a[0]); |
| 1964 | bt_a[1] = bt_alarge; |
| 1965 | bt_alen = 2; |
| 1966 | } else { |
| 1967 | Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); |
| 1968 | Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); |
| 1969 | Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, |
| 1970 | bt_clarge, bt_c[2], bt_c[1], bt_c[0]); |
| 1971 | bt_c[3] = bt_clarge; |
| 1972 | bt_clen = 4; |
| 1973 | Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); |
| 1974 | Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); |
| 1975 | Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, |
| 1976 | bt_alarge, bt_a[2], bt_a[1], bt_a[0]); |
| 1977 | bt_a[3] = bt_alarge; |
| 1978 | bt_alen = 4; |
| 1979 | } |
| 1980 | } |
| 1981 | if (cdxtail == 0.0) { |
| 1982 | if (cdytail == 0.0) { |
| 1983 | ct_a[0] = 0.0; |
| 1984 | ct_alen = 1; |
| 1985 | ct_b[0] = 0.0; |
| 1986 | ct_blen = 1; |
| 1987 | } else { |
| 1988 | negate = -cdytail; |
| 1989 | Two_Product(negate, adx, ct_alarge, ct_a[0]); |
| 1990 | ct_a[1] = ct_alarge; |
| 1991 | ct_alen = 2; |
| 1992 | Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); |
| 1993 | ct_b[1] = ct_blarge; |
| 1994 | ct_blen = 2; |
| 1995 | } |
| 1996 | } else { |
| 1997 | if (cdytail == 0.0) { |
| 1998 | Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); |
| 1999 | ct_a[1] = ct_alarge; |
| 2000 | ct_alen = 2; |
| 2001 | negate = -cdxtail; |
| 2002 | Two_Product(negate, bdy, ct_blarge, ct_b[0]); |
| 2003 | ct_b[1] = ct_blarge; |
| 2004 | ct_blen = 2; |
| 2005 | } else { |
| 2006 | Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); |
| 2007 | Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); |
| 2008 | Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, |
| 2009 | ct_alarge, ct_a[2], ct_a[1], ct_a[0]); |
| 2010 | ct_a[3] = ct_alarge; |
| 2011 | ct_alen = 4; |
| 2012 | Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); |
| 2013 | Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); |
| 2014 | Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, |
| 2015 | ct_blarge, ct_b[2], ct_b[1], ct_b[0]); |
| 2016 | ct_b[3] = ct_blarge; |
| 2017 | ct_blen = 4; |
| 2018 | } |
| 2019 | } |
| 2020 | |
| 2021 | bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); |
| 2022 | wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); |
| 2023 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2024 | finother); |
| 2025 | finswap = finnow; finnow = finother; finother = finswap; |
| 2026 | |
| 2027 | catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); |
| 2028 | wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); |
| 2029 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2030 | finother); |
| 2031 | finswap = finnow; finnow = finother; finother = finswap; |
| 2032 | |
| 2033 | abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); |
| 2034 | wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); |
| 2035 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2036 | finother); |
| 2037 | finswap = finnow; finnow = finother; finother = finswap; |
| 2038 | |
| 2039 | if (adztail != 0.0) { |
| 2040 | vlength = scale_expansion_zeroelim(4, bc, adztail, v); |
| 2041 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, |
| 2042 | finother); |
| 2043 | finswap = finnow; finnow = finother; finother = finswap; |
| 2044 | } |
| 2045 | if (bdztail != 0.0) { |
| 2046 | vlength = scale_expansion_zeroelim(4, ca, bdztail, v); |
| 2047 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, |
| 2048 | finother); |
| 2049 | finswap = finnow; finnow = finother; finother = finswap; |
| 2050 | } |
| 2051 | if (cdztail != 0.0) { |
| 2052 | vlength = scale_expansion_zeroelim(4, ab, cdztail, v); |
| 2053 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, |
| 2054 | finother); |
| 2055 | finswap = finnow; finnow = finother; finother = finswap; |
| 2056 | } |
| 2057 | |
| 2058 | if (adxtail != 0.0) { |
| 2059 | if (bdytail != 0.0) { |
| 2060 | Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); |
| 2061 | Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); |
| 2062 | u[3] = u3; |
| 2063 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2064 | finother); |
| 2065 | finswap = finnow; finnow = finother; finother = finswap; |
| 2066 | if (cdztail != 0.0) { |
| 2067 | Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); |
| 2068 | u[3] = u3; |
| 2069 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2070 | finother); |
| 2071 | finswap = finnow; finnow = finother; finother = finswap; |
| 2072 | } |
| 2073 | } |
| 2074 | if (cdytail != 0.0) { |
| 2075 | negate = -adxtail; |
| 2076 | Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); |
| 2077 | Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); |
| 2078 | u[3] = u3; |
| 2079 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2080 | finother); |
| 2081 | finswap = finnow; finnow = finother; finother = finswap; |
| 2082 | if (bdztail != 0.0) { |
| 2083 | Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); |
| 2084 | u[3] = u3; |
| 2085 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2086 | finother); |
| 2087 | finswap = finnow; finnow = finother; finother = finswap; |
| 2088 | } |
| 2089 | } |
| 2090 | } |
| 2091 | if (bdxtail != 0.0) { |
| 2092 | if (cdytail != 0.0) { |
| 2093 | Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); |
| 2094 | Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); |
| 2095 | u[3] = u3; |
| 2096 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2097 | finother); |
| 2098 | finswap = finnow; finnow = finother; finother = finswap; |
| 2099 | if (adztail != 0.0) { |
| 2100 | Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); |
| 2101 | u[3] = u3; |
| 2102 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2103 | finother); |
| 2104 | finswap = finnow; finnow = finother; finother = finswap; |
| 2105 | } |
| 2106 | } |
| 2107 | if (adytail != 0.0) { |
| 2108 | negate = -bdxtail; |
| 2109 | Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); |
| 2110 | Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); |
| 2111 | u[3] = u3; |
| 2112 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2113 | finother); |
| 2114 | finswap = finnow; finnow = finother; finother = finswap; |
| 2115 | if (cdztail != 0.0) { |
| 2116 | Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); |
| 2117 | u[3] = u3; |
| 2118 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2119 | finother); |
| 2120 | finswap = finnow; finnow = finother; finother = finswap; |
| 2121 | } |
| 2122 | } |
| 2123 | } |
| 2124 | if (cdxtail != 0.0) { |
| 2125 | if (adytail != 0.0) { |
| 2126 | Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); |
| 2127 | Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); |
| 2128 | u[3] = u3; |
| 2129 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2130 | finother); |
| 2131 | finswap = finnow; finnow = finother; finother = finswap; |
| 2132 | if (bdztail != 0.0) { |
| 2133 | Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); |
| 2134 | u[3] = u3; |
| 2135 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2136 | finother); |
| 2137 | finswap = finnow; finnow = finother; finother = finswap; |
| 2138 | } |
| 2139 | } |
| 2140 | if (bdytail != 0.0) { |
| 2141 | negate = -cdxtail; |
| 2142 | Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); |
| 2143 | Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); |
| 2144 | u[3] = u3; |
| 2145 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2146 | finother); |
| 2147 | finswap = finnow; finnow = finother; finother = finswap; |
| 2148 | if (adztail != 0.0) { |
| 2149 | Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); |
| 2150 | u[3] = u3; |
| 2151 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, |
| 2152 | finother); |
| 2153 | finswap = finnow; finnow = finother; finother = finswap; |
| 2154 | } |
| 2155 | } |
| 2156 | } |
| 2157 | |
| 2158 | if (adztail != 0.0) { |
| 2159 | wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); |
| 2160 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2161 | finother); |
| 2162 | finswap = finnow; finnow = finother; finother = finswap; |
| 2163 | } |
| 2164 | if (bdztail != 0.0) { |
| 2165 | wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); |
| 2166 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2167 | finother); |
| 2168 | finswap = finnow; finnow = finother; finother = finswap; |
| 2169 | } |
| 2170 | if (cdztail != 0.0) { |
| 2171 | wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); |
| 2172 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, |
| 2173 | finother); |
| 2174 | finswap = finnow; finnow = finother; finother = finswap; |
| 2175 | } |
| 2176 | |
| 2177 | return finnow[finlength - 1]; |
| 2178 | } |
| 2179 | |
| 2180 | #ifdef USE_CGAL_PREDICATES |
| 2181 | |
| 2182 | REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 2183 | { |
| 2184 | return (REAL) |
| 2185 | - cgal_pred_obj.orientation_3_object() |
| 2186 | (Point(pa[0], pa[1], pa[2]), |
| 2187 | Point(pb[0], pb[1], pb[2]), |
| 2188 | Point(pc[0], pc[1], pc[2]), |
| 2189 | Point(pd[0], pd[1], pd[2])); |
| 2190 | } |
| 2191 | |
| 2192 | #else |
| 2193 | |
| 2194 | REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 2195 | { |
| 2196 | REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; |
| 2197 | REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; |
| 2198 | REAL det; |
| 2199 | |
| 2200 | |
| 2201 | adx = pa[0] - pd[0]; |
| 2202 | ady = pa[1] - pd[1]; |
| 2203 | adz = pa[2] - pd[2]; |
| 2204 | bdx = pb[0] - pd[0]; |
| 2205 | bdy = pb[1] - pd[1]; |
| 2206 | bdz = pb[2] - pd[2]; |
| 2207 | cdx = pc[0] - pd[0]; |
| 2208 | cdy = pc[1] - pd[1]; |
| 2209 | cdz = pc[2] - pd[2]; |
| 2210 | |
| 2211 | bdxcdy = bdx * cdy; |
| 2212 | cdxbdy = cdx * bdy; |
| 2213 | |
| 2214 | cdxady = cdx * ady; |
| 2215 | adxcdy = adx * cdy; |
| 2216 | |
| 2217 | adxbdy = adx * bdy; |
| 2218 | bdxady = bdx * ady; |
| 2219 | |
| 2220 | det = adz * (bdxcdy - cdxbdy) |
| 2221 | + bdz * (cdxady - adxcdy) |
| 2222 | + cdz * (adxbdy - bdxady); |
| 2223 | |
| 2224 | if (_use_inexact_arith) { |
| 2225 | return det; |
| 2226 | } |
| 2227 | |
| 2228 | if (_use_static_filter) { |
| 2229 | //if (fabs(det) > o3dstaticfilter) return det; |
| 2230 | if (det > o3dstaticfilter) return det; |
| 2231 | if (det < -o3dstaticfilter) return det; |
| 2232 | } |
| 2233 | |
| 2234 | |
| 2235 | REAL permanent, errbound; |
| 2236 | |
| 2237 | permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) |
| 2238 | + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) |
| 2239 | + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); |
| 2240 | errbound = o3derrboundA * permanent; |
| 2241 | if ((det > errbound) || (-det > errbound)) { |
| 2242 | return det; |
| 2243 | } |
| 2244 | |
| 2245 | return orient3dadapt(pa, pb, pc, pd, permanent); |
| 2246 | } |
| 2247 | |
| 2248 | #endif // #ifdef USE_CGAL_PREDICATES |
| 2249 | |
| 2250 | /*****************************************************************************/ |
| 2251 | /* */ |
| 2252 | /* incirclefast() Approximate 2D incircle test. Nonrobust. */ |
| 2253 | /* incircleexact() Exact 2D incircle test. Robust. */ |
| 2254 | /* incircleslow() Another exact 2D incircle test. Robust. */ |
| 2255 | /* incircle() Adaptive exact 2D incircle test. Robust. */ |
| 2256 | /* */ |
| 2257 | /* Return a positive value if the point pd lies inside the */ |
| 2258 | /* circle passing through pa, pb, and pc; a negative value if */ |
| 2259 | /* it lies outside; and zero if the four points are cocircular.*/ |
| 2260 | /* The points pa, pb, and pc must be in counterclockwise */ |
| 2261 | /* order, or the sign of the result will be reversed. */ |
| 2262 | /* */ |
| 2263 | /* Only the first and last routine should be used; the middle two are for */ |
| 2264 | /* timings. */ |
| 2265 | /* */ |
| 2266 | /* The last three use exact arithmetic to ensure a correct answer. The */ |
| 2267 | /* result returned is the determinant of a matrix. In incircle() only, */ |
| 2268 | /* this determinant is computed adaptively, in the sense that exact */ |
| 2269 | /* arithmetic is used only to the degree it is needed to ensure that the */ |
| 2270 | /* returned value has the correct sign. Hence, incircle() is usually quite */ |
| 2271 | /* fast, but will run more slowly when the input points are cocircular or */ |
| 2272 | /* nearly so. */ |
| 2273 | /* */ |
| 2274 | /*****************************************************************************/ |
| 2275 | |
| 2276 | REAL incirclefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 2277 | { |
| 2278 | REAL adx, ady, bdx, bdy, cdx, cdy; |
| 2279 | REAL abdet, bcdet, cadet; |
| 2280 | REAL alift, blift, clift; |
| 2281 | |
| 2282 | adx = pa[0] - pd[0]; |
| 2283 | ady = pa[1] - pd[1]; |
| 2284 | bdx = pb[0] - pd[0]; |
| 2285 | bdy = pb[1] - pd[1]; |
| 2286 | cdx = pc[0] - pd[0]; |
| 2287 | cdy = pc[1] - pd[1]; |
| 2288 | |
| 2289 | abdet = adx * bdy - bdx * ady; |
| 2290 | bcdet = bdx * cdy - cdx * bdy; |
| 2291 | cadet = cdx * ady - adx * cdy; |
| 2292 | alift = adx * adx + ady * ady; |
| 2293 | blift = bdx * bdx + bdy * bdy; |
| 2294 | clift = cdx * cdx + cdy * cdy; |
| 2295 | |
| 2296 | return alift * bcdet + blift * cadet + clift * abdet; |
| 2297 | } |
| 2298 | |
| 2299 | REAL incircleexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 2300 | { |
| 2301 | INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; |
| 2302 | INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; |
| 2303 | REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; |
| 2304 | REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; |
| 2305 | REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; |
| 2306 | REAL temp8[8]; |
| 2307 | int templen; |
| 2308 | REAL abc[12], bcd[12], cda[12], dab[12]; |
| 2309 | int abclen, bcdlen, cdalen, dablen; |
| 2310 | REAL det24x[24], det24y[24], det48x[48], det48y[48]; |
| 2311 | int xlen, ylen; |
| 2312 | REAL adet[96], bdet[96], cdet[96], ddet[96]; |
| 2313 | int alen, blen, clen, dlen; |
| 2314 | REAL abdet[192], cddet[192]; |
| 2315 | int ablen, cdlen; |
| 2316 | REAL deter[384]; |
| 2317 | int deterlen; |
| 2318 | int i; |
| 2319 | |
| 2320 | INEXACT REAL bvirt; |
| 2321 | REAL avirt, bround, around; |
| 2322 | INEXACT REAL c; |
| 2323 | INEXACT REAL abig; |
| 2324 | REAL ahi, alo, bhi, blo; |
| 2325 | REAL err1, err2, err3; |
| 2326 | INEXACT REAL _i, _j; |
| 2327 | REAL _0; |
| 2328 | |
| 2329 | Two_Product(pa[0], pb[1], axby1, axby0); |
| 2330 | Two_Product(pb[0], pa[1], bxay1, bxay0); |
| 2331 | Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); |
| 2332 | |
| 2333 | Two_Product(pb[0], pc[1], bxcy1, bxcy0); |
| 2334 | Two_Product(pc[0], pb[1], cxby1, cxby0); |
| 2335 | Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); |
| 2336 | |
| 2337 | Two_Product(pc[0], pd[1], cxdy1, cxdy0); |
| 2338 | Two_Product(pd[0], pc[1], dxcy1, dxcy0); |
| 2339 | Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); |
| 2340 | |
| 2341 | Two_Product(pd[0], pa[1], dxay1, dxay0); |
| 2342 | Two_Product(pa[0], pd[1], axdy1, axdy0); |
| 2343 | Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); |
| 2344 | |
| 2345 | Two_Product(pa[0], pc[1], axcy1, axcy0); |
| 2346 | Two_Product(pc[0], pa[1], cxay1, cxay0); |
| 2347 | Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); |
| 2348 | |
| 2349 | Two_Product(pb[0], pd[1], bxdy1, bxdy0); |
| 2350 | Two_Product(pd[0], pb[1], dxby1, dxby0); |
| 2351 | Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); |
| 2352 | |
| 2353 | templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); |
| 2354 | cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); |
| 2355 | templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); |
| 2356 | dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); |
| 2357 | for (i = 0; i < 4; i++) { |
| 2358 | bd[i] = -bd[i]; |
| 2359 | ac[i] = -ac[i]; |
| 2360 | } |
| 2361 | templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); |
| 2362 | abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); |
| 2363 | templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); |
| 2364 | bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); |
| 2365 | |
| 2366 | xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); |
| 2367 | xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); |
| 2368 | ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); |
| 2369 | ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); |
| 2370 | alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); |
| 2371 | |
| 2372 | xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); |
| 2373 | xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); |
| 2374 | ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); |
| 2375 | ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); |
| 2376 | blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); |
| 2377 | |
| 2378 | xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); |
| 2379 | xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); |
| 2380 | ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); |
| 2381 | ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); |
| 2382 | clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); |
| 2383 | |
| 2384 | xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); |
| 2385 | xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); |
| 2386 | ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); |
| 2387 | ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); |
| 2388 | dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); |
| 2389 | |
| 2390 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 2391 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 2392 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); |
| 2393 | |
| 2394 | return deter[deterlen - 1]; |
| 2395 | } |
| 2396 | |
| 2397 | REAL incircleslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 2398 | { |
| 2399 | INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; |
| 2400 | REAL adxtail, bdxtail, cdxtail; |
| 2401 | REAL adytail, bdytail, cdytail; |
| 2402 | REAL negate, negatetail; |
| 2403 | INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; |
| 2404 | REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; |
| 2405 | REAL temp16[16]; |
| 2406 | int temp16len; |
| 2407 | REAL detx[32], detxx[64], detxt[32], detxxt[64], detxtxt[64]; |
| 2408 | int xlen, xxlen, xtlen, xxtlen, xtxtlen; |
| 2409 | REAL x1[128], x2[192]; |
| 2410 | int x1len, x2len; |
| 2411 | REAL dety[32], detyy[64], detyt[32], detyyt[64], detytyt[64]; |
| 2412 | int ylen, yylen, ytlen, yytlen, ytytlen; |
| 2413 | REAL y1[128], y2[192]; |
| 2414 | int y1len, y2len; |
| 2415 | REAL adet[384], bdet[384], cdet[384], abdet[768], deter[1152]; |
| 2416 | int alen, blen, clen, ablen, deterlen; |
| 2417 | int i; |
| 2418 | |
| 2419 | INEXACT REAL bvirt; |
| 2420 | REAL avirt, bround, around; |
| 2421 | INEXACT REAL c; |
| 2422 | INEXACT REAL abig; |
| 2423 | REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; |
| 2424 | REAL err1, err2, err3; |
| 2425 | INEXACT REAL _i, _j, _k, _l, _m, _n; |
| 2426 | REAL _0, _1, _2; |
| 2427 | |
| 2428 | Two_Diff(pa[0], pd[0], adx, adxtail); |
| 2429 | Two_Diff(pa[1], pd[1], ady, adytail); |
| 2430 | Two_Diff(pb[0], pd[0], bdx, bdxtail); |
| 2431 | Two_Diff(pb[1], pd[1], bdy, bdytail); |
| 2432 | Two_Diff(pc[0], pd[0], cdx, cdxtail); |
| 2433 | Two_Diff(pc[1], pd[1], cdy, cdytail); |
| 2434 | |
| 2435 | Two_Two_Product(adx, adxtail, bdy, bdytail, |
| 2436 | axby7, axby[6], axby[5], axby[4], |
| 2437 | axby[3], axby[2], axby[1], axby[0]); |
| 2438 | axby[7] = axby7; |
| 2439 | negate = -ady; |
| 2440 | negatetail = -adytail; |
| 2441 | Two_Two_Product(bdx, bdxtail, negate, negatetail, |
| 2442 | bxay7, bxay[6], bxay[5], bxay[4], |
| 2443 | bxay[3], bxay[2], bxay[1], bxay[0]); |
| 2444 | bxay[7] = bxay7; |
| 2445 | Two_Two_Product(bdx, bdxtail, cdy, cdytail, |
| 2446 | bxcy7, bxcy[6], bxcy[5], bxcy[4], |
| 2447 | bxcy[3], bxcy[2], bxcy[1], bxcy[0]); |
| 2448 | bxcy[7] = bxcy7; |
| 2449 | negate = -bdy; |
| 2450 | negatetail = -bdytail; |
| 2451 | Two_Two_Product(cdx, cdxtail, negate, negatetail, |
| 2452 | cxby7, cxby[6], cxby[5], cxby[4], |
| 2453 | cxby[3], cxby[2], cxby[1], cxby[0]); |
| 2454 | cxby[7] = cxby7; |
| 2455 | Two_Two_Product(cdx, cdxtail, ady, adytail, |
| 2456 | cxay7, cxay[6], cxay[5], cxay[4], |
| 2457 | cxay[3], cxay[2], cxay[1], cxay[0]); |
| 2458 | cxay[7] = cxay7; |
| 2459 | negate = -cdy; |
| 2460 | negatetail = -cdytail; |
| 2461 | Two_Two_Product(adx, adxtail, negate, negatetail, |
| 2462 | axcy7, axcy[6], axcy[5], axcy[4], |
| 2463 | axcy[3], axcy[2], axcy[1], axcy[0]); |
| 2464 | axcy[7] = axcy7; |
| 2465 | |
| 2466 | |
| 2467 | temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); |
| 2468 | |
| 2469 | xlen = scale_expansion_zeroelim(temp16len, temp16, adx, detx); |
| 2470 | xxlen = scale_expansion_zeroelim(xlen, detx, adx, detxx); |
| 2471 | xtlen = scale_expansion_zeroelim(temp16len, temp16, adxtail, detxt); |
| 2472 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, adx, detxxt); |
| 2473 | for (i = 0; i < xxtlen; i++) { |
| 2474 | detxxt[i] *= 2.0; |
| 2475 | } |
| 2476 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, adxtail, detxtxt); |
| 2477 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 2478 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 2479 | |
| 2480 | ylen = scale_expansion_zeroelim(temp16len, temp16, ady, dety); |
| 2481 | yylen = scale_expansion_zeroelim(ylen, dety, ady, detyy); |
| 2482 | ytlen = scale_expansion_zeroelim(temp16len, temp16, adytail, detyt); |
| 2483 | yytlen = scale_expansion_zeroelim(ytlen, detyt, ady, detyyt); |
| 2484 | for (i = 0; i < yytlen; i++) { |
| 2485 | detyyt[i] *= 2.0; |
| 2486 | } |
| 2487 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, adytail, detytyt); |
| 2488 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 2489 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 2490 | |
| 2491 | alen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, adet); |
| 2492 | |
| 2493 | |
| 2494 | temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); |
| 2495 | |
| 2496 | xlen = scale_expansion_zeroelim(temp16len, temp16, bdx, detx); |
| 2497 | xxlen = scale_expansion_zeroelim(xlen, detx, bdx, detxx); |
| 2498 | xtlen = scale_expansion_zeroelim(temp16len, temp16, bdxtail, detxt); |
| 2499 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, bdx, detxxt); |
| 2500 | for (i = 0; i < xxtlen; i++) { |
| 2501 | detxxt[i] *= 2.0; |
| 2502 | } |
| 2503 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bdxtail, detxtxt); |
| 2504 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 2505 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 2506 | |
| 2507 | ylen = scale_expansion_zeroelim(temp16len, temp16, bdy, dety); |
| 2508 | yylen = scale_expansion_zeroelim(ylen, dety, bdy, detyy); |
| 2509 | ytlen = scale_expansion_zeroelim(temp16len, temp16, bdytail, detyt); |
| 2510 | yytlen = scale_expansion_zeroelim(ytlen, detyt, bdy, detyyt); |
| 2511 | for (i = 0; i < yytlen; i++) { |
| 2512 | detyyt[i] *= 2.0; |
| 2513 | } |
| 2514 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, bdytail, detytyt); |
| 2515 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 2516 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 2517 | |
| 2518 | blen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, bdet); |
| 2519 | |
| 2520 | |
| 2521 | temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); |
| 2522 | |
| 2523 | xlen = scale_expansion_zeroelim(temp16len, temp16, cdx, detx); |
| 2524 | xxlen = scale_expansion_zeroelim(xlen, detx, cdx, detxx); |
| 2525 | xtlen = scale_expansion_zeroelim(temp16len, temp16, cdxtail, detxt); |
| 2526 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, cdx, detxxt); |
| 2527 | for (i = 0; i < xxtlen; i++) { |
| 2528 | detxxt[i] *= 2.0; |
| 2529 | } |
| 2530 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cdxtail, detxtxt); |
| 2531 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 2532 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 2533 | |
| 2534 | ylen = scale_expansion_zeroelim(temp16len, temp16, cdy, dety); |
| 2535 | yylen = scale_expansion_zeroelim(ylen, dety, cdy, detyy); |
| 2536 | ytlen = scale_expansion_zeroelim(temp16len, temp16, cdytail, detyt); |
| 2537 | yytlen = scale_expansion_zeroelim(ytlen, detyt, cdy, detyyt); |
| 2538 | for (i = 0; i < yytlen; i++) { |
| 2539 | detyyt[i] *= 2.0; |
| 2540 | } |
| 2541 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, cdytail, detytyt); |
| 2542 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 2543 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 2544 | |
| 2545 | clen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, cdet); |
| 2546 | |
| 2547 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 2548 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); |
| 2549 | |
| 2550 | return deter[deterlen - 1]; |
| 2551 | } |
| 2552 | |
| 2553 | REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) |
| 2554 | { |
| 2555 | INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; |
| 2556 | REAL det, errbound; |
| 2557 | |
| 2558 | INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; |
| 2559 | REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; |
| 2560 | REAL bc[4], ca[4], ab[4]; |
| 2561 | INEXACT REAL bc3, ca3, ab3; |
| 2562 | REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; |
| 2563 | int axbclen, axxbclen, aybclen, ayybclen, alen; |
| 2564 | REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; |
| 2565 | int bxcalen, bxxcalen, bycalen, byycalen, blen; |
| 2566 | REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; |
| 2567 | int cxablen, cxxablen, cyablen, cyyablen, clen; |
| 2568 | REAL abdet[64]; |
| 2569 | int ablen; |
| 2570 | REAL fin1[1152], fin2[1152]; |
| 2571 | REAL *finnow, *finother, *finswap; |
| 2572 | int finlength; |
| 2573 | |
| 2574 | REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; |
| 2575 | INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; |
| 2576 | REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; |
| 2577 | REAL aa[4], bb[4], cc[4]; |
| 2578 | INEXACT REAL aa3, bb3, cc3; |
| 2579 | INEXACT REAL ti1, tj1; |
| 2580 | REAL ti0, tj0; |
| 2581 | REAL u[4], v[4]; |
| 2582 | INEXACT REAL u3, v3; |
| 2583 | REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; |
| 2584 | REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; |
| 2585 | int temp8len, temp16alen, temp16blen, temp16clen; |
| 2586 | int temp32alen, temp32blen, temp48len, temp64len; |
| 2587 | REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; |
| 2588 | int axtbblen, axtcclen, aytbblen, aytcclen; |
| 2589 | REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; |
| 2590 | int bxtaalen, bxtcclen, bytaalen, bytcclen; |
| 2591 | REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; |
| 2592 | int cxtaalen, cxtbblen, cytaalen, cytbblen; |
| 2593 | REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; |
| 2594 | int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen; |
| 2595 | REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; |
| 2596 | int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; |
| 2597 | REAL axtbctt[8], aytbctt[8], bxtcatt[8]; |
| 2598 | REAL bytcatt[8], cxtabtt[8], cytabtt[8]; |
| 2599 | int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; |
| 2600 | REAL abt[8], bct[8], cat[8]; |
| 2601 | int abtlen, bctlen, catlen; |
| 2602 | REAL abtt[4], bctt[4], catt[4]; |
| 2603 | int abttlen, bcttlen, cattlen; |
| 2604 | INEXACT REAL abtt3, bctt3, catt3; |
| 2605 | REAL negate; |
| 2606 | |
| 2607 | INEXACT REAL bvirt; |
| 2608 | REAL avirt, bround, around; |
| 2609 | INEXACT REAL c; |
| 2610 | INEXACT REAL abig; |
| 2611 | REAL ahi, alo, bhi, blo; |
| 2612 | REAL err1, err2, err3; |
| 2613 | INEXACT REAL _i, _j; |
| 2614 | REAL _0; |
| 2615 | |
| 2616 | // Avoid compiler warnings. H. Si, 2012-02-16. |
| 2617 | axtbclen = aytbclen = bxtcalen = bytcalen = cxtablen = cytablen = 0; |
| 2618 | |
| 2619 | adx = (REAL) (pa[0] - pd[0]); |
| 2620 | bdx = (REAL) (pb[0] - pd[0]); |
| 2621 | cdx = (REAL) (pc[0] - pd[0]); |
| 2622 | ady = (REAL) (pa[1] - pd[1]); |
| 2623 | bdy = (REAL) (pb[1] - pd[1]); |
| 2624 | cdy = (REAL) (pc[1] - pd[1]); |
| 2625 | |
| 2626 | Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); |
| 2627 | Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); |
| 2628 | Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); |
| 2629 | bc[3] = bc3; |
| 2630 | axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); |
| 2631 | axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); |
| 2632 | aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); |
| 2633 | ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); |
| 2634 | alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); |
| 2635 | |
| 2636 | Two_Product(cdx, ady, cdxady1, cdxady0); |
| 2637 | Two_Product(adx, cdy, adxcdy1, adxcdy0); |
| 2638 | Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); |
| 2639 | ca[3] = ca3; |
| 2640 | bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); |
| 2641 | bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); |
| 2642 | bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); |
| 2643 | byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); |
| 2644 | blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); |
| 2645 | |
| 2646 | Two_Product(adx, bdy, adxbdy1, adxbdy0); |
| 2647 | Two_Product(bdx, ady, bdxady1, bdxady0); |
| 2648 | Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); |
| 2649 | ab[3] = ab3; |
| 2650 | cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); |
| 2651 | cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); |
| 2652 | cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); |
| 2653 | cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); |
| 2654 | clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); |
| 2655 | |
| 2656 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 2657 | finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); |
| 2658 | |
| 2659 | det = estimate(finlength, fin1); |
| 2660 | errbound = iccerrboundB * permanent; |
| 2661 | if ((det >= errbound) || (-det >= errbound)) { |
| 2662 | return det; |
| 2663 | } |
| 2664 | |
| 2665 | Two_Diff_Tail(pa[0], pd[0], adx, adxtail); |
| 2666 | Two_Diff_Tail(pa[1], pd[1], ady, adytail); |
| 2667 | Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); |
| 2668 | Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); |
| 2669 | Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); |
| 2670 | Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); |
| 2671 | if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) |
| 2672 | && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { |
| 2673 | return det; |
| 2674 | } |
| 2675 | |
| 2676 | errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); |
| 2677 | det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) |
| 2678 | - (bdy * cdxtail + cdx * bdytail)) |
| 2679 | + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) |
| 2680 | + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) |
| 2681 | - (cdy * adxtail + adx * cdytail)) |
| 2682 | + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) |
| 2683 | + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) |
| 2684 | - (ady * bdxtail + bdx * adytail)) |
| 2685 | + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); |
| 2686 | if ((det >= errbound) || (-det >= errbound)) { |
| 2687 | return det; |
| 2688 | } |
| 2689 | |
| 2690 | finnow = fin1; |
| 2691 | finother = fin2; |
| 2692 | |
| 2693 | if ((bdxtail != 0.0) || (bdytail != 0.0) |
| 2694 | || (cdxtail != 0.0) || (cdytail != 0.0)) { |
| 2695 | Square(adx, adxadx1, adxadx0); |
| 2696 | Square(ady, adyady1, adyady0); |
| 2697 | Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); |
| 2698 | aa[3] = aa3; |
| 2699 | } |
| 2700 | if ((cdxtail != 0.0) || (cdytail != 0.0) |
| 2701 | || (adxtail != 0.0) || (adytail != 0.0)) { |
| 2702 | Square(bdx, bdxbdx1, bdxbdx0); |
| 2703 | Square(bdy, bdybdy1, bdybdy0); |
| 2704 | Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); |
| 2705 | bb[3] = bb3; |
| 2706 | } |
| 2707 | if ((adxtail != 0.0) || (adytail != 0.0) |
| 2708 | || (bdxtail != 0.0) || (bdytail != 0.0)) { |
| 2709 | Square(cdx, cdxcdx1, cdxcdx0); |
| 2710 | Square(cdy, cdycdy1, cdycdy0); |
| 2711 | Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); |
| 2712 | cc[3] = cc3; |
| 2713 | } |
| 2714 | |
| 2715 | if (adxtail != 0.0) { |
| 2716 | axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); |
| 2717 | temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, |
| 2718 | temp16a); |
| 2719 | |
| 2720 | axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); |
| 2721 | temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); |
| 2722 | |
| 2723 | axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); |
| 2724 | temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); |
| 2725 | |
| 2726 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2727 | temp16blen, temp16b, temp32a); |
| 2728 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2729 | temp32alen, temp32a, temp48); |
| 2730 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2731 | temp48, finother); |
| 2732 | finswap = finnow; finnow = finother; finother = finswap; |
| 2733 | } |
| 2734 | if (adytail != 0.0) { |
| 2735 | aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); |
| 2736 | temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, |
| 2737 | temp16a); |
| 2738 | |
| 2739 | aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); |
| 2740 | temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); |
| 2741 | |
| 2742 | aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); |
| 2743 | temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); |
| 2744 | |
| 2745 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2746 | temp16blen, temp16b, temp32a); |
| 2747 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2748 | temp32alen, temp32a, temp48); |
| 2749 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2750 | temp48, finother); |
| 2751 | finswap = finnow; finnow = finother; finother = finswap; |
| 2752 | } |
| 2753 | if (bdxtail != 0.0) { |
| 2754 | bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); |
| 2755 | temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, |
| 2756 | temp16a); |
| 2757 | |
| 2758 | bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); |
| 2759 | temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); |
| 2760 | |
| 2761 | bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); |
| 2762 | temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); |
| 2763 | |
| 2764 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2765 | temp16blen, temp16b, temp32a); |
| 2766 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2767 | temp32alen, temp32a, temp48); |
| 2768 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2769 | temp48, finother); |
| 2770 | finswap = finnow; finnow = finother; finother = finswap; |
| 2771 | } |
| 2772 | if (bdytail != 0.0) { |
| 2773 | bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); |
| 2774 | temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, |
| 2775 | temp16a); |
| 2776 | |
| 2777 | bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); |
| 2778 | temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); |
| 2779 | |
| 2780 | bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); |
| 2781 | temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); |
| 2782 | |
| 2783 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2784 | temp16blen, temp16b, temp32a); |
| 2785 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2786 | temp32alen, temp32a, temp48); |
| 2787 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2788 | temp48, finother); |
| 2789 | finswap = finnow; finnow = finother; finother = finswap; |
| 2790 | } |
| 2791 | if (cdxtail != 0.0) { |
| 2792 | cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); |
| 2793 | temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, |
| 2794 | temp16a); |
| 2795 | |
| 2796 | cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); |
| 2797 | temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); |
| 2798 | |
| 2799 | cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); |
| 2800 | temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); |
| 2801 | |
| 2802 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2803 | temp16blen, temp16b, temp32a); |
| 2804 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2805 | temp32alen, temp32a, temp48); |
| 2806 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2807 | temp48, finother); |
| 2808 | finswap = finnow; finnow = finother; finother = finswap; |
| 2809 | } |
| 2810 | if (cdytail != 0.0) { |
| 2811 | cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); |
| 2812 | temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, |
| 2813 | temp16a); |
| 2814 | |
| 2815 | cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); |
| 2816 | temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); |
| 2817 | |
| 2818 | cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); |
| 2819 | temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); |
| 2820 | |
| 2821 | temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2822 | temp16blen, temp16b, temp32a); |
| 2823 | temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, |
| 2824 | temp32alen, temp32a, temp48); |
| 2825 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2826 | temp48, finother); |
| 2827 | finswap = finnow; finnow = finother; finother = finswap; |
| 2828 | } |
| 2829 | |
| 2830 | if ((adxtail != 0.0) || (adytail != 0.0)) { |
| 2831 | if ((bdxtail != 0.0) || (bdytail != 0.0) |
| 2832 | || (cdxtail != 0.0) || (cdytail != 0.0)) { |
| 2833 | Two_Product(bdxtail, cdy, ti1, ti0); |
| 2834 | Two_Product(bdx, cdytail, tj1, tj0); |
| 2835 | Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); |
| 2836 | u[3] = u3; |
| 2837 | negate = -bdy; |
| 2838 | Two_Product(cdxtail, negate, ti1, ti0); |
| 2839 | negate = -bdytail; |
| 2840 | Two_Product(cdx, negate, tj1, tj0); |
| 2841 | Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); |
| 2842 | v[3] = v3; |
| 2843 | bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); |
| 2844 | |
| 2845 | Two_Product(bdxtail, cdytail, ti1, ti0); |
| 2846 | Two_Product(cdxtail, bdytail, tj1, tj0); |
| 2847 | Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); |
| 2848 | bctt[3] = bctt3; |
| 2849 | bcttlen = 4; |
| 2850 | } else { |
| 2851 | bct[0] = 0.0; |
| 2852 | bctlen = 1; |
| 2853 | bctt[0] = 0.0; |
| 2854 | bcttlen = 1; |
| 2855 | } |
| 2856 | |
| 2857 | if (adxtail != 0.0) { |
| 2858 | temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); |
| 2859 | axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); |
| 2860 | temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, |
| 2861 | temp32a); |
| 2862 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2863 | temp32alen, temp32a, temp48); |
| 2864 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2865 | temp48, finother); |
| 2866 | finswap = finnow; finnow = finother; finother = finswap; |
| 2867 | if (bdytail != 0.0) { |
| 2868 | temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); |
| 2869 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, |
| 2870 | temp16a); |
| 2871 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 2872 | temp16a, finother); |
| 2873 | finswap = finnow; finnow = finother; finother = finswap; |
| 2874 | } |
| 2875 | if (cdytail != 0.0) { |
| 2876 | temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); |
| 2877 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, |
| 2878 | temp16a); |
| 2879 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 2880 | temp16a, finother); |
| 2881 | finswap = finnow; finnow = finother; finother = finswap; |
| 2882 | } |
| 2883 | |
| 2884 | temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, |
| 2885 | temp32a); |
| 2886 | axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); |
| 2887 | temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, |
| 2888 | temp16a); |
| 2889 | temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, |
| 2890 | temp16b); |
| 2891 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2892 | temp16blen, temp16b, temp32b); |
| 2893 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 2894 | temp32blen, temp32b, temp64); |
| 2895 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 2896 | temp64, finother); |
| 2897 | finswap = finnow; finnow = finother; finother = finswap; |
| 2898 | } |
| 2899 | if (adytail != 0.0) { |
| 2900 | temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); |
| 2901 | aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); |
| 2902 | temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, |
| 2903 | temp32a); |
| 2904 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2905 | temp32alen, temp32a, temp48); |
| 2906 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2907 | temp48, finother); |
| 2908 | finswap = finnow; finnow = finother; finother = finswap; |
| 2909 | |
| 2910 | |
| 2911 | temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, |
| 2912 | temp32a); |
| 2913 | aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); |
| 2914 | temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, |
| 2915 | temp16a); |
| 2916 | temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, |
| 2917 | temp16b); |
| 2918 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2919 | temp16blen, temp16b, temp32b); |
| 2920 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 2921 | temp32blen, temp32b, temp64); |
| 2922 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 2923 | temp64, finother); |
| 2924 | finswap = finnow; finnow = finother; finother = finswap; |
| 2925 | } |
| 2926 | } |
| 2927 | if ((bdxtail != 0.0) || (bdytail != 0.0)) { |
| 2928 | if ((cdxtail != 0.0) || (cdytail != 0.0) |
| 2929 | || (adxtail != 0.0) || (adytail != 0.0)) { |
| 2930 | Two_Product(cdxtail, ady, ti1, ti0); |
| 2931 | Two_Product(cdx, adytail, tj1, tj0); |
| 2932 | Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); |
| 2933 | u[3] = u3; |
| 2934 | negate = -cdy; |
| 2935 | Two_Product(adxtail, negate, ti1, ti0); |
| 2936 | negate = -cdytail; |
| 2937 | Two_Product(adx, negate, tj1, tj0); |
| 2938 | Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); |
| 2939 | v[3] = v3; |
| 2940 | catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); |
| 2941 | |
| 2942 | Two_Product(cdxtail, adytail, ti1, ti0); |
| 2943 | Two_Product(adxtail, cdytail, tj1, tj0); |
| 2944 | Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); |
| 2945 | catt[3] = catt3; |
| 2946 | cattlen = 4; |
| 2947 | } else { |
| 2948 | cat[0] = 0.0; |
| 2949 | catlen = 1; |
| 2950 | catt[0] = 0.0; |
| 2951 | cattlen = 1; |
| 2952 | } |
| 2953 | |
| 2954 | if (bdxtail != 0.0) { |
| 2955 | temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); |
| 2956 | bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); |
| 2957 | temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, |
| 2958 | temp32a); |
| 2959 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2960 | temp32alen, temp32a, temp48); |
| 2961 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 2962 | temp48, finother); |
| 2963 | finswap = finnow; finnow = finother; finother = finswap; |
| 2964 | if (cdytail != 0.0) { |
| 2965 | temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); |
| 2966 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, |
| 2967 | temp16a); |
| 2968 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 2969 | temp16a, finother); |
| 2970 | finswap = finnow; finnow = finother; finother = finswap; |
| 2971 | } |
| 2972 | if (adytail != 0.0) { |
| 2973 | temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); |
| 2974 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, |
| 2975 | temp16a); |
| 2976 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 2977 | temp16a, finother); |
| 2978 | finswap = finnow; finnow = finother; finother = finswap; |
| 2979 | } |
| 2980 | |
| 2981 | temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, |
| 2982 | temp32a); |
| 2983 | bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); |
| 2984 | temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, |
| 2985 | temp16a); |
| 2986 | temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, |
| 2987 | temp16b); |
| 2988 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 2989 | temp16blen, temp16b, temp32b); |
| 2990 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 2991 | temp32blen, temp32b, temp64); |
| 2992 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 2993 | temp64, finother); |
| 2994 | finswap = finnow; finnow = finother; finother = finswap; |
| 2995 | } |
| 2996 | if (bdytail != 0.0) { |
| 2997 | temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); |
| 2998 | bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); |
| 2999 | temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, |
| 3000 | temp32a); |
| 3001 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3002 | temp32alen, temp32a, temp48); |
| 3003 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 3004 | temp48, finother); |
| 3005 | finswap = finnow; finnow = finother; finother = finswap; |
| 3006 | |
| 3007 | |
| 3008 | temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, |
| 3009 | temp32a); |
| 3010 | bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); |
| 3011 | temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, |
| 3012 | temp16a); |
| 3013 | temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, |
| 3014 | temp16b); |
| 3015 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3016 | temp16blen, temp16b, temp32b); |
| 3017 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3018 | temp32blen, temp32b, temp64); |
| 3019 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 3020 | temp64, finother); |
| 3021 | finswap = finnow; finnow = finother; finother = finswap; |
| 3022 | } |
| 3023 | } |
| 3024 | if ((cdxtail != 0.0) || (cdytail != 0.0)) { |
| 3025 | if ((adxtail != 0.0) || (adytail != 0.0) |
| 3026 | || (bdxtail != 0.0) || (bdytail != 0.0)) { |
| 3027 | Two_Product(adxtail, bdy, ti1, ti0); |
| 3028 | Two_Product(adx, bdytail, tj1, tj0); |
| 3029 | Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); |
| 3030 | u[3] = u3; |
| 3031 | negate = -ady; |
| 3032 | Two_Product(bdxtail, negate, ti1, ti0); |
| 3033 | negate = -adytail; |
| 3034 | Two_Product(bdx, negate, tj1, tj0); |
| 3035 | Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); |
| 3036 | v[3] = v3; |
| 3037 | abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); |
| 3038 | |
| 3039 | Two_Product(adxtail, bdytail, ti1, ti0); |
| 3040 | Two_Product(bdxtail, adytail, tj1, tj0); |
| 3041 | Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); |
| 3042 | abtt[3] = abtt3; |
| 3043 | abttlen = 4; |
| 3044 | } else { |
| 3045 | abt[0] = 0.0; |
| 3046 | abtlen = 1; |
| 3047 | abtt[0] = 0.0; |
| 3048 | abttlen = 1; |
| 3049 | } |
| 3050 | |
| 3051 | if (cdxtail != 0.0) { |
| 3052 | temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); |
| 3053 | cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); |
| 3054 | temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, |
| 3055 | temp32a); |
| 3056 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3057 | temp32alen, temp32a, temp48); |
| 3058 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 3059 | temp48, finother); |
| 3060 | finswap = finnow; finnow = finother; finother = finswap; |
| 3061 | if (adytail != 0.0) { |
| 3062 | temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); |
| 3063 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, |
| 3064 | temp16a); |
| 3065 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 3066 | temp16a, finother); |
| 3067 | finswap = finnow; finnow = finother; finother = finswap; |
| 3068 | } |
| 3069 | if (bdytail != 0.0) { |
| 3070 | temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); |
| 3071 | temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, |
| 3072 | temp16a); |
| 3073 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, |
| 3074 | temp16a, finother); |
| 3075 | finswap = finnow; finnow = finother; finother = finswap; |
| 3076 | } |
| 3077 | |
| 3078 | temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, |
| 3079 | temp32a); |
| 3080 | cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); |
| 3081 | temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, |
| 3082 | temp16a); |
| 3083 | temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, |
| 3084 | temp16b); |
| 3085 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3086 | temp16blen, temp16b, temp32b); |
| 3087 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3088 | temp32blen, temp32b, temp64); |
| 3089 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 3090 | temp64, finother); |
| 3091 | finswap = finnow; finnow = finother; finother = finswap; |
| 3092 | } |
| 3093 | if (cdytail != 0.0) { |
| 3094 | temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); |
| 3095 | cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); |
| 3096 | temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, |
| 3097 | temp32a); |
| 3098 | temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3099 | temp32alen, temp32a, temp48); |
| 3100 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, |
| 3101 | temp48, finother); |
| 3102 | finswap = finnow; finnow = finother; finother = finswap; |
| 3103 | |
| 3104 | |
| 3105 | temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, |
| 3106 | temp32a); |
| 3107 | cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); |
| 3108 | temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, |
| 3109 | temp16a); |
| 3110 | temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, |
| 3111 | temp16b); |
| 3112 | temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, |
| 3113 | temp16blen, temp16b, temp32b); |
| 3114 | temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3115 | temp32blen, temp32b, temp64); |
| 3116 | finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, |
| 3117 | temp64, finother); |
| 3118 | finswap = finnow; finnow = finother; finother = finswap; |
| 3119 | } |
| 3120 | } |
| 3121 | |
| 3122 | return finnow[finlength - 1]; |
| 3123 | } |
| 3124 | |
| 3125 | REAL incircle(REAL *pa, REAL *pb, REAL *pc, REAL *pd) |
| 3126 | { |
| 3127 | REAL adx, bdx, cdx, ady, bdy, cdy; |
| 3128 | REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; |
| 3129 | REAL alift, blift, clift; |
| 3130 | REAL det; |
| 3131 | REAL permanent, errbound; |
| 3132 | |
| 3133 | adx = pa[0] - pd[0]; |
| 3134 | bdx = pb[0] - pd[0]; |
| 3135 | cdx = pc[0] - pd[0]; |
| 3136 | ady = pa[1] - pd[1]; |
| 3137 | bdy = pb[1] - pd[1]; |
| 3138 | cdy = pc[1] - pd[1]; |
| 3139 | |
| 3140 | bdxcdy = bdx * cdy; |
| 3141 | cdxbdy = cdx * bdy; |
| 3142 | alift = adx * adx + ady * ady; |
| 3143 | |
| 3144 | cdxady = cdx * ady; |
| 3145 | adxcdy = adx * cdy; |
| 3146 | blift = bdx * bdx + bdy * bdy; |
| 3147 | |
| 3148 | adxbdy = adx * bdy; |
| 3149 | bdxady = bdx * ady; |
| 3150 | clift = cdx * cdx + cdy * cdy; |
| 3151 | |
| 3152 | det = alift * (bdxcdy - cdxbdy) |
| 3153 | + blift * (cdxady - adxcdy) |
| 3154 | + clift * (adxbdy - bdxady); |
| 3155 | |
| 3156 | permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift |
| 3157 | + (Absolute(cdxady) + Absolute(adxcdy)) * blift |
| 3158 | + (Absolute(adxbdy) + Absolute(bdxady)) * clift; |
| 3159 | errbound = iccerrboundA * permanent; |
| 3160 | if ((det > errbound) || (-det > errbound)) { |
| 3161 | return det; |
| 3162 | } |
| 3163 | |
| 3164 | return incircleadapt(pa, pb, pc, pd, permanent); |
| 3165 | } |
| 3166 | |
| 3167 | /*****************************************************************************/ |
| 3168 | /* */ |
| 3169 | /* inspherefast() Approximate 3D insphere test. Nonrobust. */ |
| 3170 | /* insphereexact() Exact 3D insphere test. Robust. */ |
| 3171 | /* insphereslow() Another exact 3D insphere test. Robust. */ |
| 3172 | /* insphere() Adaptive exact 3D insphere test. Robust. */ |
| 3173 | /* */ |
| 3174 | /* Return a positive value if the point pe lies inside the */ |
| 3175 | /* sphere passing through pa, pb, pc, and pd; a negative value */ |
| 3176 | /* if it lies outside; and zero if the five points are */ |
| 3177 | /* cospherical. The points pa, pb, pc, and pd must be ordered */ |
| 3178 | /* so that they have a positive orientation (as defined by */ |
| 3179 | /* orient3d()), or the sign of the result will be reversed. */ |
| 3180 | /* */ |
| 3181 | /* Only the first and last routine should be used; the middle two are for */ |
| 3182 | /* timings. */ |
| 3183 | /* */ |
| 3184 | /* The last three use exact arithmetic to ensure a correct answer. The */ |
| 3185 | /* result returned is the determinant of a matrix. In insphere() only, */ |
| 3186 | /* this determinant is computed adaptively, in the sense that exact */ |
| 3187 | /* arithmetic is used only to the degree it is needed to ensure that the */ |
| 3188 | /* returned value has the correct sign. Hence, insphere() is usually quite */ |
| 3189 | /* fast, but will run more slowly when the input points are cospherical or */ |
| 3190 | /* nearly so. */ |
| 3191 | /* */ |
| 3192 | /*****************************************************************************/ |
| 3193 | |
| 3194 | REAL inspherefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) |
| 3195 | { |
| 3196 | REAL aex, bex, cex, dex; |
| 3197 | REAL aey, bey, cey, dey; |
| 3198 | REAL aez, bez, cez, dez; |
| 3199 | REAL alift, blift, clift, dlift; |
| 3200 | REAL ab, bc, cd, da, ac, bd; |
| 3201 | REAL abc, bcd, cda, dab; |
| 3202 | |
| 3203 | aex = pa[0] - pe[0]; |
| 3204 | bex = pb[0] - pe[0]; |
| 3205 | cex = pc[0] - pe[0]; |
| 3206 | dex = pd[0] - pe[0]; |
| 3207 | aey = pa[1] - pe[1]; |
| 3208 | bey = pb[1] - pe[1]; |
| 3209 | cey = pc[1] - pe[1]; |
| 3210 | dey = pd[1] - pe[1]; |
| 3211 | aez = pa[2] - pe[2]; |
| 3212 | bez = pb[2] - pe[2]; |
| 3213 | cez = pc[2] - pe[2]; |
| 3214 | dez = pd[2] - pe[2]; |
| 3215 | |
| 3216 | ab = aex * bey - bex * aey; |
| 3217 | bc = bex * cey - cex * bey; |
| 3218 | cd = cex * dey - dex * cey; |
| 3219 | da = dex * aey - aex * dey; |
| 3220 | |
| 3221 | ac = aex * cey - cex * aey; |
| 3222 | bd = bex * dey - dex * bey; |
| 3223 | |
| 3224 | abc = aez * bc - bez * ac + cez * ab; |
| 3225 | bcd = bez * cd - cez * bd + dez * bc; |
| 3226 | cda = cez * da + dez * ac + aez * cd; |
| 3227 | dab = dez * ab + aez * bd + bez * da; |
| 3228 | |
| 3229 | alift = aex * aex + aey * aey + aez * aez; |
| 3230 | blift = bex * bex + bey * bey + bez * bez; |
| 3231 | clift = cex * cex + cey * cey + cez * cez; |
| 3232 | dlift = dex * dex + dey * dey + dez * dez; |
| 3233 | |
| 3234 | return (dlift * abc - clift * dab) + (blift * cda - alift * bcd); |
| 3235 | } |
| 3236 | |
| 3237 | REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) |
| 3238 | { |
| 3239 | INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; |
| 3240 | INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; |
| 3241 | INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; |
| 3242 | INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; |
| 3243 | REAL axby0, bxcy0, cxdy0, dxey0, exay0; |
| 3244 | REAL bxay0, cxby0, dxcy0, exdy0, axey0; |
| 3245 | REAL axcy0, bxdy0, cxey0, dxay0, exby0; |
| 3246 | REAL cxay0, dxby0, excy0, axdy0, bxey0; |
| 3247 | REAL ab[4], bc[4], cd[4], de[4], ea[4]; |
| 3248 | REAL ac[4], bd[4], ce[4], da[4], eb[4]; |
| 3249 | REAL temp8a[8], temp8b[8], temp16[16]; |
| 3250 | int temp8alen, temp8blen, temp16len; |
| 3251 | REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; |
| 3252 | REAL abd[24], bce[24], cda[24], deb[24], eac[24]; |
| 3253 | int abclen, bcdlen, cdelen, dealen, eablen; |
| 3254 | int abdlen, bcelen, cdalen, deblen, eaclen; |
| 3255 | REAL temp48a[48], temp48b[48]; |
| 3256 | int temp48alen, temp48blen; |
| 3257 | REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; |
| 3258 | int abcdlen, bcdelen, cdealen, deablen, eabclen; |
| 3259 | REAL temp192[192]; |
| 3260 | REAL det384x[384], det384y[384], det384z[384]; |
| 3261 | int xlen, ylen, zlen; |
| 3262 | REAL detxy[768]; |
| 3263 | int xylen; |
| 3264 | REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; |
| 3265 | int alen, blen, clen, dlen, elen; |
| 3266 | REAL abdet[2304], cddet[2304], cdedet[3456]; |
| 3267 | int ablen, cdlen; |
| 3268 | REAL deter[5760]; |
| 3269 | int deterlen; |
| 3270 | int i; |
| 3271 | |
| 3272 | INEXACT REAL bvirt; |
| 3273 | REAL avirt, bround, around; |
| 3274 | INEXACT REAL c; |
| 3275 | INEXACT REAL abig; |
| 3276 | REAL ahi, alo, bhi, blo; |
| 3277 | REAL err1, err2, err3; |
| 3278 | INEXACT REAL _i, _j; |
| 3279 | REAL _0; |
| 3280 | |
| 3281 | |
| 3282 | Two_Product(pa[0], pb[1], axby1, axby0); |
| 3283 | Two_Product(pb[0], pa[1], bxay1, bxay0); |
| 3284 | Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); |
| 3285 | |
| 3286 | Two_Product(pb[0], pc[1], bxcy1, bxcy0); |
| 3287 | Two_Product(pc[0], pb[1], cxby1, cxby0); |
| 3288 | Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); |
| 3289 | |
| 3290 | Two_Product(pc[0], pd[1], cxdy1, cxdy0); |
| 3291 | Two_Product(pd[0], pc[1], dxcy1, dxcy0); |
| 3292 | Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); |
| 3293 | |
| 3294 | Two_Product(pd[0], pe[1], dxey1, dxey0); |
| 3295 | Two_Product(pe[0], pd[1], exdy1, exdy0); |
| 3296 | Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); |
| 3297 | |
| 3298 | Two_Product(pe[0], pa[1], exay1, exay0); |
| 3299 | Two_Product(pa[0], pe[1], axey1, axey0); |
| 3300 | Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); |
| 3301 | |
| 3302 | Two_Product(pa[0], pc[1], axcy1, axcy0); |
| 3303 | Two_Product(pc[0], pa[1], cxay1, cxay0); |
| 3304 | Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); |
| 3305 | |
| 3306 | Two_Product(pb[0], pd[1], bxdy1, bxdy0); |
| 3307 | Two_Product(pd[0], pb[1], dxby1, dxby0); |
| 3308 | Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); |
| 3309 | |
| 3310 | Two_Product(pc[0], pe[1], cxey1, cxey0); |
| 3311 | Two_Product(pe[0], pc[1], excy1, excy0); |
| 3312 | Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); |
| 3313 | |
| 3314 | Two_Product(pd[0], pa[1], dxay1, dxay0); |
| 3315 | Two_Product(pa[0], pd[1], axdy1, axdy0); |
| 3316 | Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); |
| 3317 | |
| 3318 | Two_Product(pe[0], pb[1], exby1, exby0); |
| 3319 | Two_Product(pb[0], pe[1], bxey1, bxey0); |
| 3320 | Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); |
| 3321 | |
| 3322 | temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); |
| 3323 | temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); |
| 3324 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3325 | temp16); |
| 3326 | temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); |
| 3327 | abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3328 | abc); |
| 3329 | |
| 3330 | temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); |
| 3331 | temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); |
| 3332 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3333 | temp16); |
| 3334 | temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); |
| 3335 | bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3336 | bcd); |
| 3337 | |
| 3338 | temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); |
| 3339 | temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); |
| 3340 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3341 | temp16); |
| 3342 | temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); |
| 3343 | cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3344 | cde); |
| 3345 | |
| 3346 | temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); |
| 3347 | temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); |
| 3348 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3349 | temp16); |
| 3350 | temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); |
| 3351 | dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3352 | dea); |
| 3353 | |
| 3354 | temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); |
| 3355 | temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); |
| 3356 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3357 | temp16); |
| 3358 | temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); |
| 3359 | eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3360 | eab); |
| 3361 | |
| 3362 | temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); |
| 3363 | temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); |
| 3364 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3365 | temp16); |
| 3366 | temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); |
| 3367 | abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3368 | abd); |
| 3369 | |
| 3370 | temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); |
| 3371 | temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); |
| 3372 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3373 | temp16); |
| 3374 | temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); |
| 3375 | bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3376 | bce); |
| 3377 | |
| 3378 | temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); |
| 3379 | temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); |
| 3380 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3381 | temp16); |
| 3382 | temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); |
| 3383 | cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3384 | cda); |
| 3385 | |
| 3386 | temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); |
| 3387 | temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); |
| 3388 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3389 | temp16); |
| 3390 | temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); |
| 3391 | deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3392 | deb); |
| 3393 | |
| 3394 | temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); |
| 3395 | temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); |
| 3396 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 3397 | temp16); |
| 3398 | temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); |
| 3399 | eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 3400 | eac); |
| 3401 | |
| 3402 | temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); |
| 3403 | temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); |
| 3404 | for (i = 0; i < temp48blen; i++) { |
| 3405 | temp48b[i] = -temp48b[i]; |
| 3406 | } |
| 3407 | bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 3408 | temp48blen, temp48b, bcde); |
| 3409 | xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); |
| 3410 | xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); |
| 3411 | ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); |
| 3412 | ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); |
| 3413 | zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); |
| 3414 | zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); |
| 3415 | xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); |
| 3416 | alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); |
| 3417 | |
| 3418 | temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); |
| 3419 | temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); |
| 3420 | for (i = 0; i < temp48blen; i++) { |
| 3421 | temp48b[i] = -temp48b[i]; |
| 3422 | } |
| 3423 | cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 3424 | temp48blen, temp48b, cdea); |
| 3425 | xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); |
| 3426 | xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); |
| 3427 | ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); |
| 3428 | ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); |
| 3429 | zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); |
| 3430 | zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); |
| 3431 | xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); |
| 3432 | blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); |
| 3433 | |
| 3434 | temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); |
| 3435 | temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); |
| 3436 | for (i = 0; i < temp48blen; i++) { |
| 3437 | temp48b[i] = -temp48b[i]; |
| 3438 | } |
| 3439 | deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 3440 | temp48blen, temp48b, deab); |
| 3441 | xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); |
| 3442 | xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); |
| 3443 | ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); |
| 3444 | ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); |
| 3445 | zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); |
| 3446 | zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); |
| 3447 | xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); |
| 3448 | clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); |
| 3449 | |
| 3450 | temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); |
| 3451 | temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); |
| 3452 | for (i = 0; i < temp48blen; i++) { |
| 3453 | temp48b[i] = -temp48b[i]; |
| 3454 | } |
| 3455 | eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 3456 | temp48blen, temp48b, eabc); |
| 3457 | xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); |
| 3458 | xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); |
| 3459 | ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); |
| 3460 | ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); |
| 3461 | zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); |
| 3462 | zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); |
| 3463 | xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); |
| 3464 | dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); |
| 3465 | |
| 3466 | temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); |
| 3467 | temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); |
| 3468 | for (i = 0; i < temp48blen; i++) { |
| 3469 | temp48b[i] = -temp48b[i]; |
| 3470 | } |
| 3471 | abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 3472 | temp48blen, temp48b, abcd); |
| 3473 | xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); |
| 3474 | xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); |
| 3475 | ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); |
| 3476 | ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); |
| 3477 | zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); |
| 3478 | zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); |
| 3479 | xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); |
| 3480 | elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); |
| 3481 | |
| 3482 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 3483 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 3484 | cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); |
| 3485 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); |
| 3486 | |
| 3487 | return deter[deterlen - 1]; |
| 3488 | } |
| 3489 | |
| 3490 | REAL insphereslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) |
| 3491 | { |
| 3492 | INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; |
| 3493 | REAL aextail, bextail, cextail, dextail; |
| 3494 | REAL aeytail, beytail, ceytail, deytail; |
| 3495 | REAL aeztail, beztail, ceztail, deztail; |
| 3496 | REAL negate, negatetail; |
| 3497 | INEXACT REAL axby7, bxcy7, cxdy7, dxay7, axcy7, bxdy7; |
| 3498 | INEXACT REAL bxay7, cxby7, dxcy7, axdy7, cxay7, dxby7; |
| 3499 | REAL axby[8], bxcy[8], cxdy[8], dxay[8], axcy[8], bxdy[8]; |
| 3500 | REAL bxay[8], cxby[8], dxcy[8], axdy[8], cxay[8], dxby[8]; |
| 3501 | REAL ab[16], bc[16], cd[16], da[16], ac[16], bd[16]; |
| 3502 | int ablen, bclen, cdlen, dalen, aclen, bdlen; |
| 3503 | REAL temp32a[32], temp32b[32], temp64a[64], temp64b[64], temp64c[64]; |
| 3504 | int temp32alen, temp32blen, temp64alen, temp64blen, temp64clen; |
| 3505 | REAL temp128[128], temp192[192]; |
| 3506 | int temp128len, temp192len; |
| 3507 | REAL detx[384], detxx[768], detxt[384], detxxt[768], detxtxt[768]; |
| 3508 | int xlen, xxlen, xtlen, xxtlen, xtxtlen; |
| 3509 | REAL x1[1536], x2[2304]; |
| 3510 | int x1len, x2len; |
| 3511 | REAL dety[384], detyy[768], detyt[384], detyyt[768], detytyt[768]; |
| 3512 | int ylen, yylen, ytlen, yytlen, ytytlen; |
| 3513 | REAL y1[1536], y2[2304]; |
| 3514 | int y1len, y2len; |
| 3515 | REAL detz[384], detzz[768], detzt[384], detzzt[768], detztzt[768]; |
| 3516 | int zlen, zzlen, ztlen, zztlen, ztztlen; |
| 3517 | REAL z1[1536], z2[2304]; |
| 3518 | int z1len, z2len; |
| 3519 | REAL detxy[4608]; |
| 3520 | int xylen; |
| 3521 | REAL adet[6912], bdet[6912], cdet[6912], ddet[6912]; |
| 3522 | int alen, blen, clen, dlen; |
| 3523 | REAL abdet[13824], cddet[13824], deter[27648]; |
| 3524 | int deterlen; |
| 3525 | int i; |
| 3526 | |
| 3527 | INEXACT REAL bvirt; |
| 3528 | REAL avirt, bround, around; |
| 3529 | INEXACT REAL c; |
| 3530 | INEXACT REAL abig; |
| 3531 | REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; |
| 3532 | REAL err1, err2, err3; |
| 3533 | INEXACT REAL _i, _j, _k, _l, _m, _n; |
| 3534 | REAL _0, _1, _2; |
| 3535 | |
| 3536 | Two_Diff(pa[0], pe[0], aex, aextail); |
| 3537 | Two_Diff(pa[1], pe[1], aey, aeytail); |
| 3538 | Two_Diff(pa[2], pe[2], aez, aeztail); |
| 3539 | Two_Diff(pb[0], pe[0], bex, bextail); |
| 3540 | Two_Diff(pb[1], pe[1], bey, beytail); |
| 3541 | Two_Diff(pb[2], pe[2], bez, beztail); |
| 3542 | Two_Diff(pc[0], pe[0], cex, cextail); |
| 3543 | Two_Diff(pc[1], pe[1], cey, ceytail); |
| 3544 | Two_Diff(pc[2], pe[2], cez, ceztail); |
| 3545 | Two_Diff(pd[0], pe[0], dex, dextail); |
| 3546 | Two_Diff(pd[1], pe[1], dey, deytail); |
| 3547 | Two_Diff(pd[2], pe[2], dez, deztail); |
| 3548 | |
| 3549 | Two_Two_Product(aex, aextail, bey, beytail, |
| 3550 | axby7, axby[6], axby[5], axby[4], |
| 3551 | axby[3], axby[2], axby[1], axby[0]); |
| 3552 | axby[7] = axby7; |
| 3553 | negate = -aey; |
| 3554 | negatetail = -aeytail; |
| 3555 | Two_Two_Product(bex, bextail, negate, negatetail, |
| 3556 | bxay7, bxay[6], bxay[5], bxay[4], |
| 3557 | bxay[3], bxay[2], bxay[1], bxay[0]); |
| 3558 | bxay[7] = bxay7; |
| 3559 | ablen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, ab); |
| 3560 | Two_Two_Product(bex, bextail, cey, ceytail, |
| 3561 | bxcy7, bxcy[6], bxcy[5], bxcy[4], |
| 3562 | bxcy[3], bxcy[2], bxcy[1], bxcy[0]); |
| 3563 | bxcy[7] = bxcy7; |
| 3564 | negate = -bey; |
| 3565 | negatetail = -beytail; |
| 3566 | Two_Two_Product(cex, cextail, negate, negatetail, |
| 3567 | cxby7, cxby[6], cxby[5], cxby[4], |
| 3568 | cxby[3], cxby[2], cxby[1], cxby[0]); |
| 3569 | cxby[7] = cxby7; |
| 3570 | bclen = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, bc); |
| 3571 | Two_Two_Product(cex, cextail, dey, deytail, |
| 3572 | cxdy7, cxdy[6], cxdy[5], cxdy[4], |
| 3573 | cxdy[3], cxdy[2], cxdy[1], cxdy[0]); |
| 3574 | cxdy[7] = cxdy7; |
| 3575 | negate = -cey; |
| 3576 | negatetail = -ceytail; |
| 3577 | Two_Two_Product(dex, dextail, negate, negatetail, |
| 3578 | dxcy7, dxcy[6], dxcy[5], dxcy[4], |
| 3579 | dxcy[3], dxcy[2], dxcy[1], dxcy[0]); |
| 3580 | dxcy[7] = dxcy7; |
| 3581 | cdlen = fast_expansion_sum_zeroelim(8, cxdy, 8, dxcy, cd); |
| 3582 | Two_Two_Product(dex, dextail, aey, aeytail, |
| 3583 | dxay7, dxay[6], dxay[5], dxay[4], |
| 3584 | dxay[3], dxay[2], dxay[1], dxay[0]); |
| 3585 | dxay[7] = dxay7; |
| 3586 | negate = -dey; |
| 3587 | negatetail = -deytail; |
| 3588 | Two_Two_Product(aex, aextail, negate, negatetail, |
| 3589 | axdy7, axdy[6], axdy[5], axdy[4], |
| 3590 | axdy[3], axdy[2], axdy[1], axdy[0]); |
| 3591 | axdy[7] = axdy7; |
| 3592 | dalen = fast_expansion_sum_zeroelim(8, dxay, 8, axdy, da); |
| 3593 | Two_Two_Product(aex, aextail, cey, ceytail, |
| 3594 | axcy7, axcy[6], axcy[5], axcy[4], |
| 3595 | axcy[3], axcy[2], axcy[1], axcy[0]); |
| 3596 | axcy[7] = axcy7; |
| 3597 | negate = -aey; |
| 3598 | negatetail = -aeytail; |
| 3599 | Two_Two_Product(cex, cextail, negate, negatetail, |
| 3600 | cxay7, cxay[6], cxay[5], cxay[4], |
| 3601 | cxay[3], cxay[2], cxay[1], cxay[0]); |
| 3602 | cxay[7] = cxay7; |
| 3603 | aclen = fast_expansion_sum_zeroelim(8, axcy, 8, cxay, ac); |
| 3604 | Two_Two_Product(bex, bextail, dey, deytail, |
| 3605 | bxdy7, bxdy[6], bxdy[5], bxdy[4], |
| 3606 | bxdy[3], bxdy[2], bxdy[1], bxdy[0]); |
| 3607 | bxdy[7] = bxdy7; |
| 3608 | negate = -bey; |
| 3609 | negatetail = -beytail; |
| 3610 | Two_Two_Product(dex, dextail, negate, negatetail, |
| 3611 | dxby7, dxby[6], dxby[5], dxby[4], |
| 3612 | dxby[3], dxby[2], dxby[1], dxby[0]); |
| 3613 | dxby[7] = dxby7; |
| 3614 | bdlen = fast_expansion_sum_zeroelim(8, bxdy, 8, dxby, bd); |
| 3615 | |
| 3616 | temp32alen = scale_expansion_zeroelim(cdlen, cd, -bez, temp32a); |
| 3617 | temp32blen = scale_expansion_zeroelim(cdlen, cd, -beztail, temp32b); |
| 3618 | temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3619 | temp32blen, temp32b, temp64a); |
| 3620 | temp32alen = scale_expansion_zeroelim(bdlen, bd, cez, temp32a); |
| 3621 | temp32blen = scale_expansion_zeroelim(bdlen, bd, ceztail, temp32b); |
| 3622 | temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3623 | temp32blen, temp32b, temp64b); |
| 3624 | temp32alen = scale_expansion_zeroelim(bclen, bc, -dez, temp32a); |
| 3625 | temp32blen = scale_expansion_zeroelim(bclen, bc, -deztail, temp32b); |
| 3626 | temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3627 | temp32blen, temp32b, temp64c); |
| 3628 | temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, |
| 3629 | temp64blen, temp64b, temp128); |
| 3630 | temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, |
| 3631 | temp128len, temp128, temp192); |
| 3632 | xlen = scale_expansion_zeroelim(temp192len, temp192, aex, detx); |
| 3633 | xxlen = scale_expansion_zeroelim(xlen, detx, aex, detxx); |
| 3634 | xtlen = scale_expansion_zeroelim(temp192len, temp192, aextail, detxt); |
| 3635 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, aex, detxxt); |
| 3636 | for (i = 0; i < xxtlen; i++) { |
| 3637 | detxxt[i] *= 2.0; |
| 3638 | } |
| 3639 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, aextail, detxtxt); |
| 3640 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 3641 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 3642 | ylen = scale_expansion_zeroelim(temp192len, temp192, aey, dety); |
| 3643 | yylen = scale_expansion_zeroelim(ylen, dety, aey, detyy); |
| 3644 | ytlen = scale_expansion_zeroelim(temp192len, temp192, aeytail, detyt); |
| 3645 | yytlen = scale_expansion_zeroelim(ytlen, detyt, aey, detyyt); |
| 3646 | for (i = 0; i < yytlen; i++) { |
| 3647 | detyyt[i] *= 2.0; |
| 3648 | } |
| 3649 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, aeytail, detytyt); |
| 3650 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 3651 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 3652 | zlen = scale_expansion_zeroelim(temp192len, temp192, aez, detz); |
| 3653 | zzlen = scale_expansion_zeroelim(zlen, detz, aez, detzz); |
| 3654 | ztlen = scale_expansion_zeroelim(temp192len, temp192, aeztail, detzt); |
| 3655 | zztlen = scale_expansion_zeroelim(ztlen, detzt, aez, detzzt); |
| 3656 | for (i = 0; i < zztlen; i++) { |
| 3657 | detzzt[i] *= 2.0; |
| 3658 | } |
| 3659 | ztztlen = scale_expansion_zeroelim(ztlen, detzt, aeztail, detztzt); |
| 3660 | z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); |
| 3661 | z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); |
| 3662 | xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); |
| 3663 | alen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, adet); |
| 3664 | |
| 3665 | temp32alen = scale_expansion_zeroelim(dalen, da, cez, temp32a); |
| 3666 | temp32blen = scale_expansion_zeroelim(dalen, da, ceztail, temp32b); |
| 3667 | temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3668 | temp32blen, temp32b, temp64a); |
| 3669 | temp32alen = scale_expansion_zeroelim(aclen, ac, dez, temp32a); |
| 3670 | temp32blen = scale_expansion_zeroelim(aclen, ac, deztail, temp32b); |
| 3671 | temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3672 | temp32blen, temp32b, temp64b); |
| 3673 | temp32alen = scale_expansion_zeroelim(cdlen, cd, aez, temp32a); |
| 3674 | temp32blen = scale_expansion_zeroelim(cdlen, cd, aeztail, temp32b); |
| 3675 | temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3676 | temp32blen, temp32b, temp64c); |
| 3677 | temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, |
| 3678 | temp64blen, temp64b, temp128); |
| 3679 | temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, |
| 3680 | temp128len, temp128, temp192); |
| 3681 | xlen = scale_expansion_zeroelim(temp192len, temp192, bex, detx); |
| 3682 | xxlen = scale_expansion_zeroelim(xlen, detx, bex, detxx); |
| 3683 | xtlen = scale_expansion_zeroelim(temp192len, temp192, bextail, detxt); |
| 3684 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, bex, detxxt); |
| 3685 | for (i = 0; i < xxtlen; i++) { |
| 3686 | detxxt[i] *= 2.0; |
| 3687 | } |
| 3688 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bextail, detxtxt); |
| 3689 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 3690 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 3691 | ylen = scale_expansion_zeroelim(temp192len, temp192, bey, dety); |
| 3692 | yylen = scale_expansion_zeroelim(ylen, dety, bey, detyy); |
| 3693 | ytlen = scale_expansion_zeroelim(temp192len, temp192, beytail, detyt); |
| 3694 | yytlen = scale_expansion_zeroelim(ytlen, detyt, bey, detyyt); |
| 3695 | for (i = 0; i < yytlen; i++) { |
| 3696 | detyyt[i] *= 2.0; |
| 3697 | } |
| 3698 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, beytail, detytyt); |
| 3699 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 3700 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 3701 | zlen = scale_expansion_zeroelim(temp192len, temp192, bez, detz); |
| 3702 | zzlen = scale_expansion_zeroelim(zlen, detz, bez, detzz); |
| 3703 | ztlen = scale_expansion_zeroelim(temp192len, temp192, beztail, detzt); |
| 3704 | zztlen = scale_expansion_zeroelim(ztlen, detzt, bez, detzzt); |
| 3705 | for (i = 0; i < zztlen; i++) { |
| 3706 | detzzt[i] *= 2.0; |
| 3707 | } |
| 3708 | ztztlen = scale_expansion_zeroelim(ztlen, detzt, beztail, detztzt); |
| 3709 | z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); |
| 3710 | z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); |
| 3711 | xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); |
| 3712 | blen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, bdet); |
| 3713 | |
| 3714 | temp32alen = scale_expansion_zeroelim(ablen, ab, -dez, temp32a); |
| 3715 | temp32blen = scale_expansion_zeroelim(ablen, ab, -deztail, temp32b); |
| 3716 | temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3717 | temp32blen, temp32b, temp64a); |
| 3718 | temp32alen = scale_expansion_zeroelim(bdlen, bd, -aez, temp32a); |
| 3719 | temp32blen = scale_expansion_zeroelim(bdlen, bd, -aeztail, temp32b); |
| 3720 | temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3721 | temp32blen, temp32b, temp64b); |
| 3722 | temp32alen = scale_expansion_zeroelim(dalen, da, -bez, temp32a); |
| 3723 | temp32blen = scale_expansion_zeroelim(dalen, da, -beztail, temp32b); |
| 3724 | temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3725 | temp32blen, temp32b, temp64c); |
| 3726 | temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, |
| 3727 | temp64blen, temp64b, temp128); |
| 3728 | temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, |
| 3729 | temp128len, temp128, temp192); |
| 3730 | xlen = scale_expansion_zeroelim(temp192len, temp192, cex, detx); |
| 3731 | xxlen = scale_expansion_zeroelim(xlen, detx, cex, detxx); |
| 3732 | xtlen = scale_expansion_zeroelim(temp192len, temp192, cextail, detxt); |
| 3733 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, cex, detxxt); |
| 3734 | for (i = 0; i < xxtlen; i++) { |
| 3735 | detxxt[i] *= 2.0; |
| 3736 | } |
| 3737 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cextail, detxtxt); |
| 3738 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 3739 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 3740 | ylen = scale_expansion_zeroelim(temp192len, temp192, cey, dety); |
| 3741 | yylen = scale_expansion_zeroelim(ylen, dety, cey, detyy); |
| 3742 | ytlen = scale_expansion_zeroelim(temp192len, temp192, ceytail, detyt); |
| 3743 | yytlen = scale_expansion_zeroelim(ytlen, detyt, cey, detyyt); |
| 3744 | for (i = 0; i < yytlen; i++) { |
| 3745 | detyyt[i] *= 2.0; |
| 3746 | } |
| 3747 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, ceytail, detytyt); |
| 3748 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 3749 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 3750 | zlen = scale_expansion_zeroelim(temp192len, temp192, cez, detz); |
| 3751 | zzlen = scale_expansion_zeroelim(zlen, detz, cez, detzz); |
| 3752 | ztlen = scale_expansion_zeroelim(temp192len, temp192, ceztail, detzt); |
| 3753 | zztlen = scale_expansion_zeroelim(ztlen, detzt, cez, detzzt); |
| 3754 | for (i = 0; i < zztlen; i++) { |
| 3755 | detzzt[i] *= 2.0; |
| 3756 | } |
| 3757 | ztztlen = scale_expansion_zeroelim(ztlen, detzt, ceztail, detztzt); |
| 3758 | z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); |
| 3759 | z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); |
| 3760 | xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); |
| 3761 | clen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, cdet); |
| 3762 | |
| 3763 | temp32alen = scale_expansion_zeroelim(bclen, bc, aez, temp32a); |
| 3764 | temp32blen = scale_expansion_zeroelim(bclen, bc, aeztail, temp32b); |
| 3765 | temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3766 | temp32blen, temp32b, temp64a); |
| 3767 | temp32alen = scale_expansion_zeroelim(aclen, ac, -bez, temp32a); |
| 3768 | temp32blen = scale_expansion_zeroelim(aclen, ac, -beztail, temp32b); |
| 3769 | temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3770 | temp32blen, temp32b, temp64b); |
| 3771 | temp32alen = scale_expansion_zeroelim(ablen, ab, cez, temp32a); |
| 3772 | temp32blen = scale_expansion_zeroelim(ablen, ab, ceztail, temp32b); |
| 3773 | temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, |
| 3774 | temp32blen, temp32b, temp64c); |
| 3775 | temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, |
| 3776 | temp64blen, temp64b, temp128); |
| 3777 | temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, |
| 3778 | temp128len, temp128, temp192); |
| 3779 | xlen = scale_expansion_zeroelim(temp192len, temp192, dex, detx); |
| 3780 | xxlen = scale_expansion_zeroelim(xlen, detx, dex, detxx); |
| 3781 | xtlen = scale_expansion_zeroelim(temp192len, temp192, dextail, detxt); |
| 3782 | xxtlen = scale_expansion_zeroelim(xtlen, detxt, dex, detxxt); |
| 3783 | for (i = 0; i < xxtlen; i++) { |
| 3784 | detxxt[i] *= 2.0; |
| 3785 | } |
| 3786 | xtxtlen = scale_expansion_zeroelim(xtlen, detxt, dextail, detxtxt); |
| 3787 | x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); |
| 3788 | x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); |
| 3789 | ylen = scale_expansion_zeroelim(temp192len, temp192, dey, dety); |
| 3790 | yylen = scale_expansion_zeroelim(ylen, dety, dey, detyy); |
| 3791 | ytlen = scale_expansion_zeroelim(temp192len, temp192, deytail, detyt); |
| 3792 | yytlen = scale_expansion_zeroelim(ytlen, detyt, dey, detyyt); |
| 3793 | for (i = 0; i < yytlen; i++) { |
| 3794 | detyyt[i] *= 2.0; |
| 3795 | } |
| 3796 | ytytlen = scale_expansion_zeroelim(ytlen, detyt, deytail, detytyt); |
| 3797 | y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); |
| 3798 | y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); |
| 3799 | zlen = scale_expansion_zeroelim(temp192len, temp192, dez, detz); |
| 3800 | zzlen = scale_expansion_zeroelim(zlen, detz, dez, detzz); |
| 3801 | ztlen = scale_expansion_zeroelim(temp192len, temp192, deztail, detzt); |
| 3802 | zztlen = scale_expansion_zeroelim(ztlen, detzt, dez, detzzt); |
| 3803 | for (i = 0; i < zztlen; i++) { |
| 3804 | detzzt[i] *= 2.0; |
| 3805 | } |
| 3806 | ztztlen = scale_expansion_zeroelim(ztlen, detzt, deztail, detztzt); |
| 3807 | z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); |
| 3808 | z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); |
| 3809 | xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); |
| 3810 | dlen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, ddet); |
| 3811 | |
| 3812 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 3813 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 3814 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); |
| 3815 | |
| 3816 | return deter[deterlen - 1]; |
| 3817 | } |
| 3818 | |
| 3819 | REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe, |
| 3820 | REAL permanent) |
| 3821 | { |
| 3822 | INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; |
| 3823 | REAL det, errbound; |
| 3824 | |
| 3825 | INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; |
| 3826 | INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; |
| 3827 | INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; |
| 3828 | REAL aexbey0, bexaey0, bexcey0, cexbey0; |
| 3829 | REAL cexdey0, dexcey0, dexaey0, aexdey0; |
| 3830 | REAL aexcey0, cexaey0, bexdey0, dexbey0; |
| 3831 | REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; |
| 3832 | INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; |
| 3833 | REAL abeps, bceps, cdeps, daeps, aceps, bdeps; |
| 3834 | REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; |
| 3835 | int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len; |
| 3836 | REAL xdet[96], ydet[96], zdet[96], xydet[192]; |
| 3837 | int xlen, ylen, zlen, xylen; |
| 3838 | REAL adet[288], bdet[288], cdet[288], ddet[288]; |
| 3839 | int alen, blen, clen, dlen; |
| 3840 | REAL abdet[576], cddet[576]; |
| 3841 | int ablen, cdlen; |
| 3842 | REAL fin1[1152]; |
| 3843 | int finlength; |
| 3844 | |
| 3845 | REAL aextail, bextail, cextail, dextail; |
| 3846 | REAL aeytail, beytail, ceytail, deytail; |
| 3847 | REAL aeztail, beztail, ceztail, deztail; |
| 3848 | |
| 3849 | INEXACT REAL bvirt; |
| 3850 | REAL avirt, bround, around; |
| 3851 | INEXACT REAL c; |
| 3852 | INEXACT REAL abig; |
| 3853 | REAL ahi, alo, bhi, blo; |
| 3854 | REAL err1, err2, err3; |
| 3855 | INEXACT REAL _i, _j; |
| 3856 | REAL _0; |
| 3857 | |
| 3858 | |
| 3859 | aex = (REAL) (pa[0] - pe[0]); |
| 3860 | bex = (REAL) (pb[0] - pe[0]); |
| 3861 | cex = (REAL) (pc[0] - pe[0]); |
| 3862 | dex = (REAL) (pd[0] - pe[0]); |
| 3863 | aey = (REAL) (pa[1] - pe[1]); |
| 3864 | bey = (REAL) (pb[1] - pe[1]); |
| 3865 | cey = (REAL) (pc[1] - pe[1]); |
| 3866 | dey = (REAL) (pd[1] - pe[1]); |
| 3867 | aez = (REAL) (pa[2] - pe[2]); |
| 3868 | bez = (REAL) (pb[2] - pe[2]); |
| 3869 | cez = (REAL) (pc[2] - pe[2]); |
| 3870 | dez = (REAL) (pd[2] - pe[2]); |
| 3871 | |
| 3872 | Two_Product(aex, bey, aexbey1, aexbey0); |
| 3873 | Two_Product(bex, aey, bexaey1, bexaey0); |
| 3874 | Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); |
| 3875 | ab[3] = ab3; |
| 3876 | |
| 3877 | Two_Product(bex, cey, bexcey1, bexcey0); |
| 3878 | Two_Product(cex, bey, cexbey1, cexbey0); |
| 3879 | Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); |
| 3880 | bc[3] = bc3; |
| 3881 | |
| 3882 | Two_Product(cex, dey, cexdey1, cexdey0); |
| 3883 | Two_Product(dex, cey, dexcey1, dexcey0); |
| 3884 | Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); |
| 3885 | cd[3] = cd3; |
| 3886 | |
| 3887 | Two_Product(dex, aey, dexaey1, dexaey0); |
| 3888 | Two_Product(aex, dey, aexdey1, aexdey0); |
| 3889 | Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); |
| 3890 | da[3] = da3; |
| 3891 | |
| 3892 | Two_Product(aex, cey, aexcey1, aexcey0); |
| 3893 | Two_Product(cex, aey, cexaey1, cexaey0); |
| 3894 | Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); |
| 3895 | ac[3] = ac3; |
| 3896 | |
| 3897 | Two_Product(bex, dey, bexdey1, bexdey0); |
| 3898 | Two_Product(dex, bey, dexbey1, dexbey0); |
| 3899 | Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); |
| 3900 | bd[3] = bd3; |
| 3901 | |
| 3902 | temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); |
| 3903 | temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); |
| 3904 | temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); |
| 3905 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 3906 | temp8blen, temp8b, temp16); |
| 3907 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 3908 | temp16len, temp16, temp24); |
| 3909 | temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); |
| 3910 | xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); |
| 3911 | temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); |
| 3912 | ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); |
| 3913 | temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); |
| 3914 | zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); |
| 3915 | xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); |
| 3916 | alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); |
| 3917 | |
| 3918 | temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); |
| 3919 | temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); |
| 3920 | temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); |
| 3921 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 3922 | temp8blen, temp8b, temp16); |
| 3923 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 3924 | temp16len, temp16, temp24); |
| 3925 | temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); |
| 3926 | xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); |
| 3927 | temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); |
| 3928 | ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); |
| 3929 | temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); |
| 3930 | zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); |
| 3931 | xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); |
| 3932 | blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); |
| 3933 | |
| 3934 | temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); |
| 3935 | temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); |
| 3936 | temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); |
| 3937 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 3938 | temp8blen, temp8b, temp16); |
| 3939 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 3940 | temp16len, temp16, temp24); |
| 3941 | temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); |
| 3942 | xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); |
| 3943 | temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); |
| 3944 | ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); |
| 3945 | temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); |
| 3946 | zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); |
| 3947 | xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); |
| 3948 | clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); |
| 3949 | |
| 3950 | temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); |
| 3951 | temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); |
| 3952 | temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); |
| 3953 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 3954 | temp8blen, temp8b, temp16); |
| 3955 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 3956 | temp16len, temp16, temp24); |
| 3957 | temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); |
| 3958 | xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); |
| 3959 | temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); |
| 3960 | ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); |
| 3961 | temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); |
| 3962 | zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); |
| 3963 | xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); |
| 3964 | dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); |
| 3965 | |
| 3966 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 3967 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 3968 | finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); |
| 3969 | |
| 3970 | det = estimate(finlength, fin1); |
| 3971 | errbound = isperrboundB * permanent; |
| 3972 | if ((det >= errbound) || (-det >= errbound)) { |
| 3973 | return det; |
| 3974 | } |
| 3975 | |
| 3976 | Two_Diff_Tail(pa[0], pe[0], aex, aextail); |
| 3977 | Two_Diff_Tail(pa[1], pe[1], aey, aeytail); |
| 3978 | Two_Diff_Tail(pa[2], pe[2], aez, aeztail); |
| 3979 | Two_Diff_Tail(pb[0], pe[0], bex, bextail); |
| 3980 | Two_Diff_Tail(pb[1], pe[1], bey, beytail); |
| 3981 | Two_Diff_Tail(pb[2], pe[2], bez, beztail); |
| 3982 | Two_Diff_Tail(pc[0], pe[0], cex, cextail); |
| 3983 | Two_Diff_Tail(pc[1], pe[1], cey, ceytail); |
| 3984 | Two_Diff_Tail(pc[2], pe[2], cez, ceztail); |
| 3985 | Two_Diff_Tail(pd[0], pe[0], dex, dextail); |
| 3986 | Two_Diff_Tail(pd[1], pe[1], dey, deytail); |
| 3987 | Two_Diff_Tail(pd[2], pe[2], dez, deztail); |
| 3988 | if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) |
| 3989 | && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) |
| 3990 | && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) |
| 3991 | && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { |
| 3992 | return det; |
| 3993 | } |
| 3994 | |
| 3995 | errbound = isperrboundC * permanent + resulterrbound * Absolute(det); |
| 3996 | abeps = (aex * beytail + bey * aextail) |
| 3997 | - (aey * bextail + bex * aeytail); |
| 3998 | bceps = (bex * ceytail + cey * bextail) |
| 3999 | - (bey * cextail + cex * beytail); |
| 4000 | cdeps = (cex * deytail + dey * cextail) |
| 4001 | - (cey * dextail + dex * ceytail); |
| 4002 | daeps = (dex * aeytail + aey * dextail) |
| 4003 | - (dey * aextail + aex * deytail); |
| 4004 | aceps = (aex * ceytail + cey * aextail) |
| 4005 | - (aey * cextail + cex * aeytail); |
| 4006 | bdeps = (bex * deytail + dey * bextail) |
| 4007 | - (bey * dextail + dex * beytail); |
| 4008 | det += (((bex * bex + bey * bey + bez * bez) |
| 4009 | * ((cez * daeps + dez * aceps + aez * cdeps) |
| 4010 | + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) |
| 4011 | + (dex * dex + dey * dey + dez * dez) |
| 4012 | * ((aez * bceps - bez * aceps + cez * abeps) |
| 4013 | + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) |
| 4014 | - ((aex * aex + aey * aey + aez * aez) |
| 4015 | * ((bez * cdeps - cez * bdeps + dez * bceps) |
| 4016 | + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) |
| 4017 | + (cex * cex + cey * cey + cez * cez) |
| 4018 | * ((dez * abeps + aez * bdeps + bez * daeps) |
| 4019 | + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) |
| 4020 | + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) |
| 4021 | * (cez * da3 + dez * ac3 + aez * cd3) |
| 4022 | + (dex * dextail + dey * deytail + dez * deztail) |
| 4023 | * (aez * bc3 - bez * ac3 + cez * ab3)) |
| 4024 | - ((aex * aextail + aey * aeytail + aez * aeztail) |
| 4025 | * (bez * cd3 - cez * bd3 + dez * bc3) |
| 4026 | + (cex * cextail + cey * ceytail + cez * ceztail) |
| 4027 | * (dez * ab3 + aez * bd3 + bez * da3))); |
| 4028 | if ((det >= errbound) || (-det >= errbound)) { |
| 4029 | return det; |
| 4030 | } |
| 4031 | |
| 4032 | return insphereexact(pa, pb, pc, pd, pe); |
| 4033 | } |
| 4034 | |
| 4035 | #ifdef USE_CGAL_PREDICATES |
| 4036 | |
| 4037 | REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) |
| 4038 | { |
| 4039 | return (REAL) |
| 4040 | - cgal_pred_obj.side_of_oriented_sphere_3_object() |
| 4041 | (Point(pa[0], pa[1], pa[2]), |
| 4042 | Point(pb[0], pb[1], pb[2]), |
| 4043 | Point(pc[0], pc[1], pc[2]), |
| 4044 | Point(pd[0], pd[1], pd[2]), |
| 4045 | Point(pe[0], pe[1], pe[2])); |
| 4046 | } |
| 4047 | |
| 4048 | #else |
| 4049 | |
| 4050 | REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) |
| 4051 | { |
| 4052 | REAL aex, bex, cex, dex; |
| 4053 | REAL aey, bey, cey, dey; |
| 4054 | REAL aez, bez, cez, dez; |
| 4055 | REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; |
| 4056 | REAL aexcey, cexaey, bexdey, dexbey; |
| 4057 | REAL alift, blift, clift, dlift; |
| 4058 | REAL ab, bc, cd, da, ac, bd; |
| 4059 | REAL abc, bcd, cda, dab; |
| 4060 | REAL det; |
| 4061 | |
| 4062 | |
| 4063 | aex = pa[0] - pe[0]; |
| 4064 | bex = pb[0] - pe[0]; |
| 4065 | cex = pc[0] - pe[0]; |
| 4066 | dex = pd[0] - pe[0]; |
| 4067 | aey = pa[1] - pe[1]; |
| 4068 | bey = pb[1] - pe[1]; |
| 4069 | cey = pc[1] - pe[1]; |
| 4070 | dey = pd[1] - pe[1]; |
| 4071 | aez = pa[2] - pe[2]; |
| 4072 | bez = pb[2] - pe[2]; |
| 4073 | cez = pc[2] - pe[2]; |
| 4074 | dez = pd[2] - pe[2]; |
| 4075 | |
| 4076 | aexbey = aex * bey; |
| 4077 | bexaey = bex * aey; |
| 4078 | ab = aexbey - bexaey; |
| 4079 | bexcey = bex * cey; |
| 4080 | cexbey = cex * bey; |
| 4081 | bc = bexcey - cexbey; |
| 4082 | cexdey = cex * dey; |
| 4083 | dexcey = dex * cey; |
| 4084 | cd = cexdey - dexcey; |
| 4085 | dexaey = dex * aey; |
| 4086 | aexdey = aex * dey; |
| 4087 | da = dexaey - aexdey; |
| 4088 | |
| 4089 | aexcey = aex * cey; |
| 4090 | cexaey = cex * aey; |
| 4091 | ac = aexcey - cexaey; |
| 4092 | bexdey = bex * dey; |
| 4093 | dexbey = dex * bey; |
| 4094 | bd = bexdey - dexbey; |
| 4095 | |
| 4096 | abc = aez * bc - bez * ac + cez * ab; |
| 4097 | bcd = bez * cd - cez * bd + dez * bc; |
| 4098 | cda = cez * da + dez * ac + aez * cd; |
| 4099 | dab = dez * ab + aez * bd + bez * da; |
| 4100 | |
| 4101 | alift = aex * aex + aey * aey + aez * aez; |
| 4102 | blift = bex * bex + bey * bey + bez * bez; |
| 4103 | clift = cex * cex + cey * cey + cez * cez; |
| 4104 | dlift = dex * dex + dey * dey + dez * dez; |
| 4105 | |
| 4106 | det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); |
| 4107 | |
| 4108 | if (_use_inexact_arith) { |
| 4109 | return det; |
| 4110 | } |
| 4111 | |
| 4112 | if (_use_static_filter) { |
| 4113 | if (fabs(det) > ispstaticfilter) return det; |
| 4114 | //if (det > ispstaticfilter) return det; |
| 4115 | //if (det < minus_ispstaticfilter) return det; |
| 4116 | |
| 4117 | } |
| 4118 | |
| 4119 | REAL aezplus, bezplus, cezplus, dezplus; |
| 4120 | REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; |
| 4121 | REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; |
| 4122 | REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; |
| 4123 | REAL permanent, errbound; |
| 4124 | |
| 4125 | aezplus = Absolute(aez); |
| 4126 | bezplus = Absolute(bez); |
| 4127 | cezplus = Absolute(cez); |
| 4128 | dezplus = Absolute(dez); |
| 4129 | aexbeyplus = Absolute(aexbey); |
| 4130 | bexaeyplus = Absolute(bexaey); |
| 4131 | bexceyplus = Absolute(bexcey); |
| 4132 | cexbeyplus = Absolute(cexbey); |
| 4133 | cexdeyplus = Absolute(cexdey); |
| 4134 | dexceyplus = Absolute(dexcey); |
| 4135 | dexaeyplus = Absolute(dexaey); |
| 4136 | aexdeyplus = Absolute(aexdey); |
| 4137 | aexceyplus = Absolute(aexcey); |
| 4138 | cexaeyplus = Absolute(cexaey); |
| 4139 | bexdeyplus = Absolute(bexdey); |
| 4140 | dexbeyplus = Absolute(dexbey); |
| 4141 | permanent = ((cexdeyplus + dexceyplus) * bezplus |
| 4142 | + (dexbeyplus + bexdeyplus) * cezplus |
| 4143 | + (bexceyplus + cexbeyplus) * dezplus) |
| 4144 | * alift |
| 4145 | + ((dexaeyplus + aexdeyplus) * cezplus |
| 4146 | + (aexceyplus + cexaeyplus) * dezplus |
| 4147 | + (cexdeyplus + dexceyplus) * aezplus) |
| 4148 | * blift |
| 4149 | + ((aexbeyplus + bexaeyplus) * dezplus |
| 4150 | + (bexdeyplus + dexbeyplus) * aezplus |
| 4151 | + (dexaeyplus + aexdeyplus) * bezplus) |
| 4152 | * clift |
| 4153 | + ((bexceyplus + cexbeyplus) * aezplus |
| 4154 | + (cexaeyplus + aexceyplus) * bezplus |
| 4155 | + (aexbeyplus + bexaeyplus) * cezplus) |
| 4156 | * dlift; |
| 4157 | errbound = isperrboundA * permanent; |
| 4158 | if ((det > errbound) || (-det > errbound)) { |
| 4159 | return det; |
| 4160 | } |
| 4161 | |
| 4162 | return insphereadapt(pa, pb, pc, pd, pe, permanent); |
| 4163 | } |
| 4164 | |
| 4165 | #endif // #ifdef USE_CGAL_PREDICATES |
| 4166 | |
| 4167 | /*****************************************************************************/ |
| 4168 | /* */ |
| 4169 | /* orient4d() Return a positive value if the point pe lies above the */ |
| 4170 | /* hyperplane passing through pa, pb, pc, and pd; "above" is */ |
| 4171 | /* defined in a manner best found by trial-and-error. Returns */ |
| 4172 | /* a negative value if pe lies below the hyperplane. Returns */ |
| 4173 | /* zero if the points are co-hyperplanar (not affinely */ |
| 4174 | /* independent). The result is also a rough approximation of */ |
| 4175 | /* 24 times the signed volume of the 4-simplex defined by the */ |
| 4176 | /* five points. */ |
| 4177 | /* */ |
| 4178 | /* Uses exact arithmetic if necessary to ensure a correct answer. The */ |
| 4179 | /* result returned is the determinant of a matrix. This determinant is */ |
| 4180 | /* computed adaptively, in the sense that exact arithmetic is used only to */ |
| 4181 | /* the degree it is needed to ensure that the returned value has the */ |
| 4182 | /* correct sign. Hence, orient4d() is usually quite fast, but will run */ |
| 4183 | /* more slowly when the input points are hyper-coplanar or nearly so. */ |
| 4184 | /* */ |
| 4185 | /* See my Robust Predicates paper for details. */ |
| 4186 | /* */ |
| 4187 | /*****************************************************************************/ |
| 4188 | |
| 4189 | REAL orient4dexact(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* pe, |
| 4190 | REAL aheight, REAL bheight, REAL cheight, REAL dheight, |
| 4191 | REAL eheight) |
| 4192 | { |
| 4193 | INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; |
| 4194 | INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; |
| 4195 | INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; |
| 4196 | INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; |
| 4197 | REAL axby0, bxcy0, cxdy0, dxey0, exay0; |
| 4198 | REAL bxay0, cxby0, dxcy0, exdy0, axey0; |
| 4199 | REAL axcy0, bxdy0, cxey0, dxay0, exby0; |
| 4200 | REAL cxay0, dxby0, excy0, axdy0, bxey0; |
| 4201 | REAL ab[4], bc[4], cd[4], de[4], ea[4]; |
| 4202 | REAL ac[4], bd[4], ce[4], da[4], eb[4]; |
| 4203 | REAL temp8a[8], temp8b[8], temp16[16]; |
| 4204 | int temp8alen, temp8blen, temp16len; |
| 4205 | REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; |
| 4206 | REAL abd[24], bce[24], cda[24], deb[24], eac[24]; |
| 4207 | int abclen, bcdlen, cdelen, dealen, eablen; |
| 4208 | int abdlen, bcelen, cdalen, deblen, eaclen; |
| 4209 | REAL temp48a[48], temp48b[48]; |
| 4210 | int temp48alen, temp48blen; |
| 4211 | REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; |
| 4212 | int abcdlen, bcdelen, cdealen, deablen, eabclen; |
| 4213 | REAL adet[192], bdet[192], cdet[192], ddet[192], edet[192]; |
| 4214 | int alen, blen, clen, dlen, elen; |
| 4215 | REAL abdet[384], cddet[384], cdedet[576]; |
| 4216 | int ablen, cdlen; |
| 4217 | REAL deter[960]; |
| 4218 | int deterlen; |
| 4219 | int i; |
| 4220 | |
| 4221 | INEXACT REAL bvirt; |
| 4222 | REAL avirt, bround, around; |
| 4223 | INEXACT REAL c; |
| 4224 | INEXACT REAL abig; |
| 4225 | REAL ahi, alo, bhi, blo; |
| 4226 | REAL err1, err2, err3; |
| 4227 | INEXACT REAL _i, _j; |
| 4228 | REAL _0; |
| 4229 | |
| 4230 | |
| 4231 | Two_Product(pa[0], pb[1], axby1, axby0); |
| 4232 | Two_Product(pb[0], pa[1], bxay1, bxay0); |
| 4233 | Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); |
| 4234 | |
| 4235 | Two_Product(pb[0], pc[1], bxcy1, bxcy0); |
| 4236 | Two_Product(pc[0], pb[1], cxby1, cxby0); |
| 4237 | Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); |
| 4238 | |
| 4239 | Two_Product(pc[0], pd[1], cxdy1, cxdy0); |
| 4240 | Two_Product(pd[0], pc[1], dxcy1, dxcy0); |
| 4241 | Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); |
| 4242 | |
| 4243 | Two_Product(pd[0], pe[1], dxey1, dxey0); |
| 4244 | Two_Product(pe[0], pd[1], exdy1, exdy0); |
| 4245 | Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); |
| 4246 | |
| 4247 | Two_Product(pe[0], pa[1], exay1, exay0); |
| 4248 | Two_Product(pa[0], pe[1], axey1, axey0); |
| 4249 | Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); |
| 4250 | |
| 4251 | Two_Product(pa[0], pc[1], axcy1, axcy0); |
| 4252 | Two_Product(pc[0], pa[1], cxay1, cxay0); |
| 4253 | Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); |
| 4254 | |
| 4255 | Two_Product(pb[0], pd[1], bxdy1, bxdy0); |
| 4256 | Two_Product(pd[0], pb[1], dxby1, dxby0); |
| 4257 | Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); |
| 4258 | |
| 4259 | Two_Product(pc[0], pe[1], cxey1, cxey0); |
| 4260 | Two_Product(pe[0], pc[1], excy1, excy0); |
| 4261 | Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); |
| 4262 | |
| 4263 | Two_Product(pd[0], pa[1], dxay1, dxay0); |
| 4264 | Two_Product(pa[0], pd[1], axdy1, axdy0); |
| 4265 | Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); |
| 4266 | |
| 4267 | Two_Product(pe[0], pb[1], exby1, exby0); |
| 4268 | Two_Product(pb[0], pe[1], bxey1, bxey0); |
| 4269 | Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); |
| 4270 | |
| 4271 | temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); |
| 4272 | temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); |
| 4273 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4274 | temp16); |
| 4275 | temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); |
| 4276 | abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4277 | abc); |
| 4278 | |
| 4279 | temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); |
| 4280 | temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); |
| 4281 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4282 | temp16); |
| 4283 | temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); |
| 4284 | bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4285 | bcd); |
| 4286 | |
| 4287 | temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); |
| 4288 | temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); |
| 4289 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4290 | temp16); |
| 4291 | temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); |
| 4292 | cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4293 | cde); |
| 4294 | |
| 4295 | temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); |
| 4296 | temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); |
| 4297 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4298 | temp16); |
| 4299 | temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); |
| 4300 | dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4301 | dea); |
| 4302 | |
| 4303 | temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); |
| 4304 | temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); |
| 4305 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4306 | temp16); |
| 4307 | temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); |
| 4308 | eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4309 | eab); |
| 4310 | |
| 4311 | temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); |
| 4312 | temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); |
| 4313 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4314 | temp16); |
| 4315 | temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); |
| 4316 | abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4317 | abd); |
| 4318 | |
| 4319 | temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); |
| 4320 | temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); |
| 4321 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4322 | temp16); |
| 4323 | temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); |
| 4324 | bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4325 | bce); |
| 4326 | |
| 4327 | temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); |
| 4328 | temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); |
| 4329 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4330 | temp16); |
| 4331 | temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); |
| 4332 | cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4333 | cda); |
| 4334 | |
| 4335 | temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); |
| 4336 | temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); |
| 4337 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4338 | temp16); |
| 4339 | temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); |
| 4340 | deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4341 | deb); |
| 4342 | |
| 4343 | temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); |
| 4344 | temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); |
| 4345 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, |
| 4346 | temp16); |
| 4347 | temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); |
| 4348 | eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, |
| 4349 | eac); |
| 4350 | |
| 4351 | temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); |
| 4352 | temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); |
| 4353 | for (i = 0; i < temp48blen; i++) { |
| 4354 | temp48b[i] = -temp48b[i]; |
| 4355 | } |
| 4356 | bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 4357 | temp48blen, temp48b, bcde); |
| 4358 | alen = scale_expansion_zeroelim(bcdelen, bcde, aheight, adet); |
| 4359 | |
| 4360 | temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); |
| 4361 | temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); |
| 4362 | for (i = 0; i < temp48blen; i++) { |
| 4363 | temp48b[i] = -temp48b[i]; |
| 4364 | } |
| 4365 | cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 4366 | temp48blen, temp48b, cdea); |
| 4367 | blen = scale_expansion_zeroelim(cdealen, cdea, bheight, bdet); |
| 4368 | |
| 4369 | temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); |
| 4370 | temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); |
| 4371 | for (i = 0; i < temp48blen; i++) { |
| 4372 | temp48b[i] = -temp48b[i]; |
| 4373 | } |
| 4374 | deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 4375 | temp48blen, temp48b, deab); |
| 4376 | clen = scale_expansion_zeroelim(deablen, deab, cheight, cdet); |
| 4377 | |
| 4378 | temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); |
| 4379 | temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); |
| 4380 | for (i = 0; i < temp48blen; i++) { |
| 4381 | temp48b[i] = -temp48b[i]; |
| 4382 | } |
| 4383 | eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 4384 | temp48blen, temp48b, eabc); |
| 4385 | dlen = scale_expansion_zeroelim(eabclen, eabc, dheight, ddet); |
| 4386 | |
| 4387 | temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); |
| 4388 | temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); |
| 4389 | for (i = 0; i < temp48blen; i++) { |
| 4390 | temp48b[i] = -temp48b[i]; |
| 4391 | } |
| 4392 | abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, |
| 4393 | temp48blen, temp48b, abcd); |
| 4394 | elen = scale_expansion_zeroelim(abcdlen, abcd, eheight, edet); |
| 4395 | |
| 4396 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 4397 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 4398 | cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); |
| 4399 | deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); |
| 4400 | |
| 4401 | return deter[deterlen - 1]; |
| 4402 | } |
| 4403 | |
| 4404 | REAL orient4dadapt(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* pe, |
| 4405 | REAL aheight, REAL bheight, REAL cheight, REAL dheight, |
| 4406 | REAL eheight, REAL permanent) |
| 4407 | { |
| 4408 | INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; |
| 4409 | INEXACT REAL aeheight, beheight, ceheight, deheight; |
| 4410 | REAL det, errbound; |
| 4411 | |
| 4412 | INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; |
| 4413 | INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; |
| 4414 | INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; |
| 4415 | REAL aexbey0, bexaey0, bexcey0, cexbey0; |
| 4416 | REAL cexdey0, dexcey0, dexaey0, aexdey0; |
| 4417 | REAL aexcey0, cexaey0, bexdey0, dexbey0; |
| 4418 | REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; |
| 4419 | INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; |
| 4420 | REAL abeps, bceps, cdeps, daeps, aceps, bdeps; |
| 4421 | REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24]; |
| 4422 | int temp8alen, temp8blen, temp8clen, temp16len, temp24len; |
| 4423 | REAL adet[48], bdet[48], cdet[48], ddet[48]; |
| 4424 | int alen, blen, clen, dlen; |
| 4425 | REAL abdet[96], cddet[96]; |
| 4426 | int ablen, cdlen; |
| 4427 | REAL fin1[192]; |
| 4428 | int finlength; |
| 4429 | |
| 4430 | REAL aextail, bextail, cextail, dextail; |
| 4431 | REAL aeytail, beytail, ceytail, deytail; |
| 4432 | REAL aeztail, beztail, ceztail, deztail; |
| 4433 | REAL aeheighttail, beheighttail, ceheighttail, deheighttail; |
| 4434 | |
| 4435 | INEXACT REAL bvirt; |
| 4436 | REAL avirt, bround, around; |
| 4437 | INEXACT REAL c; |
| 4438 | INEXACT REAL abig; |
| 4439 | REAL ahi, alo, bhi, blo; |
| 4440 | REAL err1, err2, err3; |
| 4441 | INEXACT REAL _i, _j; |
| 4442 | REAL _0; |
| 4443 | |
| 4444 | |
| 4445 | aex = (REAL) (pa[0] - pe[0]); |
| 4446 | bex = (REAL) (pb[0] - pe[0]); |
| 4447 | cex = (REAL) (pc[0] - pe[0]); |
| 4448 | dex = (REAL) (pd[0] - pe[0]); |
| 4449 | aey = (REAL) (pa[1] - pe[1]); |
| 4450 | bey = (REAL) (pb[1] - pe[1]); |
| 4451 | cey = (REAL) (pc[1] - pe[1]); |
| 4452 | dey = (REAL) (pd[1] - pe[1]); |
| 4453 | aez = (REAL) (pa[2] - pe[2]); |
| 4454 | bez = (REAL) (pb[2] - pe[2]); |
| 4455 | cez = (REAL) (pc[2] - pe[2]); |
| 4456 | dez = (REAL) (pd[2] - pe[2]); |
| 4457 | aeheight = (REAL) (aheight - eheight); |
| 4458 | beheight = (REAL) (bheight - eheight); |
| 4459 | ceheight = (REAL) (cheight - eheight); |
| 4460 | deheight = (REAL) (dheight - eheight); |
| 4461 | |
| 4462 | Two_Product(aex, bey, aexbey1, aexbey0); |
| 4463 | Two_Product(bex, aey, bexaey1, bexaey0); |
| 4464 | Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); |
| 4465 | ab[3] = ab3; |
| 4466 | |
| 4467 | Two_Product(bex, cey, bexcey1, bexcey0); |
| 4468 | Two_Product(cex, bey, cexbey1, cexbey0); |
| 4469 | Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); |
| 4470 | bc[3] = bc3; |
| 4471 | |
| 4472 | Two_Product(cex, dey, cexdey1, cexdey0); |
| 4473 | Two_Product(dex, cey, dexcey1, dexcey0); |
| 4474 | Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); |
| 4475 | cd[3] = cd3; |
| 4476 | |
| 4477 | Two_Product(dex, aey, dexaey1, dexaey0); |
| 4478 | Two_Product(aex, dey, aexdey1, aexdey0); |
| 4479 | Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); |
| 4480 | da[3] = da3; |
| 4481 | |
| 4482 | Two_Product(aex, cey, aexcey1, aexcey0); |
| 4483 | Two_Product(cex, aey, cexaey1, cexaey0); |
| 4484 | Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); |
| 4485 | ac[3] = ac3; |
| 4486 | |
| 4487 | Two_Product(bex, dey, bexdey1, bexdey0); |
| 4488 | Two_Product(dex, bey, dexbey1, dexbey0); |
| 4489 | Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); |
| 4490 | bd[3] = bd3; |
| 4491 | |
| 4492 | temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); |
| 4493 | temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); |
| 4494 | temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); |
| 4495 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 4496 | temp8blen, temp8b, temp16); |
| 4497 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 4498 | temp16len, temp16, temp24); |
| 4499 | alen = scale_expansion_zeroelim(temp24len, temp24, -aeheight, adet); |
| 4500 | |
| 4501 | temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); |
| 4502 | temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); |
| 4503 | temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); |
| 4504 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 4505 | temp8blen, temp8b, temp16); |
| 4506 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 4507 | temp16len, temp16, temp24); |
| 4508 | blen = scale_expansion_zeroelim(temp24len, temp24, beheight, bdet); |
| 4509 | |
| 4510 | temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); |
| 4511 | temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); |
| 4512 | temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); |
| 4513 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 4514 | temp8blen, temp8b, temp16); |
| 4515 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 4516 | temp16len, temp16, temp24); |
| 4517 | clen = scale_expansion_zeroelim(temp24len, temp24, -ceheight, cdet); |
| 4518 | |
| 4519 | temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); |
| 4520 | temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); |
| 4521 | temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); |
| 4522 | temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, |
| 4523 | temp8blen, temp8b, temp16); |
| 4524 | temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, |
| 4525 | temp16len, temp16, temp24); |
| 4526 | dlen = scale_expansion_zeroelim(temp24len, temp24, deheight, ddet); |
| 4527 | |
| 4528 | ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); |
| 4529 | cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); |
| 4530 | finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); |
| 4531 | |
| 4532 | det = estimate(finlength, fin1); |
| 4533 | errbound = isperrboundB * permanent; |
| 4534 | if ((det >= errbound) || (-det >= errbound)) { |
| 4535 | return det; |
| 4536 | } |
| 4537 | |
| 4538 | Two_Diff_Tail(pa[0], pe[0], aex, aextail); |
| 4539 | Two_Diff_Tail(pa[1], pe[1], aey, aeytail); |
| 4540 | Two_Diff_Tail(pa[2], pe[2], aez, aeztail); |
| 4541 | Two_Diff_Tail(aheight, eheight, aeheight, aeheighttail); |
| 4542 | Two_Diff_Tail(pb[0], pe[0], bex, bextail); |
| 4543 | Two_Diff_Tail(pb[1], pe[1], bey, beytail); |
| 4544 | Two_Diff_Tail(pb[2], pe[2], bez, beztail); |
| 4545 | Two_Diff_Tail(bheight, eheight, beheight, beheighttail); |
| 4546 | Two_Diff_Tail(pc[0], pe[0], cex, cextail); |
| 4547 | Two_Diff_Tail(pc[1], pe[1], cey, ceytail); |
| 4548 | Two_Diff_Tail(pc[2], pe[2], cez, ceztail); |
| 4549 | Two_Diff_Tail(cheight, eheight, ceheight, ceheighttail); |
| 4550 | Two_Diff_Tail(pd[0], pe[0], dex, dextail); |
| 4551 | Two_Diff_Tail(pd[1], pe[1], dey, deytail); |
| 4552 | Two_Diff_Tail(pd[2], pe[2], dez, deztail); |
| 4553 | Two_Diff_Tail(dheight, eheight, deheight, deheighttail); |
| 4554 | if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) |
| 4555 | && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) |
| 4556 | && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) |
| 4557 | && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0) |
| 4558 | && (aeheighttail == 0.0) && (beheighttail == 0.0) |
| 4559 | && (ceheighttail == 0.0) && (deheighttail == 0.0)) { |
| 4560 | return det; |
| 4561 | } |
| 4562 | |
| 4563 | errbound = isperrboundC * permanent + resulterrbound * Absolute(det); |
| 4564 | abeps = (aex * beytail + bey * aextail) |
| 4565 | - (aey * bextail + bex * aeytail); |
| 4566 | bceps = (bex * ceytail + cey * bextail) |
| 4567 | - (bey * cextail + cex * beytail); |
| 4568 | cdeps = (cex * deytail + dey * cextail) |
| 4569 | - (cey * dextail + dex * ceytail); |
| 4570 | daeps = (dex * aeytail + aey * dextail) |
| 4571 | - (dey * aextail + aex * deytail); |
| 4572 | aceps = (aex * ceytail + cey * aextail) |
| 4573 | - (aey * cextail + cex * aeytail); |
| 4574 | bdeps = (bex * deytail + dey * bextail) |
| 4575 | - (bey * dextail + dex * beytail); |
| 4576 | det += ((beheight |
| 4577 | * ((cez * daeps + dez * aceps + aez * cdeps) |
| 4578 | + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) |
| 4579 | + deheight |
| 4580 | * ((aez * bceps - bez * aceps + cez * abeps) |
| 4581 | + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) |
| 4582 | - (aeheight |
| 4583 | * ((bez * cdeps - cez * bdeps + dez * bceps) |
| 4584 | + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) |
| 4585 | + ceheight |
| 4586 | * ((dez * abeps + aez * bdeps + bez * daeps) |
| 4587 | + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) |
| 4588 | + ((beheighttail * (cez * da3 + dez * ac3 + aez * cd3) |
| 4589 | + deheighttail * (aez * bc3 - bez * ac3 + cez * ab3)) |
| 4590 | - (aeheighttail * (bez * cd3 - cez * bd3 + dez * bc3) |
| 4591 | + ceheighttail * (dez * ab3 + aez * bd3 + bez * da3))); |
| 4592 | if ((det >= errbound) || (-det >= errbound)) { |
| 4593 | return det; |
| 4594 | } |
| 4595 | |
| 4596 | return orient4dexact(pa, pb, pc, pd, pe, |
| 4597 | aheight, bheight, cheight, dheight, eheight); |
| 4598 | } |
| 4599 | |
| 4600 | REAL orient4d(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* pe, |
| 4601 | REAL aheight, REAL bheight, REAL cheight, REAL dheight, |
| 4602 | REAL eheight) |
| 4603 | { |
| 4604 | REAL aex, bex, cex, dex; |
| 4605 | REAL aey, bey, cey, dey; |
| 4606 | REAL aez, bez, cez, dez; |
| 4607 | REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; |
| 4608 | REAL aexcey, cexaey, bexdey, dexbey; |
| 4609 | REAL aeheight, beheight, ceheight, deheight; |
| 4610 | REAL ab, bc, cd, da, ac, bd; |
| 4611 | REAL abc, bcd, cda, dab; |
| 4612 | REAL aezplus, bezplus, cezplus, dezplus; |
| 4613 | REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; |
| 4614 | REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; |
| 4615 | REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; |
| 4616 | REAL det; |
| 4617 | REAL permanent, errbound; |
| 4618 | |
| 4619 | |
| 4620 | aex = pa[0] - pe[0]; |
| 4621 | bex = pb[0] - pe[0]; |
| 4622 | cex = pc[0] - pe[0]; |
| 4623 | dex = pd[0] - pe[0]; |
| 4624 | aey = pa[1] - pe[1]; |
| 4625 | bey = pb[1] - pe[1]; |
| 4626 | cey = pc[1] - pe[1]; |
| 4627 | dey = pd[1] - pe[1]; |
| 4628 | aez = pa[2] - pe[2]; |
| 4629 | bez = pb[2] - pe[2]; |
| 4630 | cez = pc[2] - pe[2]; |
| 4631 | dez = pd[2] - pe[2]; |
| 4632 | aeheight = aheight - eheight; |
| 4633 | beheight = bheight - eheight; |
| 4634 | ceheight = cheight - eheight; |
| 4635 | deheight = dheight - eheight; |
| 4636 | |
| 4637 | aexbey = aex * bey; |
| 4638 | bexaey = bex * aey; |
| 4639 | ab = aexbey - bexaey; |
| 4640 | bexcey = bex * cey; |
| 4641 | cexbey = cex * bey; |
| 4642 | bc = bexcey - cexbey; |
| 4643 | cexdey = cex * dey; |
| 4644 | dexcey = dex * cey; |
| 4645 | cd = cexdey - dexcey; |
| 4646 | dexaey = dex * aey; |
| 4647 | aexdey = aex * dey; |
| 4648 | da = dexaey - aexdey; |
| 4649 | |
| 4650 | aexcey = aex * cey; |
| 4651 | cexaey = cex * aey; |
| 4652 | ac = aexcey - cexaey; |
| 4653 | bexdey = bex * dey; |
| 4654 | dexbey = dex * bey; |
| 4655 | bd = bexdey - dexbey; |
| 4656 | |
| 4657 | abc = aez * bc - bez * ac + cez * ab; |
| 4658 | bcd = bez * cd - cez * bd + dez * bc; |
| 4659 | cda = cez * da + dez * ac + aez * cd; |
| 4660 | dab = dez * ab + aez * bd + bez * da; |
| 4661 | |
| 4662 | det = (deheight * abc - ceheight * dab) + (beheight * cda - aeheight * bcd); |
| 4663 | |
| 4664 | aezplus = Absolute(aez); |
| 4665 | bezplus = Absolute(bez); |
| 4666 | cezplus = Absolute(cez); |
| 4667 | dezplus = Absolute(dez); |
| 4668 | aexbeyplus = Absolute(aexbey); |
| 4669 | bexaeyplus = Absolute(bexaey); |
| 4670 | bexceyplus = Absolute(bexcey); |
| 4671 | cexbeyplus = Absolute(cexbey); |
| 4672 | cexdeyplus = Absolute(cexdey); |
| 4673 | dexceyplus = Absolute(dexcey); |
| 4674 | dexaeyplus = Absolute(dexaey); |
| 4675 | aexdeyplus = Absolute(aexdey); |
| 4676 | aexceyplus = Absolute(aexcey); |
| 4677 | cexaeyplus = Absolute(cexaey); |
| 4678 | bexdeyplus = Absolute(bexdey); |
| 4679 | dexbeyplus = Absolute(dexbey); |
| 4680 | permanent = ((cexdeyplus + dexceyplus) * bezplus |
| 4681 | + (dexbeyplus + bexdeyplus) * cezplus |
| 4682 | + (bexceyplus + cexbeyplus) * dezplus) |
| 4683 | * Absolute(aeheight) |
| 4684 | + ((dexaeyplus + aexdeyplus) * cezplus |
| 4685 | + (aexceyplus + cexaeyplus) * dezplus |
| 4686 | + (cexdeyplus + dexceyplus) * aezplus) |
| 4687 | * Absolute(beheight) |
| 4688 | + ((aexbeyplus + bexaeyplus) * dezplus |
| 4689 | + (bexdeyplus + dexbeyplus) * aezplus |
| 4690 | + (dexaeyplus + aexdeyplus) * bezplus) |
| 4691 | * Absolute(ceheight) |
| 4692 | + ((bexceyplus + cexbeyplus) * aezplus |
| 4693 | + (cexaeyplus + aexceyplus) * bezplus |
| 4694 | + (aexbeyplus + bexaeyplus) * cezplus) |
| 4695 | * Absolute(deheight); |
| 4696 | errbound = isperrboundA * permanent; |
| 4697 | if ((det > errbound) || (-det > errbound)) { |
| 4698 | return det; |
| 4699 | } |
| 4700 | |
| 4701 | return orient4dadapt(pa, pb, pc, pd, pe, |
| 4702 | aheight, bheight, cheight, dheight, eheight, permanent); |
| 4703 | } |
| 4704 | |
| 4705 | |
| 4706 | |
| 4707 | |