| 1 | /* | 
| 2 | <html><pre>  -<a                             href="qh-user.htm" | 
| 3 | >-------------------------------</a><a name="TOP">-</a> | 
| 4 |  | 
| 5 | user.h | 
| 6 | user redefinable constants | 
| 7 |  | 
| 8 | see qh-user.htm.  see COPYING for copyright information. | 
| 9 |  | 
| 10 | before reading any code, review qhull.h for data structure definitions and | 
| 11 | the "qh" macro. | 
| 12 | */ | 
| 13 |  | 
| 14 | #ifndef qhDEFuser | 
| 15 | #define qhDEFuser 1 | 
| 16 |  | 
| 17 | /*============= data types and configuration macros ==========*/ | 
| 18 |  | 
| 19 | /* | 
| 20 | -<a                             href="qh-user.htm#TOC" | 
| 21 | >--------------------------------</a><a name="realT">-</a> | 
| 22 |  | 
| 23 | realT | 
| 24 | set the size of floating point numbers | 
| 25 |  | 
| 26 | qh_REALdigits | 
| 27 | maximimum number of significant digits | 
| 28 |  | 
| 29 | qh_REAL_1, qh_REAL_2n, qh_REAL_3n | 
| 30 | format strings for printf | 
| 31 |  | 
| 32 | qh_REALmax, qh_REALmin | 
| 33 | maximum and minimum (near zero) values | 
| 34 |  | 
| 35 | qh_REALepsilon | 
| 36 | machine roundoff.  Maximum roundoff error for addition and multiplication. | 
| 37 |  | 
| 38 | notes: | 
| 39 | Select whether to store floating point numbers in single precision (float) | 
| 40 | or double precision (double). | 
| 41 |  | 
| 42 | Use 'float' to save about 8% in time and 25% in space.  This is particularly | 
| 43 | help if high-d where convex hulls are space limited.  Using 'float' also | 
| 44 | reduces the printed size of Qhull's output since numbers have 8 digits of | 
| 45 | precision. | 
| 46 |  | 
| 47 | Use 'double' when greater arithmetic precision is needed.  This is needed | 
| 48 | for Delaunay triangulations and Voronoi diagrams when you are not merging | 
| 49 | facets. | 
| 50 |  | 
| 51 | If 'double' gives insufficient precision, your data probably includes | 
| 52 | degeneracies.  If so you should use facet merging (done by default) | 
| 53 | or exact arithmetic (see imprecision section of manual, qh-impre.htm). | 
| 54 | You may also use option 'Po' to force output despite precision errors. | 
| 55 |  | 
| 56 | You may use 'long double', but many format statements need to be changed | 
| 57 | and you may need a 'long double' square root routine.  S. Grundmann | 
| 58 | (sg@eeiwzb.et.tu-dresden.de) has done this.  He reports that the code runs | 
| 59 | much slower with little gain in precision. | 
| 60 |  | 
| 61 | WARNING: on some machines,    int f(){realT a= REALmax;return (a == REALmax);} | 
| 62 | returns False.  Use (a > REALmax/2) instead of (a == REALmax). | 
| 63 |  | 
| 64 | REALfloat =   1      all numbers are 'float' type | 
| 65 | =   0      all numbers are 'double' type | 
| 66 | */ | 
| 67 | #ifdef SINGLE_PRECISION | 
| 68 | #define REALfloat 1 | 
| 69 | #else | 
| 70 | #define REALfloat 0 | 
| 71 | #endif | 
| 72 |  | 
| 73 | #if (REALfloat == 1) | 
| 74 | #define realT float | 
| 75 | #define REALmax FLT_MAX | 
| 76 | #define REALmin FLT_MIN | 
| 77 | #define REALepsilon FLT_EPSILON | 
| 78 | /* maximum number of significant digits */ | 
| 79 | #define qh_REALdigits 8 | 
| 80 | #define qh_REAL_1 "%6.8g " | 
| 81 | #define qh_REAL_2n "%6.8g %6.8g\n" | 
| 82 | #define qh_REAL_3n "%6.8g %6.8g %6.8g\n" | 
| 83 |  | 
| 84 | #elif (REALfloat == 0) | 
| 85 | #define realT double | 
| 86 | #define REALmax DBL_MAX | 
| 87 | #define REALmin DBL_MIN | 
| 88 | #define REALepsilon DBL_EPSILON | 
| 89 | /* maximum number of significant digits */ | 
| 90 | #define qh_REALdigits 16 | 
| 91 | #define qh_REAL_1 "%6.16g " | 
| 92 | #define qh_REAL_2n "%6.16g %6.16g\n" | 
| 93 | #define qh_REAL_3n "%6.16g %6.16g %6.16g\n" | 
| 94 |  | 
| 95 | #else | 
| 96 | #error unknown float option | 
| 97 | #endif | 
| 98 |  | 
| 99 | /*-<a                             href="qh-user.htm#TOC" | 
| 100 | >--------------------------------</a><a name="CPUclock">-</a> | 
| 101 |  | 
| 102 | qh_CPUclock | 
| 103 | define the clock() function for reporting the total time spent by Qhull | 
| 104 | returns CPU ticks as a 'long int' | 
| 105 | qh_CPUclock is only used for reporting the total time spent by Qhull | 
| 106 |  | 
| 107 | qh_SECticks | 
| 108 | the number of clock ticks per second | 
| 109 |  | 
| 110 | notes: | 
| 111 | looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds | 
| 112 | to define a custom clock, set qh_CLOCKtype to 0 | 
| 113 |  | 
| 114 | if your system does not use clock() to return CPU ticks, replace | 
| 115 | qh_CPUclock with the corresponding function.  It is converted | 
| 116 | to unsigned long to prevent wrap-around during long runs. | 
| 117 |  | 
| 118 |  | 
| 119 | Set qh_CLOCKtype to | 
| 120 |  | 
| 121 | 1          for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond | 
| 122 | Note:  may fail if more than 1 hour elapsed time | 
| 123 |  | 
| 124 | 2          use qh_clock() with POSIX times() (see global.c) | 
| 125 | */ | 
| 126 | /* change to the desired number */ | 
| 127 | #define qh_CLOCKtype 1 | 
| 128 | #if (qh_CLOCKtype == 1) | 
| 129 |  | 
| 130 | #if defined (CLOCKS_PER_SECOND) | 
| 131 | /* return CPU clock */ | 
| 132 | #define qh_CPUclock    ((unsigned long)clock()) | 
| 133 | #define qh_SECticks CLOCKS_PER_SECOND | 
| 134 |  | 
| 135 | #elif defined (CLOCKS_PER_SEC) | 
| 136 | /* return CPU clock */ | 
| 137 | #define qh_CPUclock    ((unsigned long)clock()) | 
| 138 | #define qh_SECticks CLOCKS_PER_SEC | 
| 139 |  | 
| 140 | #elif defined (CLK_TCK) | 
| 141 | /* return CPU clock */ | 
| 142 | #define qh_CPUclock    ((unsigned long)clock()) | 
| 143 | #define qh_SECticks CLK_TCK | 
| 144 |  | 
| 145 | #else | 
| 146 | /* return CPU clock */ | 
| 147 | #define qh_CPUclock    ((unsigned long)clock()) | 
| 148 | #define qh_SECticks 1E6 | 
| 149 | #endif | 
| 150 |  | 
| 151 | #elif (qh_CLOCKtype == 2) | 
| 152 | /* return CPU clock */ | 
| 153 | #define qh_CPUclock    qh_clock() | 
| 154 | #define qh_SECticks 100 | 
| 155 |  | 
| 156 | #else | 
| 157 | /* qh_CLOCKtype == ? */ | 
| 158 | #error unknown clock option | 
| 159 | #endif | 
| 160 |  | 
| 161 | /*-<a                             href="qh-user.htm#TOC" | 
| 162 | >--------------------------------</a><a name="RANDOM">-</a> | 
| 163 |  | 
| 164 | qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed | 
| 165 | define random number generator | 
| 166 |  | 
| 167 | qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax. | 
| 168 | qh_RANDOMseed sets the random number seed for qh_RANDOMint | 
| 169 |  | 
| 170 | Set qh_RANDOMtype (default 5) to: | 
| 171 | 1       for random() with 31 bits (UCB) | 
| 172 | 2       for rand() with RAND_MAX or 15 bits (system 5) | 
| 173 | 3       for rand() with 31 bits (Sun) | 
| 174 | 4       for lrand48() with 31 bits (Solaris) | 
| 175 | 5       for qh_rand() with 31 bits (included with Qhull) | 
| 176 |  | 
| 177 | notes: | 
| 178 | Random numbers are used by rbox to generate point sets.  Random | 
| 179 | numbers are used by Qhull to rotate the input ('QRn' option), | 
| 180 | simulate a randomized algorithm ('Qr' option), and to simulate | 
| 181 | roundoff errors ('Rn' option). | 
| 182 |  | 
| 183 | Random number generators differ between systems.  Most systems provide | 
| 184 | rand() but the period varies.  The period of rand() is not critical | 
| 185 | since qhull does not normally use random numbers. | 
| 186 |  | 
| 187 | The default generator is Park & Miller's minimal standard random | 
| 188 | number generator [CACM 31:1195 '88].  It is included with Qhull. | 
| 189 |  | 
| 190 | If qh_RANDOMmax is wrong, qhull will report a warning and Geomview | 
| 191 | output will likely be invisible. | 
| 192 | */ | 
| 193 | /* *** change to the desired number *** */ | 
| 194 | #define qh_RANDOMtype 5 | 
| 195 | #if (qh_RANDOMtype == 1) | 
| 196 | /* 31 bits, random()/MAX */ | 
| 197 | #define qh_RANDOMmax ((realT)0x7fffffffUL) | 
| 198 | #define qh_RANDOMint random() | 
| 199 | #define qh_RANDOMseed_(seed) srandom(seed); | 
| 200 |  | 
| 201 | #elif (qh_RANDOMtype == 2) | 
| 202 | #ifdef RAND_MAX | 
| 203 | #define qh_RANDOMmax ((realT)RAND_MAX) | 
| 204 | #else | 
| 205 | /* 15 bits (System 5) */ | 
| 206 | #define qh_RANDOMmax ((realT)32767) | 
| 207 | #endif | 
| 208 | #define qh_RANDOMint  rand() | 
| 209 | #define qh_RANDOMseed_(seed) srand((unsigned)seed); | 
| 210 |  | 
| 211 | #elif (qh_RANDOMtype == 3) | 
| 212 | /* 31 bits, Sun */ | 
| 213 | #define qh_RANDOMmax ((realT)0x7fffffffUL) | 
| 214 | #define qh_RANDOMint  rand() | 
| 215 | #define qh_RANDOMseed_(seed) srand((unsigned)seed); | 
| 216 |  | 
| 217 | #elif (qh_RANDOMtype == 4) | 
| 218 | /* 31 bits, lrand38()/MAX */ | 
| 219 | #define qh_RANDOMmax ((realT)0x7fffffffUL) | 
| 220 | #define qh_RANDOMint lrand48() | 
| 221 | #define qh_RANDOMseed_(seed) srand48(seed); | 
| 222 |  | 
| 223 | #elif (qh_RANDOMtype == 5) | 
| 224 | /* 31 bits, qh_rand/MAX */ | 
| 225 | #define qh_RANDOMmax ((realT)2147483646UL) | 
| 226 | #define qh_RANDOMint qh_rand() | 
| 227 | #define qh_RANDOMseed_(seed) qh_srand(seed); | 
| 228 | /* unlike rand(), never returns 0 */ | 
| 229 |  | 
| 230 | #else | 
| 231 | #error: unknown random option | 
| 232 | #endif | 
| 233 |  | 
| 234 | /*-<a                             href="qh-user.htm#TOC" | 
| 235 | >--------------------------------</a><a name="ORIENTclock">-</a> | 
| 236 |  | 
| 237 | qh_ORIENTclock | 
| 238 | 0 for inward pointing normals by Geomview convention | 
| 239 | */ | 
| 240 | #define qh_ORIENTclock 0 | 
| 241 |  | 
| 242 |  | 
| 243 | /*========= performance related constants =========*/ | 
| 244 |  | 
| 245 | /*-<a                             href="qh-user.htm#TOC" | 
| 246 | >--------------------------------</a><a name="HASHfactor">-</a> | 
| 247 |  | 
| 248 | qh_HASHfactor | 
| 249 | total hash slots / used hash slots.  Must be at least 1.1. | 
| 250 |  | 
| 251 | notes: | 
| 252 | =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy | 
| 253 | */ | 
| 254 | #define qh_HASHfactor 2 | 
| 255 |  | 
| 256 | /*-<a                             href="qh-user.htm#TOC" | 
| 257 | >--------------------------------</a><a name="VERIFYdirect">-</a> | 
| 258 |  | 
| 259 | qh_VERIFYdirect | 
| 260 | with 'Tv' verify all points against all facets if op count is smaller | 
| 261 |  | 
| 262 | notes: | 
| 263 | if greater, calls qh_check_bestdist() instead | 
| 264 | */ | 
| 265 | #define qh_VERIFYdirect 1000000 | 
| 266 |  | 
| 267 | /*-<a                             href="qh-user.htm#TOC" | 
| 268 | >--------------------------------</a><a name="INITIALsearch">-</a> | 
| 269 |  | 
| 270 | qh_INITIALsearch | 
| 271 | if qh_INITIALmax, search points up to this dimension | 
| 272 | */ | 
| 273 | #define qh_INITIALsearch 6 | 
| 274 |  | 
| 275 | /*-<a                             href="qh-user.htm#TOC" | 
| 276 | >--------------------------------</a><a name="INITIALmax">-</a> | 
| 277 |  | 
| 278 | qh_INITIALmax | 
| 279 | if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex | 
| 280 |  | 
| 281 | notes: | 
| 282 | from points with non-zero determinants | 
| 283 | please use option 'Qs' to override (much slower) | 
| 284 | */ | 
| 285 | #define qh_INITIALmax 8 | 
| 286 |  | 
| 287 | /*-<a                             href="qh-user.htm#TOC" | 
| 288 | >--------------------------------</a><a name="JOGGLEdefault">-</a> | 
| 289 |  | 
| 290 | qh_JOGGLEdefault | 
| 291 | default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault | 
| 292 |  | 
| 293 | notes: | 
| 294 | rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16 | 
| 295 | rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults | 
| 296 | rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults | 
| 297 | rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults | 
| 298 | rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults | 
| 299 | rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults | 
| 300 | rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults | 
| 301 | rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults | 
| 302 | rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults | 
| 303 | the later have about 20 points per facet, each of which may interfere | 
| 304 |  | 
| 305 | pick a value large enough to avoid retries on most inputs | 
| 306 | */ | 
| 307 | #define qh_JOGGLEdefault 30000.0 | 
| 308 |  | 
| 309 | /*-<a                             href="qh-user.htm#TOC" | 
| 310 | >--------------------------------</a><a name="JOGGLEincrease">-</a> | 
| 311 |  | 
| 312 | qh_JOGGLEincrease | 
| 313 | factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain | 
| 314 | */ | 
| 315 | #define qh_JOGGLEincrease 10.0 | 
| 316 |  | 
| 317 | /*-<a                             href="qh-user.htm#TOC" | 
| 318 | >--------------------------------</a><a name="JOGGLEretry">-</a> | 
| 319 |  | 
| 320 | qh_JOGGLEretry | 
| 321 | if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax | 
| 322 |  | 
| 323 | notes: | 
| 324 | try twice at the original value in case of bad luck the first time | 
| 325 | */ | 
| 326 | #define qh_JOGGLEretry 2 | 
| 327 |  | 
| 328 | /*-<a                             href="qh-user.htm#TOC" | 
| 329 | >--------------------------------</a><a name="JOGGLEagain">-</a> | 
| 330 |  | 
| 331 | qh_JOGGLEagain | 
| 332 | every following qh_JOGGLEagain, increase qh.JOGGLEmax | 
| 333 |  | 
| 334 | notes: | 
| 335 | 1 is OK since it's already failed qh_JOGGLEretry times | 
| 336 | */ | 
| 337 | #define qh_JOGGLEagain 1 | 
| 338 |  | 
| 339 | /*-<a                             href="qh-user.htm#TOC" | 
| 340 | >--------------------------------</a><a name="JOGGLEmaxincrease">-</a> | 
| 341 |  | 
| 342 | qh_JOGGLEmaxincrease | 
| 343 | maximum qh.JOGGLEmax due to qh_JOGGLEincrease | 
| 344 | relative to qh.MAXwidth | 
| 345 |  | 
| 346 | notes: | 
| 347 | qh.joggleinput will retry at this value until qh_JOGGLEmaxretry | 
| 348 | */ | 
| 349 | #define qh_JOGGLEmaxincrease 1e-2 | 
| 350 |  | 
| 351 | /*-<a                             href="qh-user.htm#TOC" | 
| 352 | >--------------------------------</a><a name="JOGGLEmaxretry">-</a> | 
| 353 |  | 
| 354 | qh_JOGGLEmaxretry | 
| 355 | stop after qh_JOGGLEmaxretry attempts | 
| 356 | */ | 
| 357 | #define qh_JOGGLEmaxretry 100 | 
| 358 |  | 
| 359 | /*========= memory constants =========*/ | 
| 360 |  | 
| 361 | /*-<a                             href="qh-user.htm#TOC" | 
| 362 | >--------------------------------</a><a name="MEMalign">-</a> | 
| 363 |  | 
| 364 | qh_MEMalign | 
| 365 | memory alignment for qh_meminitbuffers() in global.c | 
| 366 |  | 
| 367 | notes: | 
| 368 | to avoid bus errors, memory allocation must consider alignment requirements. | 
| 369 | malloc() automatically takes care of alignment.   Since mem.c manages | 
| 370 | its own memory, we need to explicitly specify alignment in | 
| 371 | qh_meminitbuffers(). | 
| 372 |  | 
| 373 | A safe choice is sizeof(double).  sizeof(float) may be used if doubles | 
| 374 | do not occur in data structures and pointers are the same size.  Be careful | 
| 375 | of machines (e.g., DEC Alpha) with large pointers. | 
| 376 |  | 
| 377 | If using gcc, best alignment is | 
| 378 | #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *)) | 
| 379 | */ | 
| 380 | #define qh_MEMalign fmax_(sizeof(realT), sizeof(void *)) | 
| 381 |  | 
| 382 | /*-<a                             href="qh-user.htm#TOC" | 
| 383 | >--------------------------------</a><a name="MEMbufsize">-</a> | 
| 384 |  | 
| 385 | qh_MEMbufsize | 
| 386 | size of additional memory buffers | 
| 387 |  | 
| 388 | notes: | 
| 389 | used for qh_meminitbuffers() in global.c | 
| 390 | */ | 
| 391 | /* allocate 64K memory buffers */ | 
| 392 | #define qh_MEMbufsize 0x10000 | 
| 393 |  | 
| 394 | /*-<a                             href="qh-user.htm#TOC" | 
| 395 | >--------------------------------</a><a name="MEMinitbuf">-</a> | 
| 396 |  | 
| 397 | qh_MEMinitbuf | 
| 398 | size of initial memory buffer | 
| 399 |  | 
| 400 | notes: | 
| 401 | please to be using for qh_meminitbuffers() in global.c | 
| 402 | */ | 
| 403 | /* initially allocate 128K buffer */ | 
| 404 | #define qh_MEMinitbuf 0x20000 | 
| 405 |  | 
| 406 | /*-<a                             href="qh-user.htm#TOC" | 
| 407 | >--------------------------------</a><a name="INFINITE">-</a> | 
| 408 |  | 
| 409 | qh_INFINITE | 
| 410 | on output, indicates Voronoi center at infinity | 
| 411 | */ | 
| 412 | #define qh_INFINITE  -10.101 | 
| 413 |  | 
| 414 | /*-<a                             href="qh-user.htm#TOC" | 
| 415 | >--------------------------------</a><a name="DEFAULTbox">-</a> | 
| 416 |  | 
| 417 | qh_DEFAULTbox | 
| 418 | default box size (Geomview expects 0.5) | 
| 419 | */ | 
| 420 | #define qh_DEFAULTbox 0.5 | 
| 421 |  | 
| 422 | /*======= conditional compilation ============================*/ | 
| 423 |  | 
| 424 | /*-<a                             href="qh-user.htm#TOC" | 
| 425 | >--------------------------------</a><a name="compiler">-</a> | 
| 426 |  | 
| 427 | __cplusplus | 
| 428 | defined by C++ compilers | 
| 429 |  | 
| 430 | __MSC_VER | 
| 431 | defined by Microsoft Visual C++ | 
| 432 |  | 
| 433 | __MWERKS__ && __POWERPC__ | 
| 434 | defined by Metrowerks when compiling for the Power Macintosh | 
| 435 |  | 
| 436 | __STDC__ | 
| 437 | defined for strict ANSI C | 
| 438 | */ | 
| 439 |  | 
| 440 | /*-<a                             href="qh-user.htm#TOC" | 
| 441 | >--------------------------------</a><a name="COMPUTEfurthest">-</a> | 
| 442 |  | 
| 443 | qh_COMPUTEfurthest | 
| 444 | compute furthest distance to an outside point instead of storing it with the facet | 
| 445 | =1 to compute furthest | 
| 446 |  | 
| 447 | notes: | 
| 448 | computing furthest saves memory but costs time | 
| 449 | about 40% more distance tests for partitioning | 
| 450 | removes facet->furthestdist | 
| 451 | */ | 
| 452 | #define qh_COMPUTEfurthest 0 | 
| 453 |  | 
| 454 | /*-<a                             href="qh-user.htm#TOC" | 
| 455 | >--------------------------------</a><a name="KEEPstatistics">-</a> | 
| 456 |  | 
| 457 | qh_KEEPstatistics | 
| 458 | =0 removes most of statistic gathering and reporting | 
| 459 |  | 
| 460 | notes: | 
| 461 | if 0, code size is reduced by about 4%. | 
| 462 | */ | 
| 463 | #define qh_KEEPstatistics 1 | 
| 464 |  | 
| 465 | /*-<a                             href="qh-user.htm#TOC" | 
| 466 | >--------------------------------</a><a name="MAXoutside">-</a> | 
| 467 |  | 
| 468 | qh_MAXoutside | 
| 469 | record outer plane for each facet | 
| 470 | =1 to record facet->maxoutside | 
| 471 |  | 
| 472 | notes: | 
| 473 | this takes a realT per facet and slightly slows down qhull | 
| 474 | it produces better outer planes for geomview output | 
| 475 | */ | 
| 476 | #define qh_MAXoutside 1 | 
| 477 |  | 
| 478 | /*-<a                             href="qh-user.htm#TOC" | 
| 479 | >--------------------------------</a><a name="NOmerge">-</a> | 
| 480 |  | 
| 481 | qh_NOmerge | 
| 482 | disables facet merging if defined | 
| 483 |  | 
| 484 | notes: | 
| 485 | This saves about 10% space. | 
| 486 |  | 
| 487 | Unless 'Q0' | 
| 488 | qh_NOmerge sets 'QJ' to avoid precision errors | 
| 489 |  | 
| 490 | #define qh_NOmerge | 
| 491 |  | 
| 492 | see: | 
| 493 | <a href="mem.h#NOmem">qh_NOmem</a> in mem.c | 
| 494 |  | 
| 495 | see user.c/user_eg.c for removing io.o | 
| 496 | */ | 
| 497 |  | 
| 498 | /*-<a                             href="qh-user.htm#TOC" | 
| 499 | >--------------------------------</a><a name="NOtrace">-</a> | 
| 500 |  | 
| 501 | qh_NOtrace | 
| 502 | no tracing if defined | 
| 503 |  | 
| 504 | notes: | 
| 505 | This saves about 5% space. | 
| 506 |  | 
| 507 | #define qh_NOtrace | 
| 508 | */ | 
| 509 |  | 
| 510 | /*-<a                             href="qh-user.htm#TOC" | 
| 511 | >--------------------------------</a><a name="QHpointer">-</a> | 
| 512 |  | 
| 513 | qh_QHpointer | 
| 514 | access global data with pointer or static structure | 
| 515 |  | 
| 516 | qh_QHpointer  = 1     access globals via a pointer to allocated memory | 
| 517 | enables qh_saveqhull() and qh_restoreqhull() | 
| 518 | costs about 8% in time and 2% in space | 
| 519 |  | 
| 520 | = 0     qh_qh and qh_qhstat are static data structures | 
| 521 | only one instance of qhull() can be active at a time | 
| 522 | default value | 
| 523 |  | 
| 524 | notes: | 
| 525 | all global variables for qhull are in qh, qhmem, and qhstat | 
| 526 | qh is defined in qhull.h | 
| 527 | qhmem is defined in mem.h | 
| 528 | qhstat is defined in stat.h | 
| 529 |  | 
| 530 | see: | 
| 531 | user_eg.c for an example | 
| 532 | */ | 
| 533 | #define qh_QHpointer 0 | 
| 534 | #if 0 | 
| 535 | /* sample code */ | 
| 536 | qhT *oldqhA, *oldqhB; | 
| 537 |  | 
| 538 | exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, | 
| 539 | flags, outfile, errfile); | 
| 540 | /* use results from first call to qh_new_qhull */ | 
| 541 | oldqhA= qh_save_qhull(); | 
| 542 | exitcode= qh_new_qhull (dimB, numpointsB, pointsB, ismalloc, | 
| 543 | flags, outfile, errfile); | 
| 544 | /* use results from second call to qh_new_qhull */ | 
| 545 | oldqhB= qh_save_qhull(); | 
| 546 | qh_restore_qhull (&oldqhA); | 
| 547 | /* use results from first call to qh_new_qhull */ | 
| 548 | qh_freeqhull (qh_ALL);  /* frees all memory used by first call */ | 
| 549 | qh_restore_qhull (&oldqhB); | 
| 550 | /* use results from second call to qh_new_qhull */ | 
| 551 | qh_freeqhull (!qh_ALL); /* frees long memory used by second call */ | 
| 552 | qh_memfreeshort (&curlong, &totlong);  /* frees short memory and memory allocator */ | 
| 553 | #endif | 
| 554 |  | 
| 555 | /*-<a                             href="qh-user.htm#TOC" | 
| 556 | >--------------------------------</a><a name="QUICKhelp">-</a> | 
| 557 |  | 
| 558 | qh_QUICKhelp | 
| 559 | =1 to use abbreviated help messages, e.g., for degenerate inputs | 
| 560 | */ | 
| 561 | #define qh_QUICKhelp    0 | 
| 562 |  | 
| 563 | /* ============ -merge constants- ==================== | 
| 564 |  | 
| 565 | These constants effect facet merging.  You probably will not need | 
| 566 | to modify these.  They effect the performance of facet merging. | 
| 567 | */ | 
| 568 |  | 
| 569 | /*-<a                             href="qh-user.htm#TOC" | 
| 570 | >--------------------------------</a><a name="DIMmergeVertex">-</a> | 
| 571 |  | 
| 572 | qh_DIMmergeVertex | 
| 573 | max dimension for vertex merging (it is not effective in high-d) | 
| 574 | */ | 
| 575 | #define qh_DIMmergeVertex 6 | 
| 576 |  | 
| 577 | /*-<a                             href="qh-user.htm#TOC" | 
| 578 | >--------------------------------</a><a name="DIMreduceBuild">-</a> | 
| 579 |  | 
| 580 | qh_DIMreduceBuild | 
| 581 | max dimension for vertex reduction during build (slow in high-d) | 
| 582 | */ | 
| 583 | #define qh_DIMreduceBuild 5 | 
| 584 |  | 
| 585 | /*-<a                             href="qh-user.htm#TOC" | 
| 586 | >--------------------------------</a><a name="BESTcentrum">-</a> | 
| 587 |  | 
| 588 | qh_BESTcentrum | 
| 589 | if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster) | 
| 590 | else, qh_findbestneighbor() tests all vertices (much better merges) | 
| 591 |  | 
| 592 | qh_BESTcentrum2 | 
| 593 | if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums | 
| 594 | */ | 
| 595 | #define qh_BESTcentrum 20 | 
| 596 | #define qh_BESTcentrum2 2 | 
| 597 |  | 
| 598 | /*-<a                             href="qh-user.htm#TOC" | 
| 599 | >--------------------------------</a><a name="BESTnonconvex">-</a> | 
| 600 |  | 
| 601 | qh_BESTnonconvex | 
| 602 | if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges. | 
| 603 |  | 
| 604 | notes: | 
| 605 | It is needed because qh_findbestneighbor is slow for large facets | 
| 606 | */ | 
| 607 | #define qh_BESTnonconvex 15 | 
| 608 |  | 
| 609 | /*-<a                             href="qh-user.htm#TOC" | 
| 610 | >--------------------------------</a><a name="MAXnewmerges">-</a> | 
| 611 |  | 
| 612 | qh_MAXnewmerges | 
| 613 | if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums. | 
| 614 |  | 
| 615 | notes: | 
| 616 | It is needed because postmerge can merge many facets at once | 
| 617 | */ | 
| 618 | #define qh_MAXnewmerges 2 | 
| 619 |  | 
| 620 | /*-<a                             href="qh-user.htm#TOC" | 
| 621 | >--------------------------------</a><a name="MAXnewcentrum">-</a> | 
| 622 |  | 
| 623 | qh_MAXnewcentrum | 
| 624 | if <= dim+n vertices (n approximates the number of merges), | 
| 625 | reset the centrum in qh_updatetested() and qh_mergecycle_facets() | 
| 626 |  | 
| 627 | notes: | 
| 628 | needed to reduce cost and because centrums may move too much if | 
| 629 | many vertices in high-d | 
| 630 | */ | 
| 631 | #define qh_MAXnewcentrum 5 | 
| 632 |  | 
| 633 | /*-<a                             href="qh-user.htm#TOC" | 
| 634 | >--------------------------------</a><a name="COPLANARratio">-</a> | 
| 635 |  | 
| 636 | qh_COPLANARratio | 
| 637 | for 3-d+ merging, qh.MINvisible is n*premerge_centrum | 
| 638 |  | 
| 639 | notes: | 
| 640 | for non-merging, it's DISTround | 
| 641 | */ | 
| 642 | #define qh_COPLANARratio 3 | 
| 643 |  | 
| 644 | /*-<a                             href="qh-user.htm#TOC" | 
| 645 | >--------------------------------</a><a name="DISToutside">-</a> | 
| 646 |  | 
| 647 | qh_DISToutside | 
| 648 | When is a point clearly outside of a facet? | 
| 649 | Stops search in qh_findbestnew or qh_partitionall | 
| 650 | qh_findbest uses qh.MINoutside since since it is only called if no merges. | 
| 651 |  | 
| 652 | notes: | 
| 653 | 'Qf' always searches for best facet | 
| 654 | if !qh.MERGING, same as qh.MINoutside. | 
| 655 | if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved | 
| 656 | [Note: Zdelvertextot occurs normally with interior points] | 
| 657 | RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv | 
| 658 | When there is a sharp edge, need to move points to a | 
| 659 | clearly good facet; otherwise may be lost in another partitioning. | 
| 660 | if too big then O(n^2) behavior for partitioning in cone | 
| 661 | if very small then important points not processed | 
| 662 | Needed in qh_partitionall for | 
| 663 | RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv | 
| 664 | Needed in qh_findbestnew for many instances of | 
| 665 | RBOX 1000 s Z1 G1e-13 t | QHULL Tv | 
| 666 |  | 
| 667 | See: | 
| 668 | qh_DISToutside -- when is a point clearly outside of a facet | 
| 669 | qh_SEARCHdist -- when is facet coplanar with the best facet? | 
| 670 | qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint() | 
| 671 | */ | 
| 672 | #define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \ | 
| 673 | fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside)) | 
| 674 |  | 
| 675 | /*-<a                             href="qh-user.htm#TOC" | 
| 676 | >--------------------------------</a><a name="RATIOnearinside">-</a> | 
| 677 |  | 
| 678 | qh_RATIOnearinside | 
| 679 | ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for | 
| 680 | qh_check_maxout(). | 
| 681 |  | 
| 682 | notes: | 
| 683 | This is overkill since do not know the correct value. | 
| 684 | It effects whether 'Qc' reports all coplanar points | 
| 685 | Not used for 'd' since non-extreme points are coplanar | 
| 686 | */ | 
| 687 | #define qh_RATIOnearinside 5 | 
| 688 |  | 
| 689 | /*-<a                             href="qh-user.htm#TOC" | 
| 690 | >--------------------------------</a><a name="SEARCHdist">-</a> | 
| 691 |  | 
| 692 | qh_SEARCHdist | 
| 693 | When is a facet coplanar with the best facet? | 
| 694 | qh_findbesthorizon: all coplanar facets of the best facet need to be searched. | 
| 695 |  | 
| 696 | See: | 
| 697 | qh_DISToutside -- when is a point clearly outside of a facet | 
| 698 | qh_SEARCHdist -- when is facet coplanar with the best facet? | 
| 699 | qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint() | 
| 700 | */ | 
| 701 | #define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \ | 
| 702 | (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar))); | 
| 703 |  | 
| 704 | /*-<a                             href="qh-user.htm#TOC" | 
| 705 | >--------------------------------</a><a name="USEfindbestnew">-</a> | 
| 706 |  | 
| 707 | qh_USEfindbestnew | 
| 708 | Always use qh_findbestnew for qh_partitionpoint, otherwise use | 
| 709 | qh_findbestnew if merged new facet or sharpnewfacets. | 
| 710 |  | 
| 711 | See: | 
| 712 | qh_DISToutside -- when is a point clearly outside of a facet | 
| 713 | qh_SEARCHdist -- when is facet coplanar with the best facet? | 
| 714 | qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint() | 
| 715 | */ | 
| 716 | #define qh_USEfindbestnew (zzval_(Ztotmerge) > 50) | 
| 717 |  | 
| 718 | /*-<a                             href="qh-user.htm#TOC" | 
| 719 | >--------------------------------</a><a name="WIDEcoplanar">-</a> | 
| 720 |  | 
| 721 | qh_WIDEcoplanar | 
| 722 | n*MAXcoplanar or n*MINvisible for a WIDEfacet | 
| 723 |  | 
| 724 | if vertex is further than qh.WIDEfacet from the hyperplane | 
| 725 | then its ridges are not counted in computing the area, and | 
| 726 | the facet's centrum is frozen. | 
| 727 |  | 
| 728 | notes: | 
| 729 | qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar, | 
| 730 | qh_WIDEcoplanar * qh.MINvisible); | 
| 731 | */ | 
| 732 | #define qh_WIDEcoplanar 6 | 
| 733 |  | 
| 734 | /*-<a                             href="qh-user.htm#TOC" | 
| 735 | >--------------------------------</a><a name="MAXnarrow">-</a> | 
| 736 |  | 
| 737 | qh_MAXnarrow | 
| 738 | max. cosine in initial hull that sets qh.NARROWhull | 
| 739 |  | 
| 740 | notes: | 
| 741 | If qh.NARROWhull, the initial partition does not make | 
| 742 | coplanar points.  If narrow, a coplanar point can be | 
| 743 | coplanar to two facets of opposite orientations and | 
| 744 | distant from the exact convex hull. | 
| 745 |  | 
| 746 | Conservative estimate.  Don't actually see problems until it is -1.0 | 
| 747 | */ | 
| 748 | #define qh_MAXnarrow -0.99999999 | 
| 749 |  | 
| 750 | /*-<a                             href="qh-user.htm#TOC" | 
| 751 | >--------------------------------</a><a name="WARNnarrow">-</a> | 
| 752 |  | 
| 753 | qh_WARNnarrow | 
| 754 | max. cosine in initial hull to warn about qh.NARROWhull | 
| 755 |  | 
| 756 | notes: | 
| 757 | this is a conservative estimate. | 
| 758 | Don't actually see problems until it is -1.0.  See qh-impre.htm | 
| 759 | */ | 
| 760 | #define qh_WARNnarrow -0.999999999999999 | 
| 761 |  | 
| 762 | /*-<a                             href="qh-user.htm#TOC" | 
| 763 | >--------------------------------</a><a name="ZEROdelaunay">-</a> | 
| 764 |  | 
| 765 | qh_ZEROdelaunay | 
| 766 | a zero Delaunay facet occurs for input sites coplanar with their convex hull | 
| 767 | the last normal coefficient of a zero Delaunay facet is within | 
| 768 | qh_ZEROdelaunay * qh.ANGLEround of 0 | 
| 769 |  | 
| 770 | notes: | 
| 771 | qh_ZEROdelaunay does not allow for joggled input ('QJ'). | 
| 772 |  | 
| 773 | You can avoid zero Delaunay facets by surrounding the input with a box. | 
| 774 |  | 
| 775 | Use option 'PDk:-n' to explicitly define zero Delaunay facets | 
| 776 | k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation) | 
| 777 | n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12') | 
| 778 | */ | 
| 779 | #define qh_ZEROdelaunay 2 | 
| 780 |  | 
| 781 | #endif | 
| 782 |  | 
| 783 |  | 
| 784 |  |