| 1 |
chuckv |
1138 |
/* |
| 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 |
|
|
|