00001 /*<html><pre> -<a href="qh-c.htm#qhull" 00002 >-------------------------------</a><a name="TOP">-</a> 00003 00004 qhull.h 00005 user-level header file for using qhull.a library 00006 00007 see qh-c.htm, qhull_a.h 00008 00009 copyright (c) 1993-1998, The Geometry Center 00010 00011 defines qh_qh, global data structure for qhull. 00012 00013 NOTE: access to qh_qh is via the 'qh' macro. This allows 00014 qh_qh to be either a pointer or a structure. An example 00015 of using qh is "qh DROPdim" which accesses the DROPdim 00016 field of qh_qh. Similarly, access to qh_qhstat is via 00017 the 'qhstat' macro. 00018 00019 includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c 00020 00021 use mem.h for mem.c 00022 use set.h for set.c 00023 00024 see unix.c for an example of using qhull.h 00025 00026 recompile qhull if you change this file 00027 */ 00028 00029 #ifndef qhDEFqhull 00030 #define qhDEFqhull 1 00031 00032 /*=========================== -included files ==============*/ 00033 00034 #include <setjmp.h> 00035 #include <float.h> 00036 #include <time.h> 00037 00038 #if __MWERKS__ && __POWERPC__ 00039 #include <SIOUX.h> 00040 #include <Files.h> 00041 #include <Desk.h> 00042 #endif 00043 00044 #ifndef __STDC__ 00045 #ifndef __cplusplus 00046 #if !_MSC_VER 00047 #error Neither __STDC__ nor __cplusplus is defined. Please use strict ANSI C or C++ to compile 00048 #error Qhull. You may need to turn off compiler extensions in your project configuration. If 00049 #error your compiler is a standard C compiler, you can delete this warning from qhull.h 00050 #endif 00051 #endif 00052 #endif 00053 00054 #include "user.h" /* user defineable constants */ 00055 00056 /*============ constants and basic types ====================*/ 00057 00058 /*-<a href="qh-c.htm#geom" 00059 >--------------------------------</a><a name="coordT">-</a> 00060 00061 coordT 00062 coordinates and coefficients are stored as realT (i.e., double) 00063 00064 notes: 00065 could use 'float' for data and 'double' for calculations (realT vs. coordT) 00066 This requires many type casts, and adjusted error bounds. 00067 Also C compilers may do expressions in double anyway. 00068 */ 00069 #define coordT realT 00070 /*-<a href="qh-c.htm#geom" 00071 >--------------------------------</a><a name="pointT">-</a> 00072 00073 pointT 00074 a point is an array of DIM3 coordinates 00075 */ 00076 #define pointT coordT 00077 00078 /*-<a href="qh-c.htm#qhull" 00079 >--------------------------------</a><a name="flagT">-</a> 00080 00081 flagT 00082 Boolean flag as a bit 00083 */ 00084 #define flagT unsigned int 00085 00086 /*-<a href="qh-c.htm#qhull" 00087 >--------------------------------</a><a name="boolT">-</a> 00088 00089 boolT 00090 boolean value, either True or False 00091 00092 notes: 00093 needed for portability 00094 */ 00095 #define boolT unsigned int 00096 #ifdef False 00097 #undef False 00098 #endif 00099 #ifdef True 00100 #undef True 00101 #endif 00102 #define False 0 00103 #define True 1 00104 00105 /*-<a href="qh-c.htm#qhull" 00106 >--------------------------------</a><a name="CENTERtype">-</a> 00107 00108 qh_CENTER 00109 to distinguish facet->center 00110 */ 00111 typedef enum 00112 { 00113 qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum 00114 } 00115 qh_CENTER; 00116 00117 /*-<a href="qh-c.htm#qhull" 00118 >--------------------------------</a><a name="qh_PRINT">-</a> 00119 00120 qh_PRINT 00121 output formats for printing (qh.PRINTout). 00122 00123 notes: 00124 some of these names are similar to qh names. The similar names are only 00125 used in switch statements in qh_printbegin() etc. 00126 */ 00127 typedef enum {qh_PRINTnone= 0, qh_PRINTarea, qh_PRINTaverage, 00128 qh_PRINTcoplanars, qh_PRINTcentrums, 00129 qh_PRINTfacets, qh_PRINTfacets_xridge, 00130 qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, 00131 qh_PRINTnormals, qh_PRINTouter, qh_PRINTincidences, 00132 qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff, 00133 qh_PRINToptions, qh_PRINTpointintersect, qh_PRINTpointnearest, 00134 qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize, qh_PRINTsummary, 00135 qh_PRINTtriangles, qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes, 00136 qh_PRINTEND} qh_PRINT; 00137 00138 /*-<a href="qh-c.htm#qhull" 00139 >--------------------------------</a><a name="qh_ALL">-</a> 00140 00141 qh_ALL 00142 argument flag for selecting everything 00143 */ 00144 #define qh_ALL True 00145 #define qh_NOupper True /* argument for qh_findbest */ 00146 00147 /*-<a href="qh-c.htm#qhull" 00148 >--------------------------------</a><a name="qh_ERR">-</a> 00149 00150 qh_ERR 00151 Qhull exit codes, for indicating errors 00152 */ 00153 #define qh_ERRnone 0 /* no error occurred during qhull */ 00154 #define qh_ERRinput 1 /* input inconsistency */ 00155 #define qh_ERRsingular 2 /* singular input data */ 00156 #define qh_ERRprec 3 /* precision error */ 00157 #define qh_ERRmem 4 /* insufficient memory, matches mem.h */ 00158 #define qh_ERRqhull 5 /* internal error detected, matches mem.h */ 00159 00160 /* ============ -structures- ==================== 00161 each of the following structures is defined by a typedef 00162 all realT and coordT fields occur at the beginning of a structure 00163 (otherwise space may be wasted due to alignment) 00164 define all flags together and pack into 32-bit number 00165 */ 00166 00167 typedef struct vertexT vertexT; 00168 typedef struct ridgeT ridgeT; 00169 typedef struct facetT facetT; 00170 #ifndef DEFsetT 00171 #define DEFsetT 1 00172 typedef struct setT setT; /* defined in set.h */ 00173 #endif 00174 00175 /*-<a href="qh-c.htm#poly" 00176 >--------------------------------</a><a name="facetT">-</a> 00177 00178 facetT 00179 defines a facet 00180 00181 notes: 00182 qhull() generates the hull as a list of facets. 00183 00184 topological information: 00185 f.previous,next doubly-linked list of facets 00186 f.vertices set of vertices 00187 f.ridges set of ridges 00188 f.neighbors set of neighbors 00189 f.toporient True if facet has top-orientation (else bottom) 00190 00191 geometric information: 00192 f.offset,normal hyperplane equation 00193 f.maxoutside offset to outer plane -- all points inside 00194 f.center centrum for testing convexity 00195 f.simplicial True if facet is simplicial 00196 f.flipped True if facet does not include qh.interior_point 00197 00198 for constructing hull: 00199 f.visible True if facet on list of visible facets (will be deleted) 00200 f.newfacet True if facet on list of newly created facets 00201 f.coplanarset set of points coplanar with this facet 00202 (includes near-inside points for later testing) 00203 f.outsideset set of points outside of this facet 00204 f.furthestdist distance to furthest point of outside set 00205 f.visitid marks visited facets during a loop 00206 f.replace replacement facet for to-be-deleted, visible facets 00207 f.samecycle,newcycle cycle of facets for merging into horizon facet 00208 00209 see below for other flags and fields 00210 */ 00211 struct facetT { 00212 #if !qh_COMPUTEfurthest 00213 coordT furthestdist;/* distance to furthest point of outsideset */ 00214 #endif 00215 #if qh_MAXoutside 00216 coordT maxoutside; /* max computed distance of point to facet 00217 Before QHULLfinished this is an approximation 00218 since maxdist not always set for mergefacet 00219 Actual outer plane is +DISTround and 00220 computed outer plane is +2*DISTround */ 00221 #endif 00222 coordT offset; /* exact offset of hyperplane from origin */ 00223 coordT *normal; /* normal of hyperplane, hull_dim coefficients */ 00224 union { /* in order of testing */ 00225 realT area; /* area of facet, only in io.c if ->isarea */ 00226 facetT *replace; /* replacement facet if ->visible and NEWfacets 00227 is NULL only if qh_mergedegen_redundant or interior */ 00228 facetT *samecycle; /* cycle of facets from the same visible/horizon intersection, 00229 if ->newfacet */ 00230 facetT *newcycle; /* in horizon facet, current samecycle of new facets */ 00231 }f; 00232 coordT *center; /* centrum for convexity, qh CENTERtype == qh_AScentrum */ 00233 /* Voronoi center, qh CENTERtype == qh_ASvoronoi */ 00234 facetT *previous; /* previous facet in the facet_list */ 00235 facetT *next; /* next facet in the facet_list */ 00236 setT *vertices; /* vertices for this facet, inverse sorted by id 00237 if simplicial, 1st vertex was apex/furthest */ 00238 setT *ridges; /* explicit ridges for nonsimplicial facets. 00239 for simplicial facets, neighbors defines ridge */ 00240 setT *neighbors; /* neighbors of the facet. If simplicial, the kth 00241 neighbor is opposite the kth vertex, and the first 00242 neighbor is the horizon facet for the first vertex*/ 00243 setT *outsideset; /* set of points outside this facet 00244 if non-empty, last point is furthest 00245 if NARROWhull, includes coplanars for partitioning*/ 00246 setT *coplanarset; /* set of points coplanar with this facet 00247 > qh.min_vertex and <= facet->max_outside 00248 a point is assigned to the furthest facet 00249 if non-empty, last point is furthest away */ 00250 unsigned visitid; /* visit_id, for visiting all neighbors, 00251 all uses are independent */ 00252 unsigned id; /* unique identifier from qh facet_id */ 00253 unsigned nummerge:9; /* number of merges */ 00254 #define qh_MAXnummerge 511 /* 2^9-1 */ 00255 flagT newfacet:1; /* True if facet on qh newfacet_list (new or merged) */ 00256 flagT visible:1; /* True if visible facet (will be deleted) */ 00257 flagT toporient:1; /* True if created with top orientation 00258 after merging, use ridge orientation */ 00259 flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */ 00260 flagT seen:1; /* used to perform operations only once, like visitid */ 00261 flagT seen2:1; /* used to perform operations only once, like visitid */ 00262 flagT flipped:1; /* True if facet is flipped */ 00263 flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */ 00264 flagT notfurthest:1; /* True if last point of outsideset is not furthest*/ 00265 00266 /*-------- flags primarily for output ---------*/ 00267 flagT good:1; /* True if a facet marked good for output */ 00268 flagT isarea:1; /* True if facet->f.area is defined */ 00269 00270 /*-------- flags for merging ------------------*/ 00271 flagT dupridge:1; /* True if duplicate ridge in facet */ 00272 flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge 00273 ->normal defined (also defined for mergeridge2) */ 00274 flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */ 00275 flagT coplanar:1; /* True if horizon facet is coplanar at last use */ 00276 flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */ 00277 flagT cycledone:1;/* True if mergecycle_all already done */ 00278 flagT tested:1; /* True if facet convexity has been tested (false after merge */ 00279 flagT keepcentrum:1; /* True if keep old centrum after a merge */ 00280 flagT newmerge:1; /* True if facet is newly merged for reducevertices */ 00281 flagT degenerate:1; /* True if facet is degenerate (degen_mergeset) */ 00282 flagT redundant:1; /* True if facet is redundant (degen_mergeset) */ 00283 }; 00284 00285 00286 /*-<a href="qh-c.htm#poly" 00287 >--------------------------------</a><a name="ridgeT">-</a> 00288 00289 ridgeT 00290 defines a ridge 00291 00292 notes: 00293 a ridge is DIM3-1 simplex between two neighboring facets. If the 00294 facets are non-simplicial, there may be more than one ridge between 00295 two facets. E.G. a 4-d hypercube has two triangles between each pair 00296 of neighboring facets. 00297 00298 topological information: 00299 vertices a set of vertices 00300 top,bottom neighboring facets with orientation 00301 00302 geometric information: 00303 tested True if ridge is clearly convex 00304 nonconvex True if ridge is non-convex 00305 */ 00306 struct ridgeT { 00307 setT *vertices; /* vertices belonging to this ridge, inverse sorted by id 00308 NULL if a degen ridge (matchsame) */ 00309 facetT *top; /* top facet this ridge is part of */ 00310 facetT *bottom; /* bottom facet this ridge is part of */ 00311 unsigned id:24; /* unique identifier, =>room for 8 flags */ 00312 flagT seen:1; /* used to perform operations only once */ 00313 flagT tested:1; /* True when ridge is tested for convexity */ 00314 flagT nonconvex:1; /* True if getmergeset detected a non-convex neighbor 00315 only one ridge between neighbors may have nonconvex */ 00316 }; 00317 00318 /*-<a href="qh-c.htm#poly" 00319 >--------------------------------</a><a name="vertexT">-</a> 00320 00321 vertexT 00322 defines a vertex 00323 00324 topological information: 00325 next,previous doubly-linked list of all vertices 00326 neighbors set of adjacent facets (only if qh.VERTEXneighbors) 00327 00328 geometric information: 00329 point array of DIM3 coordinates 00330 */ 00331 struct vertexT { 00332 vertexT *next; /* next vertex in vertex_list */ 00333 vertexT *previous; /* previous vertex in vertex_list */ 00334 pointT *point; /* hull_dim coordinates (coordT) */ 00335 setT *neighbors; /* neighboring facets of vertex, qh_vertexneighbors() 00336 inits in io.c or after first merge */ 00337 unsigned visitid; /* for use with qh vertex_visit */ 00338 unsigned id:24; /* unique identifier, =>room for 8 flags */ 00339 flagT seen:1; /* used to perform operations only once */ 00340 flagT seen2:1; /* another seen flag */ 00341 flagT delridge:1; /* vertex was part of a deleted ridge */ 00342 flagT deleted:1; /* true if vertex on qh del_vertices */ 00343 flagT newlist:1; /* true if vertex on qh newvertex_list */ 00344 }; 00345 00346 /*======= -global variables -qh ============================*/ 00347 00348 extern char qh_version[]; /* defined in unix.c */ 00349 00350 /*-<a href="qh-c.htm#global" 00351 >--------------------------------</a><a name="qh">-</a> 00352 00353 qh 00354 all global variables for qhull are in qh, qhmem, and qhstat 00355 00356 notes: 00357 qhmem is defined in mem.h and qhstat is defined in stat.h 00358 access to qh_qh is via the "qh" macro. See qh_QHpointer in user.h 00359 */ 00360 typedef struct qhT qhT; 00361 #if qh_QHpointer 00362 #define qh qh_qh-> 00363 extern qhT *qh_qh; /* allocated in global.c */ 00364 #else 00365 #define qh qh_qh. 00366 extern qhT qh_qh; 00367 #endif 00368 00369 struct qhT { 00370 00371 /*-<a href="qh-c.htm#global" 00372 >--------------------------------</a><a name="qh-const">-</a> 00373 00374 qh constants 00375 configuration flags and constants for Qhull 00376 00377 notes: 00378 The user configures Qhull by defining flags. They are 00379 copied into qh by qh_setflags(). qh-opt.htm defines the flags. 00380 */ 00381 boolT ALLpoints; /* true 'Qs' if search all points for initial simplex */ 00382 boolT ANGLEmerge; /* true 'Qa' if sort potential merges by angle */ 00383 boolT APPROXhull; /* true 'Wn' if MINoutside set */ 00384 realT MINoutside; /* 'Wn' min. distance for an outside point */ 00385 boolT ATinfinity; /* true 'Qz' if point num_points-1 is "at-infinity" 00386 for improving precision in Delaunay triangulations */ 00387 boolT AVOIDold; /* true 'Q4' if avoid old->new merges */ 00388 boolT BESToutside; /* true 'Qf' if partition points into best outsideset */ 00389 boolT CDDinput; /* true 'Pc' if input uses CDD format (1.0/offset first) */ 00390 boolT CDDoutput; /* true 'PC' if print normals in CDD format (offset first) */ 00391 boolT CHECKfrequently; /* true 'Tc' if checking frequently */ 00392 realT premerge_cos; /* 'A-n' cos_max when pre merging */ 00393 realT postmerge_cos; /* 'An' cos_max when post merging */ 00394 boolT DELAUNAY; /* true 'd' if computing DELAUNAY triangulation */ 00395 boolT DOintersections; /* true 'Gh' if print hyperplane intersections */ 00396 int DROPdim; /* drops dim 'GDn' for 4-d -> 3-d output */ 00397 boolT FORCEoutput; /* true 'Po' if forcing output despite degeneracies */ 00398 int GOODpoint; /* 1+n for 'QGn', good facet if visible/not(-) from point n*/ 00399 pointT *GOODpointp; /* the actual point */ 00400 boolT GOODthreshold; /* true if qh lower_threshold/upper_threshold defined 00401 false if qh SPLITthreshold */ 00402 int GOODvertex; /* 1+n, good facet if vertex for point n */ 00403 pointT *GOODvertexp; /* the actual point */ 00404 boolT HALFspace; /* true 'Hn,n,n' if half-space intersection */ 00405 int IStracing; /* trace execution, 0=none, 1=least, 4=most, -1=events */ 00406 int KEEParea; /* 'PAn' number of largest facets to keep */ 00407 boolT KEEPcoplanar; /* true 'Qc' if keeping nearest facet for coplanar points */ 00408 boolT KEEPinside; /* true 'Qi' if keeping nearest facet for inside points 00409 set automatically if 'd Qc' */ 00410 int KEEPmerge; /* 'PMn' number of facets to keep with most merges */ 00411 realT KEEPminArea; /* 'PFn' minimum facet area to keep */ 00412 realT MAXcoplanar; /* 'Un' max distance below a facet to be coplanar*/ 00413 boolT MERGEexact; /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */ 00414 boolT MERGEindependent; /* true 'Q2' if merging independent sets */ 00415 boolT MERGING; /* true if exact-, pre- or post-merging, with angle and centrum tests */ 00416 realT premerge_centrum; /* 'C-n' centrum_radius when pre merging. Default is round-off */ 00417 realT postmerge_centrum; /* 'Cn' centrum_radius when post merging. Default is round-off */ 00418 boolT MERGEvertices; /* true 'Q3' if merging redundant vertices */ 00419 realT MINvisible; /* 'Vn' min. distance for a facet to be visible */ 00420 boolT NOnearinside; /* true 'Q8' if ignore near-inside points when partitioning */ 00421 boolT NOpremerge; /* true 'Q0' if no defaults for C-0 or Qx */ 00422 boolT ONLYgood; /* true 'Qg' if process points with good visible or horizon facets */ 00423 boolT ONLYmax; /* true 'Qm' if only process points that increase max_outside */ 00424 boolT PICKfurthest; /* true 'Q9' if process furthest of furthest points*/ 00425 boolT POSTmerge; /* true if merging after buildhull (Cn or An) */ 00426 boolT PREmerge; /* true if merging during buildhull (C-n or A-n) */ 00427 /* NOTE: some of these names are similar to qh_PRINT names */ 00428 boolT PRINTcentrums; /* true 'Gc' if printing centrums */ 00429 boolT PRINTcoplanar; /* true 'Gp' if printing coplanar points */ 00430 int PRINTdim; /* print dimension for Geomview output */ 00431 boolT PRINTdots; /* true 'Ga' if printing all points as dots */ 00432 boolT PRINTgood; /* true 'Pg' if printing good facets */ 00433 boolT PRINTinner; /* true 'Gi' if printing inner planes */ 00434 boolT PRINTneighbors; /* true 'PG' if printing neighbors of good facets */ 00435 boolT PRINTnoplanes; /* true 'Gn' if printing no planes */ 00436 boolT PRINToptions1st; /* true 'FO' if printing options to stderr */ 00437 boolT PRINTouter; /* true 'Go' if printing outer planes */ 00438 boolT PRINTprecision; /* false 'Pp' if not reporting precision problems */ 00439 qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */ 00440 boolT PRINTridges; /* true 'Gr' if print ridges */ 00441 boolT PRINTspheres; /* true 'Gv' if print vertices as spheres */ 00442 boolT PRINTstatistics; /* true 'Ts' if printing statistics to stderr */ 00443 boolT PRINTsummary; /* true 's' if printing summary to stderr */ 00444 boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */ 00445 boolT PROJECTdelaunay; /* true if DELAUNAY, no readpoints() and 00446 need projectinput() for Delaunay in qh_init_B */ 00447 int PROJECTinput; /* number of projected dimensions 'bn:0Bn:0' */ 00448 boolT QUICKhelp; /* true if quick help message for degen input */ 00449 boolT RANDOMdist; /* true if randomly change distplane and setfacetplane */ 00450 realT RANDOMfactor; /* maximum random perturbation */ 00451 realT RANDOMa; /* qh_randomfactor is randr * RANDOMa + RANDOMb */ 00452 realT RANDOMb; 00453 boolT RANDOMoutside; /* true if select a random outside point */ 00454 int REPORTfreq; /* buildtracing reports every n facets */ 00455 int REPORTfreq2; /* tracemerging reports every REPORTfreq/2 facets */ 00456 int RERUN; /* 'TRn' rerun qhull n times (qh.build_cnt) */ 00457 int ROTATErandom; /* 'QRn' seed, 0 time, >= rotate input */ 00458 boolT SCALEinput; /* true 'Qbk' if scaling input */ 00459 boolT SCALElast; /* true 'Qbb' if scale last coord to max prev coord */ 00460 boolT SETroundoff; /* true 'E' if qh DISTround is predefined */ 00461 boolT SKIPcheckmax; /* true 'Q5' if skip qh_check_maxout */ 00462 boolT SKIPconvex; /* true 'Q6' if skip convexity testing during pre-merge */ 00463 boolT SPLITthresholds; /* true if upper_/lower_threshold defines a region 00464 used only for printing (not for qh ONLYgood) */ 00465 int STOPcone; /* 'TCn' 1+n for stopping after cone for point n*/ 00466 /* also used by qh_build_withresart for err exit*/ 00467 int STOPpoint; /* 'TVn' 'TV-n' 1+n for stopping after/before(-) 00468 adding point n */ 00469 boolT TESTvneighbors; /* true 'Qv' if test vertex neighbors at end */ 00470 int TRACElevel; /* 'Tn' conditional IStracing level */ 00471 int TRACElastrun; /* qh.TRACElevel applies to last qh.RERUN */ 00472 int TRACEpoint; /* 'TPn' start tracing when point n is a vertex */ 00473 realT TRACEdist; /* 'TWn' start tracing when merge distance too big */ 00474 int TRACEmerge; /* 'TMn' start tracing before this merge */ 00475 boolT UPPERdelaunay; /* true 'Qu' if computing furthest-site Delaunay */ 00476 boolT VERIFYoutput; /* true 'Tv' if verify output at end of qhull */ 00477 boolT VIRTUALmemory; /* true 'Q7' if depth-first processing in buildhull */ 00478 boolT VORONOI; /* true 'v' if computing Voronoi diagram */ 00479 00480 /*--------input constants ---------*/ 00481 realT AREAfactor; /* 1/(hull_dim-1)! for converting det's to area */ 00482 boolT DOcheckmax; /* true if calling qh_check_maxout (qh_initqhull_globals) */ 00483 char *feasible_string; /* feasible point 'Hn,n,n' for half-space intersection */ 00484 coordT *feasible_point; /* as coordinates, both malloc'd */ 00485 boolT GETarea; /* true if need to compute facet areas in io.c */ 00486 boolT KEEPnearinside; /* true if near-inside points in coplanarset */ 00487 int hull_dim; /* dimension of hull, set by initbuffers */ 00488 int input_dim; /* dimension of input, set by initbuffers */ 00489 int num_points; /* number of input points */ 00490 pointT *first_point; /* array of input points, see POINTSmalloc */ 00491 boolT POINTSmalloc; /* true if qh first_point/num_points allocated */ 00492 pointT *input_points; /* copy of original qh.first_point for input points for qh_joggleinput */ 00493 boolT input_malloc; /* true if qh input_points malloc'd */ 00494 char qhull_command[256];/* command line that invoked this program */ 00495 char rbox_command[256]; /* command line that produced the input points */ 00496 char qhull_options[512];/* descriptive list of options */ 00497 int qhull_optionlen; /* length of last line */ 00498 int qhull_optionsiz; /* size of qhull_options before qh_initbuild */ 00499 boolT VERTEXneighbors; /* true if maintaining vertex neighbors */ 00500 boolT ZEROcentrum; /* true if 'C-0' or 'C-0 Qx'. sets ZEROall_ok */ 00501 realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k] 00502 must set either GOODthreshold or SPLITthreshold 00503 if Delaunay, default is 0.0 for upper envelope */ 00504 realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */ 00505 realT *upper_bound; /* scale point[k] to new upper bound */ 00506 realT *lower_bound; /* scale point[k] to new lower bound 00507 project if both upper_ and lower_bound == 0 */ 00508 00509 /*-<a href="qh-c.htm#global" 00510 >--------------------------------</a><a name="qh-prec">-</a> 00511 00512 qh precision constants 00513 precision constants for Qhull 00514 00515 notes: 00516 qh_detroundoff() computes the maximum roundoff error for distance 00517 and other computations. It also sets default values for the 00518 qh constants above. 00519 */ 00520 realT ANGLEround; /* max round off error for angles */ 00521 realT centrum_radius; /* max centrum radius for convexity (roundoff added) */ 00522 realT cos_max; /* max cosine for convexity (roundoff added) */ 00523 realT DISTround; /* max round off error for distances, 'E' overrides */ 00524 realT MAXabs_coord; /* max absolute coordinate */ 00525 realT MAXlastcoord; /* max last coordinate for qh_scalelast */ 00526 realT MAXsumcoord; /* max sum of coordinates */ 00527 realT MAXwidth; /* max rectilinear width of point coordinates */ 00528 realT MINdenom_1; /* min. abs. value for 1/x */ 00529 realT MINdenom; /* use divzero if denominator < MINdenom */ 00530 realT MINdenom_1_2; /* min. abs. val for 1/x that allows normalization */ 00531 realT MINdenom_2; /* use divzero if denominator < MINdenom_2 */ 00532 realT MINlastcoord; /* min. last coordinate for qh_scalelast */ 00533 realT MINnorm; /* min. norm for not redoing qh_sethyperplane_det */ 00534 boolT NARROWhull; /* set in qh_initialhull if angle < qh_MAXnarrow */ 00535 realT *NEARzero; /* hull_dim array for near zero in gausselim */ 00536 realT NEARinside; /* keep points for qh_check_maxout if close to facet */ 00537 realT ONEmerge; /* max distance for merging simplicial facets */ 00538 realT outside_err; /* application's epsilon for coplanar points 00539 qh_check_bestdist() qh_check_points() reports error if point outside */ 00540 realT WIDEfacet; /* size of wide facet for skipping ridge in 00541 area computation and locking centrum */ 00542 00543 /*-<a href="qh-c.htm#global" 00544 >--------------------------------</a><a name="qh-intern">-</a> 00545 00546 qh internal constants 00547 internal constants for Qhull 00548 */ 00549 char qhull[sizeof("qhull")]; /* for checking ownership */ 00550 void *old_stat; /* pointer to saved qh_qhstat, qh_save_qhull */ 00551 jmp_buf errexit; /* exit label for qh_errexit, defined by setjmp() */ 00552 char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */ 00553 jmp_buf restartexit; /* restart label for qh_errexit, defined by setjmp() */ 00554 char jmpXtra2[40]; /* extra bytes in case jmp_buf is defined wrong by compiler*/ 00555 FILE *fin; /* pointer to input file, init by qh_meminit */ 00556 FILE *fout; /* pointer to output file */ 00557 FILE *ferr; /* pointer to error file */ 00558 pointT *interior_point; /* center point of the initial simplex*/ 00559 int normal_size; /* size in bytes for facet normals and point coords*/ 00560 int center_size; /* size in bytes for Voronoi centers */ 00561 int TEMPsize; /* size for small, temporary sets (in quick mem) */ 00562 00563 /*-<a href="qh-c.htm#global" 00564 >--------------------------------</a><a name="qh-lists">-</a> 00565 00566 qh facet and vertex lists 00567 defines lists of facets, new facets, visible facets, vertices, and 00568 new vertices. Includes counts, next ids, and trace ids. 00569 see: 00570 qh_resetlists() 00571 */ 00572 facetT *facet_list; /* first facet */ 00573 facetT *facet_tail; /* end of facet_list (dummy facet) */ 00574 facetT *facet_next; /* next facet for buildhull() 00575 all previous facets do not have outside sets*/ 00576 facetT *newfacet_list; /* list of new facets to end of facet_list */ 00577 facetT *visible_list; /* list of visible facets preceeding newfacet_list, 00578 facet->visible set */ 00579 int num_visible; /* current number of visible facets */ 00580 unsigned tracefacet_id; /* set at init, then can print whenever */ 00581 facetT *tracefacet; /* set in newfacet/mergefacet, undone in delfacet*/ 00582 unsigned tracevertex_id; /* set at buildtracing, can print whenever */ 00583 vertexT *tracevertex; /* set in newvertex, undone in delvertex*/ 00584 vertexT *vertex_list; /* list of all vertices, to vertex_tail */ 00585 vertexT *vertex_tail; 00586 vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail 00587 all vertices have 'newlist' set */ 00588 int num_facets; /* number of facets in facet_list 00589 includes visble faces (num_visible) */ 00590 int num_vertices; /* number of vertices in facet_list */ 00591 int num_outside; /* number of points in outsidesets (for tracing) */ 00592 int num_good; /* number of good facets (after findgood_all) */ 00593 unsigned facet_id; /* id of next, new facet from newfacet() */ 00594 unsigned ridge_id; /* id of next, new ridge from newridge() */ 00595 unsigned vertex_id; /* id of next, new vertex from newvertex() */ 00596 00597 /*-<a href="qh-c.htm#global" 00598 >--------------------------------</a><a name="qh-var">-</a> 00599 00600 qh global variables 00601 defines minimum and maximum distances, next visit ids, several flags, 00602 and other global variables. 00603 initialize in qh_initbuild or qh_maxmin if used in qh_buildhull 00604 */ 00605 unsigned long hulltime; /* ignore time to set up input and randomize */ 00606 /* use unsigned to avoid wrap-around errors */ 00607 boolT ALLOWrestart; /* true if qh_precision can use qh.restartexit */ 00608 int build_cnt; /* number of calls to qh_initbuild */ 00609 qh_CENTER CENTERtype; /* current type of facet->center, qh_CENTER */ 00610 int furthest_id; /* pointid of furthest point, for tracing */ 00611 facetT *GOODclosest; /* closest facet to GOODthreshold in qh_findgood */ 00612 realT JOGGLEmax; /* set 'QJn' if randomly joggle input */ 00613 boolT maxoutdone; /* set qh_check_maxout(), cleared by qh_addpoint() */ 00614 realT max_outside; /* maximum distance from a point to a facet, 00615 before roundoff, not simplicial vertices 00616 actual outer plane is +DISTround and 00617 computed outer plane is +2*DISTround */ 00618 realT max_vertex; /* maximum distance (>0) from vertex to a facet, 00619 before roundoff, due to a merge */ 00620 realT min_vertex; /* minimum distance (<0) from vertex to a facet, 00621 before roundoff, due to a merge 00622 if qh.JOGGLEmax, qh_makenewplanes sets it 00623 recomputed if qh.DOcheckmax, default -qh.DISTround */ 00624 boolT NEWfacets; /* true while visible facets invalid due to new or merge 00625 from makecone/attachnewfacets to deletevisible */ 00626 boolT findbestnew; /* true if partitioning calls qh_findbestnew */ 00627 boolT findbest_notsharp; /* true if new facets are at least 90 degrees */ 00628 boolT NOerrexit; /* true if qh.errexit is not available */ 00629 realT PRINTcradius; /* radius for printing centrums */ 00630 realT PRINTradius; /* radius for printing vertex spheres and points */ 00631 boolT POSTmerging; /* true when post merging */ 00632 int printoutvar; /* temporary variable for qh_printbegin, etc. */ 00633 int printoutnum; /* number of facets printed */ 00634 boolT QHULLfinished; /* True after qhull() is finished */ 00635 realT totarea; /* total facet area computed by qh_getarea */ 00636 realT totvol; /* total volume computed by qh_getarea */ 00637 unsigned int visit_id; /* unique id for searching neighborhoods, */ 00638 unsigned int vertex_visit; /* unique id for searching vertices */ 00639 boolT ZEROall_ok; /* True if qh_checkzero always succeeds */ 00640 boolT WAScoplanar; /* True if qh_partitioncoplanar (qh_check_maxout) */ 00641 00642 /*-<a href="qh-c.htm#global" 00643 >--------------------------------</a><a name="qh-set">-</a> 00644 00645 qh global sets 00646 defines sets for merging, initial simplex, hashing, extra input points, 00647 and deleted vertices 00648 */ 00649 setT *facet_mergeset; /* temporary set of merges to be done */ 00650 setT *degen_mergeset; /* temporary set of degenerate and redundant merges */ 00651 setT *hash_table; /* hash table for matching ridges in qh_matchfacets 00652 size is setsize() */ 00653 setT *other_points; /* additional points (first is qh interior_point) */ 00654 setT *del_vertices; /* vertices to partition and delete with visible 00655 facets. Have deleted set for checkfacet */ 00656 00657 /*-<a href="qh-c.htm#global" 00658 >--------------------------------</a><a name="qh-buf">-</a> 00659 00660 qh global buffers 00661 defines buffers for maxtrix operations, input, and error messages 00662 */ 00663 coordT *gm_matrix; /* (dim+1)Xdim matrix for geom.c */ 00664 coordT **gm_row; /* array of gm_matrix rows */ 00665 char* line; /* malloc'd input line of maxline+1 chars */ 00666 int maxline; 00667 coordT *half_space; /* malloc'd input array for halfspace (qh normal_size+coordT) */ 00668 coordT *temp_malloc; /* malloc'd input array for points */ 00669 00670 /*-<a href="qh-c.htm#global" 00671 >--------------------------------</a><a name="qh-static">-</a> 00672 00673 qh static variables 00674 defines static variables for individual functions 00675 00676 notes: 00677 do not use 'static' within a function. Multiple instances of qhull 00678 may exist. 00679 00680 do not assume zero initialization, 'QPn' may cause a restart 00681 */ 00682 boolT ERREXITcalled; /* true during errexit (prevents duplicate calls */ 00683 boolT firstcentrum; /* for qh_printcentrum */ 00684 realT last_low; /* qh_scalelast parameters for qh_setdelaunay */ 00685 realT last_high; 00686 realT last_newhigh; 00687 unsigned lastreport; /* for qh_buildtracing */ 00688 int mergereport; /* for qh_tracemerging */ 00689 boolT old_randomdist; /* save RANDOMdist when io, tracing, or statistics */ 00690 int ridgeoutnum; /* number of ridges in 4OFF output */ 00691 void *old_qhstat; /* for saving qh_qhstat in save_qhull() */ 00692 setT *old_tempstack; /* for saving qhmem.tempstack in save_qhull */ 00693 setT *searchset; /* set of facets for searching in qh_findbest() */ 00694 int rand_seed; /* for qh_rand/qh_srand */ 00695 }; 00696 00697 /*=========== -macros- =========================*/ 00698 00699 /*-<a href="qh-c.htm#poly" 00700 >--------------------------------</a><a name="otherfacet_">-</a> 00701 00702 otherfacet_(ridge, facet) 00703 return neighboring facet for a ridge in facet 00704 */ 00705 #define otherfacet_(ridge, facet) \ 00706 (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top) 00707 00708 /*-<a href="qh-c.htm#poly" 00709 >--------------------------------</a><a name="getid_">-</a> 00710 00711 getid_(p) 00712 return id for facet, ridge, or vertex 00713 return MAXINT if NULL (-1 causes type conversion error ) 00714 */ 00715 #define getid_(p) ((p) ? (p)->id : -1) 00716 00717 /*============== FORALL macros ===================*/ 00718 00719 /*-<a href="qh-c.htm#poly" 00720 >--------------------------------</a><a name="FORALLfacets">-</a> 00721 00722 FORALLfacets { ... } 00723 assign 'facet' to each facet in qh.facet_list 00724 00725 notes: 00726 uses 'facetT *facet;' 00727 assumes last facet is a sentinel 00728 00729 see: 00730 FORALLfacet_( facetlist ) 00731 */ 00732 #define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next) 00733 00734 /*-<a href="qh-c.htm#poly" 00735 >--------------------------------</a><a name="FORALLpoints">-</a> 00736 00737 FORALLpoints { ... } 00738 assign 'point' to each point in qh.first_point, qh.num_points 00739 00740 declare: 00741 coordT *point, *pointtemp; 00742 */ 00743 #define FORALLpoints FORALLpoint_(qh first_point, qh num_points) 00744 00745 /*-<a href="qh-c.htm#poly" 00746 >--------------------------------</a><a name="FORALLpoint_">-</a> 00747 00748 FORALLpoint_( points, num) { ... } 00749 assign 'point' to each point in points array of num points 00750 00751 declare: 00752 coordT *point, *pointtemp; 00753 */ 00754 #define FORALLpoint_(points, num) for(point= (points), \ 00755 pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim) 00756 00757 /*-<a href="qh-c.htm#poly" 00758 >--------------------------------</a><a name="FORALLvertices">-</a> 00759 00760 FORALLvertices { ... } 00761 assign 'vertex' to each vertex in qh.vertex_list 00762 00763 declare: 00764 vertexT *vertex; 00765 00766 notes: 00767 assumes qh.vertex_list terminated with a sentinel 00768 */ 00769 #define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next) 00770 00771 /*-<a href="qh-c.htm#poly" 00772 >--------------------------------</a><a name="FOREACHfacet_">-</a> 00773 00774 FOREACHfacet_( facets ) { ... } 00775 assign 'facet' to each facet in facets 00776 00777 declare: 00778 facetT *facet, **facetp; 00779 00780 see: 00781 <a href="set.h#FOREACHsetelement_">FOREACHsetelement_</a> 00782 */ 00783 #define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet) 00784 00785 /*-<a href="qh-c.htm#poly" 00786 >--------------------------------</a><a name="FOREACHneighbor_">-</a> 00787 00788 FOREACHneighbor_( facet ) { ... } 00789 assign 'neighbor' to each neighbor in facet->neighbors 00790 00791 FOREACHneighbor_( vertex ) { ... } 00792 assign 'neighbor' to each neighbor in vertex->neighbors 00793 00794 declare: 00795 facetT *neighbor, **neighborp; 00796 00797 see: 00798 <a href="set.h#FOREACHsetelement_">FOREACHsetelement_</a> 00799 */ 00800 #define FOREACHneighbor_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighbor) 00801 00802 /*-<a href="qh-c.htm#poly" 00803 >--------------------------------</a><a name="FOREACHpoint_">-</a> 00804 00805 FOREACHpoint_( points ) { ... } 00806 assign 'point' to each point in points set 00807 00808 declare: 00809 pointT *point, **pointp; 00810 00811 see: 00812 <a href="set.h#FOREACHsetelement_">FOREACHsetelement_</a> 00813 */ 00814 #define FOREACHpoint_(points) FOREACHsetelement_(pointT, points, point) 00815 00816 /*-<a href="qh-c.htm#poly" 00817 >--------------------------------</a><a name="FOREACHridge_">-</a> 00818 00819 FOREACHridge_( ridges ) { ... } 00820 assign 'ridge' to each ridge in ridges set 00821 00822 declare: 00823 ridgeT *ridge, **ridgep; 00824 00825 see: 00826 <a href="set.h#FOREACHsetelement_">FOREACHsetelement_</a> 00827 */ 00828 #define FOREACHridge_(ridges) FOREACHsetelement_(ridgeT, ridges, ridge) 00829 00830 /*-<a href="qh-c.htm#poly" 00831 >--------------------------------</a><a name="FOREACHvertex_">-</a> 00832 00833 FOREACHvertex_( vertices ) { ... } 00834 assign 'vertex' to each vertex in vertices set 00835 00836 declare: 00837 vertexT *vertex, **vertexp; 00838 00839 see: 00840 <a href="set.h#FOREACHsetelement_">FOREACHsetelement_</a> 00841 */ 00842 #define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex) 00843 00844 /*-<a href="qh-c.htm#poly" 00845 >--------------------------------</a><a name="FOREACHfacet_i_">-</a> 00846 00847 FOREACHfacet_i_( facets ) { ... } 00848 assign 'facet' and 'facet_i' for each facet in facets set 00849 00850 declare: 00851 facetT *facet; 00852 int facet_n, facet_i; 00853 00854 see: 00855 <a href="set.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a> 00856 */ 00857 #define FOREACHfacet_i_(facets) FOREACHsetelement_i_(facetT, facets, facet) 00858 00859 /*-<a href="qh-c.htm#poly" 00860 >--------------------------------</a><a name="FOREACHneighbor_i_">-</a> 00861 00862 FOREACHneighbor_i_( facet ) { ... } 00863 assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors 00864 00865 FOREACHneighbor_i_( vertex ) { ... } 00866 assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors 00867 00868 declare: 00869 facetT *neighbor; 00870 int neighbor_n, neighbor_i; 00871 00872 see: 00873 <a href="set.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a> 00874 */ 00875 #define FOREACHneighbor_i_(facet) FOREACHsetelement_i_(facetT, facet->neighbors, neighbor) 00876 00877 /*-<a href="qh-c.htm#poly" 00878 >--------------------------------</a><a name="FOREACHpoint_i_">-</a> 00879 00880 FOREACHpoint_i_( points ) { ... } 00881 assign 'point' and 'point_i' for each point in points set 00882 00883 declare: 00884 pointT *point; 00885 int point_n, point_i; 00886 00887 see: 00888 <a href="set.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a> 00889 */ 00890 #define FOREACHpoint_i_(points) FOREACHsetelement_i_(pointT, points, point) 00891 00892 /*-<a href="qh-c.htm#poly" 00893 >--------------------------------</a><a name="FOREACHridge_i_">-</a> 00894 00895 FOREACHridge_i_( ridges ) { ... } 00896 assign 'ridge' and 'ridge_i' for each ridge in ridges set 00897 00898 declare: 00899 ridgeT *ridge; 00900 int ridge_n, ridge_i; 00901 00902 see: 00903 <a href="set.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a> 00904 */ 00905 #define FOREACHridge_i_(ridges) FOREACHsetelement_i_(ridgeT, ridges, ridge) 00906 00907 /*-<a href="qh-c.htm#poly" 00908 >--------------------------------</a><a name="FOREACHvertex_i_">-</a> 00909 00910 FOREACHvertex_i_( vertices ) { ... } 00911 assign 'vertex' and 'vertex_i' for each vertex in vertices set 00912 00913 declare: 00914 vertexT *vertex; 00915 int vertex_n, vertex_i; 00916 00917 see: 00918 <a href="set.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a> 00919 */ 00920 #define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex) 00921 00922 /********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/ 00923 00924 void qh_qhull (void); 00925 boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist); 00926 void qh_printsummary(FILE *fp); 00927 00928 /********* -user.c prototypes (alphabetical) **********************/ 00929 00930 void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge); 00931 void qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex); 00932 void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall); 00933 void qh_user_memsizes (void); 00934 00935 /***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/ 00936 00937 facetT *qh_findbest (pointT *point, facetT *startfacet, 00938 boolT bestoutside, boolT newfacets, boolT noupper, 00939 realT *dist, boolT *isoutside, int *numpart); 00940 facetT *qh_findbestnew (pointT *point, facetT *startfacet, 00941 realT *dist, boolT *isoutside, int *numpart); 00942 boolT qh_gram_schmidt(int dim, realT **rows); 00943 void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane); 00944 void qh_printsummary(FILE *fp); 00945 void qh_projectinput (void); 00946 void qh_randommatrix (realT *buffer, int dim, realT **row); 00947 void qh_rotateinput (realT **rows); 00948 void qh_scaleinput (void); 00949 void qh_setdelaunay (int dim, int count, pointT *points); 00950 coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible); 00951 00952 /***** -global.c prototypes (alphabetical) ***********************/ 00953 00954 void qh_freebuffers (void); 00955 void qh_freeqhull (boolT allmem); 00956 void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]); 00957 void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc); 00958 void qh_init_qhull_command (int argc, char *argv[]); 00959 void qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc); 00960 void qh_initflags (char *command); 00961 void qh_initqhull_buffers (void); 00962 void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc); 00963 void qh_initqhull_mem (void); 00964 void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile); 00965 void qh_initthresholds (char *command); 00966 #if qh_QHpointer 00967 void qh_restore_qhull (qhT **oldqh); 00968 qhT *qh_save_qhull (void); 00969 #endif 00970 00971 /***** -io.c prototypes (duplicated from io.h) ***********************/ 00972 00973 void dfacet( unsigned id); 00974 void dvertex( unsigned id); 00975 void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall); 00976 void qh_produce_output(void); 00977 coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc); 00978 00979 00980 /********* -mem.c prototypes (duplicated from mem.h) **********************/ 00981 00982 void qh_meminit (FILE *ferr); 00983 void qh_memfreeshort (int *curlong, int *totlong); 00984 00985 /********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/ 00986 00987 void qh_check_output (void); 00988 void qh_check_points (void); 00989 setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets); 00990 facetT *qh_findbestfacet (pointT *point, boolT bestoutside, 00991 realT *bestdist, boolT *isoutside); 00992 vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp); 00993 pointT *qh_point (int id); 00994 setT *qh_pointfacet (void /*qh.facet_list*/); 00995 int qh_pointid (pointT *point); 00996 setT *qh_pointvertex (void /*qh.facet_list*/); 00997 void qh_setvoronoi_all (void); 00998 00999 /********* -stat.c prototypes (duplicated from stat.h) **********************/ 01000 01001 void qh_collectstatistics (void); 01002 void qh_printallstatistics (FILE *fp, char *string); 01003 01004 #endif /* qhDEFqhull */