user_eg2.c
Go to the documentation of this file.
00001 /*<html><pre>  -<a                             href="../libqhull/qh-user.htm"
00002   >-------------------------------</a><a name="TOP">-</a>
00003 
00004   user_eg2.c
00005 
00006   sample code for calling qhull() from an application.
00007 
00008   See user_eg.c for a simpler method using qh_new_qhull().
00009   The method used here and in unix.c gives you additional
00010   control over Qhull.
00011 
00012   See user_eg3.cpp for a C++ example
00013 
00014   call with:
00015 
00016      user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
00017 
00018   for example:
00019 
00020      user_eg2                             # return summaries
00021 
00022      user_eg2 "n" "o" "Fp"                # return normals, OFF, points
00023 
00024      user_eg2 "QR0 p" "QR0 v p" "QR0 Fp"  # rotate input and return points
00025                                          # 'v' returns Voronoi
00026                                          # transform is rotated for halfspaces
00027 
00028    main() makes three runs of qhull.
00029 
00030      1) compute the convex hull of a cube, and incrementally add a diamond
00031 
00032      2a) compute the Delaunay triangulation of random points, and add points.
00033 
00034      2b) find the Delaunay triangle closest to a point.
00035 
00036      3) compute the halfspace intersection of a diamond, and add a cube
00037 
00038  notes:
00039 
00040    summaries are sent to stderr if other output formats are used
00041 
00042    derived from unix.c and compiled by 'make user_eg2'
00043 
00044    see libqhull.h for data structures, macros, and user-callable functions.
00045 
00046    If you want to control all output to stdio and input to stdin,
00047    set the #if below to "1" and delete all lines that contain "io.c".
00048    This prevents the loading of io.o.  Qhull will
00049    still write to 'qh ferr' (stderr) for error reporting and tracing.
00050 
00051    Defining #if 1, also prevents user.o from being loaded.
00052 */
00053 
00054 #include "qhull_a.h"
00055 
00056 /*-------------------------------------------------
00057 -internal function prototypes
00058 */
00059 void print_summary (void);
00060 void makecube (coordT *points, int numpoints, int dim);
00061 void adddiamond (coordT *points, int numpoints, int numnew, int dim);
00062 void makeDelaunay (coordT *points, int numpoints, int dim);
00063 void addDelaunay (coordT *points, int numpoints, int numnew, int dim);
00064 void findDelaunay (int dim);
00065 void makehalf (coordT *points, int numpoints, int dim);
00066 void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
00067 
00068 /*-------------------------------------------------
00069 -print_summary()
00070 */
00071 void print_summary (void) {
00072   facetT *facet;
00073   int k;
00074 
00075   printf ("\n%d vertices and %d facets with normals:\n",
00076                  qh num_vertices, qh num_facets);
00077   FORALLfacets {
00078     for (k=0; k < qh hull_dim; k++)
00079       printf ("%6.2g ", facet->normal[k]);
00080     printf ("\n");
00081   }
00082 }
00083 
00084 /*--------------------------------------------------
00085 -makecube- set points to vertices of cube
00086   points is numpoints X dim
00087 */
00088 void makecube (coordT *points, int numpoints, int dim) {
00089   int j,k;
00090   coordT *point;
00091 
00092   for (j=0; j<numpoints; j++) {
00093     point= points + j*dim;
00094     for (k=dim; k--; ) {
00095       if (j & ( 1 << k))
00096         point[k]= 1.0;
00097       else
00098         point[k]= -1.0;
00099     }
00100   }
00101 } /*.makecube.*/
00102 
00103 /*--------------------------------------------------
00104 -adddiamond- add diamond to convex hull
00105   points is numpoints+numnew X dim.
00106 
00107 notes:
00108   qh_addpoint() does not make a copy of the point coordinates.
00109 
00110   For inside points and some outside points, qh_findbestfacet performs
00111   an exhaustive search for a visible facet.  Algorithms that retain
00112   previously constructed hulls should be faster for on-line construction
00113   of the convex hull.
00114 */
00115 void adddiamond (coordT *points, int numpoints, int numnew, int dim) {
00116   int j,k;
00117   coordT *point;
00118   facetT *facet;
00119   boolT isoutside;
00120   realT bestdist;
00121 
00122   for (j= 0; j < numnew ; j++) {
00123     point= points + (numpoints+j)*dim;
00124     if (points == qh first_point)  /* in case of 'QRn' */
00125       qh num_points= numpoints+j+1;
00126     /* qh num_points sets the size of the points array.  You may
00127        allocate the points elsewhere.  If so, qh_addpoint records
00128        the point's address in qh other_points
00129     */
00130     for (k=dim; k--; ) {
00131       if (j/2 == k)
00132         point[k]= (j & 1) ? 2.0 : -2.0;
00133       else
00134         point[k]= 0.0;
00135     }
00136     facet= qh_findbestfacet (point, !qh_ALL, &bestdist, &isoutside);
00137     if (isoutside) {
00138       if (!qh_addpoint (point, facet, False))
00139         break;  /* user requested an early exit with 'TVn' or 'TCn' */
00140     }
00141     printf ("%d vertices and %d facets\n",
00142                  qh num_vertices, qh num_facets);
00143     /* qh_produce_output(); */
00144   }
00145   if (qh DOcheckmax)
00146     qh_check_maxout();
00147   else if (qh KEEPnearinside)
00148     qh_nearcoplanar();
00149 } /*.adddiamond.*/
00150 
00151 /*--------------------------------------------------
00152 -makeDelaunay- set points for dim-1 Delaunay triangulation of random points
00153   points is numpoints X dim.  Each point is projected to a paraboloid.
00154 */
00155 void makeDelaunay (coordT *points, int numpoints, int dim) {
00156   int j,k, seed;
00157   coordT *point, realr;
00158 
00159   seed= (int)time(NULL); /* time_t to int */
00160   printf ("seed: %d\n", seed);
00161   qh_RANDOMseed_( seed);
00162   for (j=0; j<numpoints; j++) {
00163     point= points + j*dim;
00164     for (k= 0; k < dim-1; k++) {
00165       realr= qh_RANDOMint;
00166       point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
00167     }
00168   }
00169   qh_setdelaunay (dim, numpoints, points);
00170 } /*.makeDelaunay.*/
00171 
00172 /*--------------------------------------------------
00173 -addDelaunay- add points to dim-1 Delaunay triangulation
00174   points is numpoints+numnew X dim.  Each point is projected to a paraboloid.
00175 notes:
00176   qh_addpoint() does not make a copy of the point coordinates.
00177 
00178   Since qh_addpoint() is not given a visible facet, it performs a directed
00179   search of all facets.  Algorithms that retain previously
00180   constructed hulls may be faster.
00181 */
00182 void addDelaunay (coordT *points, int numpoints, int numnew, int dim) {
00183   int j,k;
00184   coordT *point, realr;
00185   facetT *facet;
00186   realT bestdist;
00187   boolT isoutside;
00188 
00189   for (j= 0; j < numnew ; j++) {
00190     point= points + (numpoints+j)*dim;
00191     if (points == qh first_point)  /* in case of 'QRn' */
00192       qh num_points= numpoints+j+1;
00193     /* qh num_points sets the size of the points array.  You may
00194        allocate the point elsewhere.  If so, qh_addpoint records
00195        the point's address in qh other_points
00196     */
00197     for (k= 0; k < dim-1; k++) {
00198       realr= qh_RANDOMint;
00199       point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
00200     }
00201     qh_setdelaunay (dim, 1, point);
00202     facet= qh_findbestfacet (point, !qh_ALL, &bestdist, &isoutside);
00203     if (isoutside) {
00204       if (!qh_addpoint (point, facet, False))
00205         break;  /* user requested an early exit with 'TVn' or 'TCn' */
00206     }
00207     qh_printpoint (stdout, "added point", point);
00208     printf ("%d points, %d extra points, %d vertices, and %d facets in total\n",
00209                   qh num_points, qh_setsize (qh other_points),
00210                   qh num_vertices, qh num_facets);
00211 
00212     /* qh_produce_output(); */
00213   }
00214   if (qh DOcheckmax)
00215     qh_check_maxout();
00216   else if (qh KEEPnearinside)
00217     qh_nearcoplanar();
00218 } /*.addDelaunay.*/
00219 
00220 /*--------------------------------------------------
00221 -findDelaunay- find Delaunay triangle for [0.5,0.5,...]
00222   assumes dim < 100
00223 notes:
00224   calls qh_setdelaunay() to project the point to a parabaloid
00225 warning:
00226   This is not implemented for tricoplanar facets ('Qt'),
00227   See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
00228 */
00229 void findDelaunay (int dim) {
00230   int k;
00231   coordT point[ 100];
00232   boolT isoutside;
00233   realT bestdist;
00234   facetT *facet;
00235   vertexT *vertex, **vertexp;
00236 
00237   for (k= 0; k < dim-1; k++)
00238     point[k]= 0.5;
00239   qh_setdelaunay (dim, 1, point);
00240   facet= qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside);
00241   if (facet->tricoplanar) {
00242     fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
00243        facet->id);
00244     qh_errexit (qh_ERRqhull, facet, NULL);
00245   }
00246   FOREACHvertex_(facet->vertices) {
00247     for (k=0; k < dim-1; k++)
00248       printf ("%5.2f ", vertex->point[k]);
00249     printf ("\n");
00250   }
00251 } /*.findDelaunay.*/
00252 
00253 /*--------------------------------------------------
00254 -makehalf- set points to halfspaces for a (dim)-d diamond
00255   points is numpoints X dim+1
00256 
00257   each halfspace consists of dim coefficients followed by an offset
00258 */
00259 void makehalf (coordT *points, int numpoints, int dim) {
00260   int j,k;
00261   coordT *point;
00262 
00263   for (j=0; j<numpoints; j++) {
00264     point= points + j*(dim+1);
00265     point[dim]= -1.0; /* offset */
00266     for (k=dim; k--; ) {
00267       if (j & ( 1 << k))
00268         point[k]= 1.0;
00269       else
00270         point[k]= -1.0;
00271     }
00272   }
00273 } /*.makehalf.*/
00274 
00275 /*--------------------------------------------------
00276 -addhalf- add halfspaces for a (dim)-d cube to the intersection
00277   points is numpoints+numnew X dim+1
00278 notes:
00279   assumes dim < 100.
00280 
00281   For makehalf(), points is the initial set of halfspaces with offsets.
00282   It is transformed by qh_sethalfspace_all into a
00283   (dim)-d set of newpoints.  Qhull computed the convex hull of newpoints -
00284   this is equivalent to the halfspace intersection of the
00285   orginal halfspaces.
00286 
00287   For addhalf(), the remainder of points stores the transforms of
00288   the added halfspaces.  Qhull computes the convex hull of newpoints
00289   and the added points.  qh_addpoint() does not make a copy of these points.
00290 
00291   Since halfspace intersection is equivalent to a convex hull,
00292   qh_findbestfacet may perform an exhaustive search
00293   for a visible facet.  Algorithms that retain previously constructed
00294   intersections should be faster for on-line construction.
00295 */
00296 void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
00297   int j,k;
00298   coordT *point, normal[100], offset, *next;
00299   facetT *facet;
00300   boolT isoutside;
00301   realT bestdist;
00302 
00303   for (j= 0; j < numnew ; j++) {
00304     offset= -1.0;
00305     for (k=dim; k--; ) {
00306       if (j/2 == k) {
00307         normal[k]= sqrt((coordT)dim);   /* to normalize as in makehalf */
00308         if (j & 1)
00309           normal[k]= -normal[k];
00310       }else
00311         normal[k]= 0.0;
00312     }
00313     point= points + (numpoints+j)* (dim+1);  /* does not use point[dim] */
00314     qh_sethalfspace (dim, point, &next, normal, &offset, feasible);
00315     facet= qh_findbestfacet (point, !qh_ALL, &bestdist, &isoutside);
00316     if (isoutside) {
00317       if (!qh_addpoint (point, facet, False))
00318         break;  /* user requested an early exit with 'TVn' or 'TCn' */
00319     }
00320     qh_printpoint (stdout, "added offset -1 and normal", normal);
00321     printf ("%d points, %d extra points, %d vertices, and %d facets in total\n",
00322                   qh num_points, qh_setsize (qh other_points),
00323                   qh num_vertices, qh num_facets);
00324     /* qh_produce_output(); */
00325   }
00326   if (qh DOcheckmax)
00327     qh_check_maxout();
00328   else if (qh KEEPnearinside)
00329     qh_nearcoplanar();
00330 } /*.addhalf.*/
00331 
00332 #define DIM 3     /* dimension of points, must be < 31 for SIZEcube */
00333 #define SIZEcube (1<<DIM)
00334 #define SIZEdiamond (2*DIM)
00335 #define TOTpoints (SIZEcube + SIZEdiamond)
00336 
00337 /*--------------------------------------------------
00338 -main- derived from call_qhull in user.c
00339 
00340   see program header
00341 
00342   this contains three runs of Qhull for convex hull, Delaunay
00343   triangulation or Voronoi vertices, and halfspace intersection
00344 
00345 */
00346 int main (int argc, char *argv[]) {
00347   boolT ismalloc;
00348   int curlong, totlong, exitcode;
00349   char options [2000];
00350 
00351   printf ("This is the output from user_eg2.c\n\n\
00352 It shows how qhull() may be called from an application in the same way as\n\
00353 qconvex.  It is not part of qhull itself.  If it appears accidently,\n\
00354 please remove user_eg2.c from your project.\n\n");
00355 
00356 #if qh_QHpointer  /* see user.h */
00357   if (qh_qh){
00358       printf ("QH6237: Qhull link error.  The global variable qh_qh was not initialized\n\
00359               to NULL by global.c.  Please compile user_eg2.c with -Dqh_QHpointer_dllimport\n\
00360               as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
00361       return -1;
00362   }
00363 #endif
00364 
00365 
00366   ismalloc= False;      /* True if qh_freeqhull should 'free(array)' */
00367   /*
00368     Run 1: convex hull
00369   */
00370   qh_init_A (stdin, stdout, stderr, 0, NULL);
00371   exitcode= setjmp (qh errexit);
00372   if (!exitcode) {
00373     coordT array[TOTpoints][DIM];
00374 
00375     strcat (qh rbox_command, "user_eg cube");
00376     sprintf (options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
00377     qh_initflags (options);
00378     printf( "\ncompute triangulated convex hull of cube after rotating input\n");
00379     makecube (array[0], SIZEcube, DIM);
00380     qh_init_B (array[0], SIZEcube, DIM, ismalloc);
00381     qh_qhull();
00382     qh_check_output();
00383     qh_triangulate();  /* requires option 'Q11' if want to add points */
00384     print_summary ();
00385     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00386       qh_check_points ();
00387     printf( "\nadd points in a diamond\n");
00388     adddiamond (array[0], SIZEcube, SIZEdiamond, DIM);
00389     qh_check_output();
00390     print_summary ();
00391     qh_produce_output();  /* delete this line to help avoid io.c */
00392     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00393       qh_check_points ();
00394   }
00395   qh NOerrexit= True;
00396   qh_freeqhull (!qh_ALL);
00397   qh_memfreeshort (&curlong, &totlong);
00398   /*
00399     Run 2: Delaunay triangulation
00400   */
00401   qh_init_A (stdin, stdout, stderr, 0, NULL);
00402   exitcode= setjmp (qh errexit);
00403   if (!exitcode) {
00404     coordT array[TOTpoints][DIM];
00405 
00406     strcat (qh rbox_command, "user_eg Delaunay");
00407     sprintf (options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
00408     qh_initflags (options);
00409     printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
00410     makeDelaunay (array[0], SIZEcube, DIM);
00411     /* Instead of makeDelaunay with qh_setdelaunay, you may
00412        produce a 2-d array of points, set DIM to 2, and set
00413        qh PROJECTdelaunay to True.  qh_init_B will call
00414        qh_projectinput to project the points to the paraboloid
00415        and add a point "at-infinity".
00416     */
00417     qh_init_B (array[0], SIZEcube, DIM, ismalloc);
00418     qh_qhull();
00419     /* If you want Voronoi ('v') without qh_produce_output(), call
00420        qh_setvoronoi_all() after qh_qhull() */
00421     qh_check_output();
00422     print_summary ();
00423     qh_produce_output();  /* delete this line to help avoid io.c */
00424     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00425       qh_check_points ();
00426     printf( "\nadd points to triangulation\n");
00427     addDelaunay (array[0], SIZEcube, SIZEdiamond, DIM);
00428     qh_check_output();
00429     qh_produce_output();  /* delete this line to help avoid io.c */
00430     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00431       qh_check_points ();
00432     printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
00433     findDelaunay (DIM);
00434   }
00435   qh NOerrexit= True;
00436   qh_freeqhull (!qh_ALL);
00437   qh_memfreeshort (&curlong, &totlong);
00438   /*
00439     Run 3: halfspace intersection
00440   */
00441   qh_init_A (stdin, stdout, stderr, 0, NULL);
00442   exitcode= setjmp (qh errexit);
00443   if (!exitcode) {
00444     coordT array[TOTpoints][DIM+1];  /* +1 for halfspace offset */
00445     pointT *points;
00446 
00447     strcat (qh rbox_command, "user_eg halfspaces");
00448     sprintf (options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
00449     qh_initflags (options);
00450     printf( "\ncompute halfspace intersection about the origin for a diamond\n");
00451     makehalf (array[0], SIZEcube, DIM);
00452     qh_setfeasible (DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */
00453     /* you may malloc and set qh feasible_point directly.  It is only used for
00454        option 'Fp' */
00455     points= qh_sethalfspace_all ( DIM+1, SIZEcube, array[0], qh feasible_point);
00456     qh_init_B (points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
00457     qh_qhull();
00458     qh_check_output();
00459     qh_produce_output();  /* delete this line to help avoid io.c */
00460     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00461       qh_check_points ();
00462     printf( "\nadd halfspaces for cube to intersection\n");
00463     addhalf (array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point);
00464     qh_check_output();
00465     qh_produce_output();  /* delete this line to help avoid io.c */
00466     if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
00467       qh_check_points ();
00468   }
00469   qh NOerrexit= True;
00470   qh NOerrexit= True;
00471   qh_freeqhull (!qh_ALL);
00472   qh_memfreeshort (&curlong, &totlong);
00473   if (curlong || totlong)  /* could also check previous runs */
00474     fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
00475        totlong, curlong);
00476   return exitcode;
00477 } /* main */
00478 
00479 #if 1    /* use 1 to prevent loading of io.o and user.o */
00480 /*-------------------------------------------
00481 -errexit- return exitcode to system after an error
00482   assumes exitcode non-zero
00483   prints useful information
00484   see qh_errexit2() in libqhull.c for 2 facets
00485 */
00486 void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
00487   QHULL_UNUSED(facet);
00488   QHULL_UNUSED(ridge);
00489 
00490   if (qh ERREXITcalled) {
00491     fprintf (qh ferr, "qhull error while processing previous error.  Exit program\n");
00492     exit(1);
00493   }
00494   qh ERREXITcalled= True;
00495   if (!qh QHULLfinished)
00496     qh hulltime= (unsigned)clock() - qh hulltime;
00497   fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
00498   fprintf(qh ferr, "Options selected:\n%s\n", qh qhull_options);
00499   if (qh furthest_id >= 0) {
00500     fprintf(qh ferr, "\nLast point added to hull was p%d", qh furthest_id);
00501     if (zzval_(Ztotmerge))
00502       fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
00503     if (qh QHULLfinished)
00504       fprintf(qh ferr, "\nQhull has finished constructing the hull.");
00505     else if (qh POSTmerging)
00506       fprintf(qh ferr, "\nQhull has started post-merging");
00507     fprintf(qh ferr, "\n\n");
00508   }
00509   if (qh NOerrexit) {
00510     fprintf (qh ferr, "qhull error while ending program.  Exit program\n");
00511     exit(1);
00512   }
00513   if (!exitcode)
00514     exitcode= qh_ERRqhull;
00515   qh NOerrexit= True;
00516   longjmp(qh errexit, exitcode);
00517 } /* errexit */
00518 
00519 
00520 /*-------------------------------------------
00521 -errprint- prints out the information of the erroneous object
00522     any parameter may be NULL, also prints neighbors and geomview output
00523 */
00524 void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
00525 
00526   fprintf (qh ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
00527            string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
00528            getid_(atvertex));
00529 } /* errprint */
00530 
00531 
00532 void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
00533   facetT *facet, **facetp;
00534 
00535   /* remove these calls to help avoid io.c */
00536   qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
00537   FORALLfacet_(facetlist)                                              /*io.c*/
00538     qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
00539   FOREACHfacet_(facets)                                                /*io.c*/
00540     qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
00541   qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);  /*io.c*/
00542 
00543   FORALLfacet_(facetlist)
00544     fprintf( qh ferr, "facet f%d\n", facet->id);
00545 } /* printfacetlist */
00546 
00547 /* qh_printhelp_degenerate( fp )
00548     prints descriptive message for precision error
00549 
00550   notes:
00551     no message if qh_QUICKhelp
00552 */
00553 void qh_printhelp_degenerate(FILE *fp) {
00554 
00555   if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
00556     qh_fprintf(fp, 9368, "\n\
00557 A Qhull error has occurred.  Qhull should have corrected the above\n\
00558 precision error.  Please send the input and all of the output to\n\
00559 qhull_bug@qhull.org\n");
00560   else if (!qh_QUICKhelp) {
00561     qh_fprintf(fp, 9369, "\n\
00562 Precision problems were detected during construction of the convex hull.\n\
00563 This occurs because convex hull algorithms assume that calculations are\n\
00564 exact, but floating-point arithmetic has roundoff errors.\n\
00565 \n\
00566 To correct for precision problems, do not use 'Q0'.  By default, Qhull\n\
00567 selects 'C-0' or 'Qx' and merges non-convex facets.  With option 'QJ',\n\
00568 Qhull joggles the input to prevent precision problems.  See \"Imprecision\n\
00569 in Qhull\" (qh-impre.htm).\n\
00570 \n\
00571 If you use 'Q0', the output may include\n\
00572 coplanar ridges, concave ridges, and flipped facets.  In 4-d and higher,\n\
00573 Qhull may produce a ridge with four neighbors or two facets with the same \n\
00574 vertices.  Qhull reports these events when they occur.  It stops when a\n\
00575 concave ridge, flipped facet, or duplicate facet occurs.\n");
00576 #if REALfloat
00577     qh_fprintf(fp, 9370, "\
00578 \n\
00579 Qhull is currently using single precision arithmetic.  The following\n\
00580 will probably remove the precision problems:\n\
00581   - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
00582 #endif
00583     if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
00584       qh_fprintf(fp, 9371, "\
00585 \n\
00586 When computing the Delaunay triangulation of coordinates > 1.0,\n\
00587   - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
00588     if (qh DELAUNAY && !qh ATinfinity)
00589       qh_fprintf(fp, 9372, "\
00590 When computing the Delaunay triangulation:\n\
00591   - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
00592 
00593     qh_fprintf(fp, 9373, "\
00594 \n\
00595 If you need triangular output:\n\
00596   - use option 'Qt' to triangulate the output\n\
00597   - use option 'QJ' to joggle the input points and remove precision errors\n\
00598   - use option 'Ft'.  It triangulates non-simplicial facets with added points.\n\
00599 \n\
00600 If you must use 'Q0',\n\
00601 try one or more of the following options.  They can not guarantee an output.\n\
00602   - use 'QbB' to scale the input to a cube.\n\
00603   - use 'Po' to produce output and prevent partitioning for flipped facets\n\
00604   - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
00605   - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
00606   - options 'Qf', 'Qbb', and 'QR0' may also help\n",
00607                qh DISTround);
00608     qh_fprintf(fp, 9374, "\
00609 \n\
00610 To guarantee simplicial output:\n\
00611   - use option 'Qt' to triangulate the output\n\
00612   - use option 'QJ' to joggle the input points and remove precision errors\n\
00613   - use option 'Ft' to triangulate the output by adding points\n\
00614   - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
00615 ");
00616   }
00617 } /* printhelp_degenerate */
00618 
00619 
00620 /* qh_printhelp_narrowhull( minangle )
00621      Warn about a narrow hull
00622 
00623   notes:
00624     Alternatively, reduce qh_WARNnarrow in user.h
00625 
00626 */
00627 void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
00628 
00629     qh_fprintf(fp, 9375, "qhull precision warning: \n\
00630 The initial hull is narrow (cosine of min. angle is %.16f).\n\
00631 A coplanar point may lead to a wide facet.  Options 'QbB' (scale to unit box)\n\
00632 or 'Qbb' (scale last coordinate) may remove this warning.  Use 'Pp' to skip\n\
00633 this warning.  See 'Limitations' in qh-impre.htm.\n",
00634           -minangle);   /* convert from angle between normals to angle between facets */
00635 } /* printhelp_narrowhull */
00636 
00637 /* qh_printhelp_singular
00638       prints descriptive message for singular input
00639 */
00640 void qh_printhelp_singular(FILE *fp) {
00641   facetT *facet;
00642   vertexT *vertex, **vertexp;
00643   realT min, max, *coord, dist;
00644   int i,k;
00645 
00646   qh_fprintf(fp, 9376, "\n\
00647 The input to qhull appears to be less than %d dimensional, or a\n\
00648 computation has overflowed.\n\n\
00649 Qhull could not construct a clearly convex simplex from points:\n",
00650            qh hull_dim);
00651   qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
00652   if (!qh_QUICKhelp)
00653     qh_fprintf(fp, 9377, "\n\
00654 The center point is coplanar with a facet, or a vertex is coplanar\n\
00655 with a neighboring facet.  The maximum round off error for\n\
00656 computing distances is %2.2g.  The center point, facets and distances\n\
00657 to the center point are as follows:\n\n", qh DISTround);
00658   qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, -1);
00659   qh_fprintf(fp, 9378, "\n");
00660   FORALLfacets {
00661     qh_fprintf(fp, 9379, "facet");
00662     FOREACHvertex_(facet->vertices)
00663       qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
00664     zinc_(Zdistio);
00665     qh_distplane(qh interior_point, facet, &dist);
00666     qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
00667   }
00668   if (!qh_QUICKhelp) {
00669     if (qh HALFspace)
00670       qh_fprintf(fp, 9382, "\n\
00671 These points are the dual of the given halfspaces.  They indicate that\n\
00672 the intersection is degenerate.\n");
00673     qh_fprintf(fp, 9383,"\n\
00674 These points either have a maximum or minimum x-coordinate, or\n\
00675 they maximize the determinant for k coordinates.  Trial points\n\
00676 are first selected from points that maximize a coordinate.\n");
00677     if (qh hull_dim >= qh_INITIALmax)
00678       qh_fprintf(fp, 9384, "\n\
00679 Because of the high dimension, the min x-coordinate and max-coordinate\n\
00680 points are used if the determinant is non-zero.  Option 'Qs' will\n\
00681 do a better, though much slower, job.  Instead of 'Qs', you can change\n\
00682 the points by randomly rotating the input with 'QR0'.\n");
00683   }
00684   qh_fprintf(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
00685   for (k=0; k < qh hull_dim; k++) {
00686     min= REALmax;
00687     max= -REALmin;
00688     for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
00689       maximize_(max, *coord);
00690       minimize_(min, *coord);
00691     }
00692     qh_fprintf(fp, 9386, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
00693   }
00694   if (!qh_QUICKhelp) {
00695     qh_fprintf(fp, 9387, "\n\
00696 If the input should be full dimensional, you have several options that\n\
00697 may determine an initial simplex:\n\
00698   - use 'QJ'  to joggle the input and make it full dimensional\n\
00699   - use 'QbB' to scale the points to the unit cube\n\
00700   - use 'QR0' to randomly rotate the input for different maximum points\n\
00701   - use 'Qs'  to search all points for the initial simplex\n\
00702   - use 'En'  to specify a maximum roundoff error less than %2.2g.\n\
00703   - trace execution with 'T3' to see the determinant for each point.\n",
00704                      qh DISTround);
00705 #if REALfloat
00706     qh_fprintf(fp, 9388, "\
00707   - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
00708 #endif
00709     qh_fprintf(fp, 9389, "\n\
00710 If the input is lower dimensional:\n\
00711   - use 'QJ' to joggle the input and make it full dimensional\n\
00712   - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should\n\
00713     pick the coordinate with the least range.  The hull will have the\n\
00714     correct topology.\n\
00715   - determine the flat containing the points, rotate the points\n\
00716     into a coordinate plane, and delete the other coordinates.\n\
00717   - add one or more points to make the input full dimensional.\n\
00718 ");
00719     if (qh DELAUNAY && !qh ATinfinity)
00720       qh_fprintf(fp, 9390, "\n\n\
00721 This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
00722   - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
00723   - or use 'QJ' to joggle the input and avoid co-circular data\n");
00724   }
00725 } /* printhelp_singular */
00726 
00727 
00728 /*-----------------------------------------
00729 -user_memsizes- allocate up to 10 additional, quick allocation sizes
00730 */
00731 void qh_user_memsizes (void) {
00732 
00733   /* qh_memsize (size); */
00734 } /* user_memsizes */
00735 
00736 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


libqhull
Author(s): Robert Krug
autogenerated on Tue Jun 18 2013 12:38:50