?? global.c
字號:
qh_errexit (qh_ERRinput, NULL, NULL); }#endif if (qh MERGING && !qh POSTmerge && qh premerge_cos > REALmax/2 && (qh premerge_centrum == 0 || qh premerge_centrum > REALmax/2)) { qh ZEROcentrum= True; qh ZEROall_ok= True; } if ((qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY) && !(qh PRINTgood || qh PRINTneighbors)) { qh PRINTgood= True; qh_option ("Pgood", NULL, NULL); } if (qh DELAUNAY && qh HALFspace) { fprintf (qh ferr, "qhull input error: can not use Delaunay ('d') or Voronoi ('v') with halfspace intersection ('H')\n"); qh_errexit (qh_ERRinput, NULL, NULL); } if (!qh DELAUNAY && !qh ATinfinity) { fprintf (qh ferr, "qhull input error: use upper-hull ('Qu') with Delaunay ('d') or Voronoi ('v')\n"); qh_errexit (qh_ERRinput, NULL, NULL); } qh DOcheckmax= (!qh FORCEoutput && !qh SKIPcheckmax && (qh MERGING || qh APPROXhull)); qh KEEPnearinside= (qh DOcheckmax && !(qh KEEPinside && qh KEEPcoplanar) && !qh NOnearinside); if (qh MERGING) qh CENTERtype= qh_AScentrum; else if (qh VORONOI) qh CENTERtype= qh_ASvoronoi; if (qh TESTvneighbors && !qh MERGING) { fprintf(qh ferr, "qhull input error: test vertex neighbors ('Qv') needs a merge option\n"); qh_errexit (qh_ERRinput, NULL ,NULL); } if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay)) { qh hull_dim -= qh PROJECTinput; if (qh DELAUNAY) { qh hull_dim++; extra= 1; } } if (qh hull_dim <= 1) { fprintf(qh ferr, "qhull error: dimension %d must be > 1\n", qh hull_dim); qh_errexit (qh_ERRinput, NULL, NULL); } for (k= 2, factorial=1.0; k < qh hull_dim; k++) factorial *= k; qh AREAfactor= 1.0 / factorial; trace2((qh ferr, "qh_initqhull_globals: initialize globals. dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n", dim, numpoints, ismalloc, qh PROJECTinput, qh hull_dim)); qh normal_size= qh hull_dim * sizeof(coordT); qh center_size= qh normal_size - sizeof(coordT); pointsneeded= qh hull_dim+1; if (qh hull_dim > qh_DIMmergeVertex) { qh MERGEvertices= False; qh_option ("Q3-no-merge-vertices-dim-high", NULL, NULL); } if (qh GOODpoint) pointsneeded++; if (qh GOODpoint > 0) qh GOODpointp= qh_point (qh GOODpoint-1); else if (qh GOODpoint < 0) qh GOODpointp= qh_point (-qh GOODpoint-1); if (qh GOODvertex > 0) qh GOODvertexp= qh_point (qh GOODvertex-1); else if (qh GOODvertex < 0) qh GOODvertexp= qh_point (-qh GOODvertex-1); if ((qh GOODpoint && (qh GOODpointp < qh first_point /* also catches !GOODpointp */ || qh GOODpointp > qh_point (qh num_points-1))) || (qh GOODvertex && (qh GOODvertexp < qh first_point /* also catches !GOODvertexp */ || qh GOODvertexp > qh_point (qh num_points-1)))) { fprintf (qh ferr, "qhull input error: either QGn or QVn point is > p%d\n", qh num_points-1); qh_errexit (qh_ERRinput, NULL, NULL); } if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) { qh TRACElevel= (qh IStracing? qh IStracing : 3); qh IStracing= 0; }#ifdef qh_NOtrace if (qh IStracing || qh TRACElevel) { fprintf (qh ferr, "qhull input error: tracing is not installed (qh_NOtrace in user.h)"); qh_errexit (qh_ERRqhull, NULL, NULL); } #endif if (qh ROTATErandom == 0 || qh ROTATErandom == -1) { seed= time (&timedata); if (!qh ROTATErandom) qh_option ("QRotate-random", &seed, NULL); qh ROTATErandom= seed; }else if (qh ROTATErandom > 0) seed= qh ROTATErandom; else seed= 1; qh_RANDOMseed_(seed); randr= 0.0; for (i= 1000; i--; ) { randi= qh_RANDOMint; randr += randi; if (randi > qh_RANDOMmax) { fprintf (qh ferr, "\qhull configuration error (qh_RANDOMmax in user.h):\n\ random integer %d > qh_RANDOMmax (%.8g)\n", randi, qh_RANDOMmax); qh_errexit (qh_ERRinput, NULL, NULL); } } if (randr/1000 < qh_RANDOMmax/10) fprintf (qh ferr, "\qhull configuration warning (qh_RANDOMmax in user.h):\n\ average of 1000 randoms %.2g much less than expected (%.2g).\n\ Is qh_RANDOMmax wrong?\n", randr/1000, qh_RANDOMmax/2); qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax; qh RANDOMb= 1.0 - qh RANDOMfactor; if (qh_HASHfactor < 1.1) { fprintf(qh ferr, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1. Qhull uses linear hash probing\n", qh_HASHfactor); qh_errexit (qh_ERRqhull, NULL, NULL); } if (numpoints+extra < pointsneeded) { fprintf(qh ferr,"qhull input error: not enough points (%d) to construct initial simplex (need %d)\n", numpoints, pointsneeded); qh_errexit(qh_ERRinput, NULL, NULL); } for (i= qh_PRINTEND; i--; ) { if (qh PRINTout[i] == qh_PRINTgeom) printgeom= True; else if (qh PRINTout[i] == qh_PRINTmathematica) printmath= True; else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) { fprintf (qh ferr, "qhull input error: option 'Fp' is used for halfspace intersect ('Hn,n,n')\n"); qh_errexit (qh_ERRinput, NULL, NULL); }else if (qh PRINTout[i] == qh_PRINTpointnearest && !qh KEEPcoplanar && !qh KEEPinside) fprintf (qh ferr, "qhull input warning: option 'FP' needs option 'Qc' or 'Qi' to record the points\n"); else if (qh PRINTout[i] == qh_PRINTcentrums && qh VORONOI) { fprintf (qh ferr, "qhull input error: option 'Fc' is not available for Voronoi vertices ('v')\n"); qh_errexit (qh_ERRinput, NULL, NULL); } } if (printmath && (qh hull_dim > 3 || qh VORONOI || qh HALFspace)) { fprintf (qh ferr, "qhull input error: Mathematica output is only available for 2-d and 3-d convex hulls and Delaunay triangulations\n"); qh_errexit (qh_ERRinput, NULL, NULL); } if (printgeom) { if (qh hull_dim > 4) { fprintf (qh ferr, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n"); qh_errexit (qh_ERRinput, NULL, NULL); } if (qh PRINTnoplanes && !(qh PRINTcoplanar + qh PRINTcentrums + qh PRINTdots + qh PRINTspheres + qh DOintersections + qh PRINTridges)) { fprintf (qh ferr, "qhull input error: no output specified for Geomview\n"); qh_errexit (qh_ERRinput, NULL, NULL); } if (qh VORONOI && (qh hull_dim > 3 || qh DROPdim >= 0)) { fprintf (qh ferr, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n"); qh_errexit (qh_ERRinput, NULL, NULL); } if (qh hull_dim == 4 && qh DROPdim == -1 && (qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) { fprintf (qh ferr, "qhull input warning: coplanars, vertices, and centrums output not\n\available for 4-d output (ignored). Could use 'GDn' instead.\n"); qh PRINTcoplanar= qh PRINTspheres= qh PRINTcentrums= False; } } qh PRINTdim= qh hull_dim; if (qh DROPdim >=0) { /* after Geomview checks */ if (qh DROPdim < qh hull_dim) { qh PRINTdim--; if (!printgeom || qh hull_dim < 3) fprintf (qh ferr, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim); }else qh DROPdim= -1; }else if (qh VORONOI) { qh DROPdim= qh hull_dim-1; qh PRINTdim= qh hull_dim-1; }} /* initqhull_globals */ /*------------------------------------------------------initqhull_mem- initialize mem.c for qhull qh.hull_dim and normal_size determines some of the allocation sizes if qh MERGING, includes ridgeTreturns: mem.c already for memalloc/memfree (errors if called beforehand)notes: the user can add up to 10 additional sizes for quick allocation (increase numsizes) print out memsizes in qh_produceoutput*/void qh_initqhull_mem (void) { int numsizes; int i; numsizes= 8+10; qh_meminitbuffers (qh IStracing, qh_MEMalign, numsizes, qh_MEMbufsize,qh_MEMinitbuf); qh_memsize(sizeof(vertexT)); if (qh MERGING) { qh_memsize(sizeof(ridgeT)); qh_memsize(sizeof(mergeT)); } qh_memsize(sizeof(facetT)); qh_memsize(sizeof(hashentryT)); i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize; /* ridge.vertices */ qh_memsize(i); qh_memsize(qh normal_size); /* normal */ i += SETelemsize; /* facet.vertices, .ridges, .neighbors */ qh_memsize(i); qh_user_memsizes(); qh_memsetup();} /* initqhull_mem *//*--------------------------------------------initqhull_start -- start initialization of qhull inits statistics*/ void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile) { clock(); /* start the clock */#if qh_QHpointer if (!(qh_qh= (qhT *)malloc (sizeof(qhT)))) { fprintf (errfile, "qhull error (qh_initqhull_globals): insufficient memory\n"); exit (qh_ERRmem); /* no error handler */ } memset((char *)qh_qh, 0, sizeof(qhT)); /* every field is 0, FALSE, NULL */#else memset((char *)&qh_qh, 0, sizeof(qhT));#endif strcat (qh qhull, "qhull"); qh_initstatistics(); qh ANGLEmerge= True; qh ATinfinity= True; qh DROPdim= -1; qh ferr= errfile; qh fin= infile; qh fout= outfile; qh furthest_id= -1; qh KEEPminArea = REALmax; qh lastreport= INT_MIN; qh mergereport= INT_MIN; qh max_outside= 0.0; qh maxmaxcoord= 0.0; qh max_vertex= 0.0; qh MERGEindependent= True; qh mergereport= INT_MAX; qh min_vertex= 0.0; qh MINdenom_1= fmax_(1.0/REALmax, REALmin); qh MINoutside= 0.0; qh MINvisible= REALmax; qh MAXcoplanar= REALmax; qh premerge_centrum= 0.0; qh premerge_cos= REALmax; qh PRINTprecision= True; qh PRINTradius= 0.0; qh postmerge_cos= REALmax; qh postmerge_centrum= 0.0; qh rand_seed= 1; qh ROTATErandom= INT_MIN; qh MERGEvertices= True; qh totarea= 0.0; qh TRACEdist= REALmax; qh TRACEpoint= -1; qh tracefacet_id= -1; /* recompile to trace an id */ qh tracevertex_id= -1;} /* initqhull_start *//*----------------------------------------------initthresholds set thresholds for printing and scaling from command line see 'prompt' in unix.c for documentation see also initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk' sets qh GOODthreshold or qh SPLITthreshold if 'Pd0D1' used*/void qh_initthresholds(char *command) { realT value; int index, maxdim, k; char *s= command; char key; maxdim= qh input_dim; if (qh DELAUNAY && (qh PROJECTdelaunay || qh PROJECTinput)) maxdim++; while (*s) { if (*s == '-') s++; if (*s == 'P') { s++; while (*s && !isspace(key= *s++)) { if (key == 'd' || key == 'D') { if (!isdigit(*s)) { fprintf(qh ferr, "qhull warning: no dimension given for Print option '%c' at: %s. Ignored\n", key, s-1); continue; } index= qh_strtol (s, &s); if (index >= qh hull_dim) { fprintf(qh ferr, "qhull warning: dimension %d for Print option '%c' is >= %d. Ignored\n", index, key, qh hull_dim); continue; } if (*s == ':') { value= qh_strtod(++s, &s); if (fabs((double)value) > 1.0) { fprintf(qh ferr, "qhull warning: value %2.4g for Print option %c is > +1 or < -1. Ignored\n", value, key); continue; } }else value= 0.0; if (key == 'd') qh lower_threshold[index]= value; else qh upper_threshold[index]= value; } } }else if (*s == 'Q') { s++; while (*s && !isspace(key= *s++)) { if (key == 'b' && *s == 'B') { s++; for (k=maxdim; k--; ) { qh lower_bound[k]= -qh_DEFAULTbox; qh upper_bound[k]= qh_DEFAULTbox; } }else if (key == 'b' || key == 'B') { if (!isdigit(*s)) { fprintf(qh ferr, "qhull warning: no dimension given for Qhull option %c. Ignored\n", key); continue; } index= qh_strtol (s, &s); if (index >= maxdim) { fprintf(qh ferr, "qhull warning: dimension %d for Qhull option %c is >= %d. Ignored\n", index, key, maxdim); continue; } if (*s == ':') value= qh_strtod(++s, &s); else if (key == 'b') value= -qh_DEFAULTbox; else value= qh_DEFAULTbox; if (key == 'b') qh lower_bound[index]= value; else qh upper_bound[index]= value; } } }else { while (*s && !isspace (*s)) s++; } while (isspace (*s)) s++; } for (k= qh hull_dim; k--; ) { if (qh lower_threshold[k] > -REALmax/2) { qh GOODthreshold= True; if (qh upper_threshold[k] < REALmax/2) { qh SPLITthresholds= True; qh GOODthreshold= False; break; } }else if (qh upper_threshold[k] < REALmax/2) qh GOODthreshold= True; }} /* initthresholds *//*-------------------------------------------option- add an option description to qh qhull_options will be printed with statistics ('Ts') and errors strlen(option) < 40*/void qh_option (char *option, int *i, realT *r) { char buf[200]; int len, maxlen; sprintf (buf, " %s", option); if (i) sprintf (buf+strlen(buf), " %d", *i); if (r) sprintf (buf+strlen(buf), " %2.2g", *r); len= strlen(buf); qh qhull_optionslen += len; maxlen= sizeof (qh qhull_options) - len -1; maximize_(maxlen, 0); if (qh qhull_optionslen > 80 && maxlen > 0) { qh qhull_optionslen= len; strncat (qh qhull_options, "\n", maxlen--); } strncat (qh qhull_options, buf, maxlen);} /* option */#if qh_QHpointer/*-------------------------------------------restore_qhull- restores a previously saved qhull also restores qh_qhstat and qhmem.tempstack errors if current qhull hasn't been saved or freed uses qhmem for error reporting*/void qh_restore_qhull (qhT **oldqh) { if (*oldqh && strcmp ((*oldqh)->qhull, "qhull")) { fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n", *oldqh); qh_errexit (qh_ERRqhull, NULL, NULL); } if (qh_qh) { fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n"); qh_errexit (qh_ERRqhull, NULL, NULL); } if (!*oldqh || !(*oldqh)->old_qhstat) { fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n", *oldqh); qh_errexit (qh_ERRqhull, NULL, NULL); } qh_qh= *oldqh; *oldqh= NULL; qh_qhstat= qh old_qhstat; qhmem.tempstack= qh old_tempstack; trace1((qh ferr, "qh_restore_qhull: restored qhull from %p\n", *oldqh));} /* restore_qhull *//*-------------------------------------------save_qhull- saves qhull for a later qh_restore_qhull also saves qh_qhstat and qhmem.tempstackreturns: qhull for a later restore_qhull qh_qh=NULLnotes: need to initialize qhull or call qh_restore_qhull before continuing*/qhT *qh_save_qhull (void) { qhT *oldqh; if (!qh_qh) { fprintf (qhmem.ferr, "qhull internal error (qh_save_qhull): qhull not initialized\n"); qh_errexit (qh_ERRqhull, NULL, NULL); } qh old_qhstat= qh_qhstat; qh_qhstat= NULL; qh old_tempstack= qhmem.tempstack; qhmem.tempstack= NULL; oldqh= qh_qh; qh_qh= NULL; trace1((qhmem.ferr, "qh_save_qhull: saved qhull %p\n", oldqh)); return oldqh;} /* save_qhull */#endif/*------------------------------------------strtol/tod -- internal versions that don't skip trailing spaces*/double qh_strtod (const char *s, char **endp) { double result; result= strtod (s, endp); if (s < (*endp) && (*endp)[-1] == ' ') (*endp)--; return result;} /* strtod */int qh_strtol (const char *s, char **endp) { int result; result= (int) strtol (s, endp, 10); if (s< (*endp) && (*endp)[-1] == ' ') (*endp)--; return result;} /* strtol */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -