user_eg2.c
Go to the documentation of this file.
1 /*<html><pre> -<a href="../libqhull/qh-user.htm"
2  >-------------------------------</a><a name="TOP">-</a>
3 
4  user_eg2.c
5 
6  sample code for calling qhull() from an application.
7 
8  See user_eg.c for a simpler method using qh_new_qhull().
9  The method used here and in unix.c gives you additional
10  control over Qhull.
11 
12  See user_eg3/user_eg3_r.cpp for a C++ example
13 
14  call with:
15 
16  user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
17 
18  for example:
19 
20  user_eg2 # return summaries
21 
22  user_eg2 "n" "o" "Fp" # return normals, OFF, points
23 
24  user_eg2 "QR0 p" "QR0 v p" "QR0 Fp" # rotate input and return points
25  # 'v' returns Voronoi
26  # transform is rotated for halfspaces
27 
28  main() makes three runs of qhull.
29 
30  1) compute the convex hull of a cube, and incrementally add a diamond
31 
32  2a) compute the Delaunay triangulation of random points, and add points.
33 
34  2b) find the Delaunay triangle closest to a point.
35 
36  3) compute the halfspace intersection of a diamond, and add a cube
37 
38  notes:
39 
40  summaries are sent to stderr if other output formats are used
41 
42  derived from unix.c and compiled by 'make bin/user_eg2'
43 
44  see libqhull.h for data structures, macros, and user-callable functions.
45 
46  If you want to control all output to stdio and input to stdin,
47  set the #if below to "1" and delete all lines that contain "io.c".
48  This prevents the loading of io.o. Qhull will
49  still write to 'qh ferr' (stderr) for error reporting and tracing.
50 
51  Defining #if 1, also prevents user.o from being loaded.
52 */
53 
54 #include "libqhull/qhull_a.h"
55 
56 /*-------------------------------------------------
57 -internal function prototypes
58 */
59 void print_summary(void);
60 void makecube(coordT *points, int numpoints, int dim);
61 void adddiamond(coordT *points, int numpoints, int numnew, int dim);
62 void makeDelaunay(coordT *points, int numpoints, int dim);
63 void addDelaunay(coordT *points, int numpoints, int numnew, int dim);
64 void findDelaunay(int dim);
65 void makehalf(coordT *points, int numpoints, int dim);
66 void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
67 
68 /*-------------------------------------------------
69 -print_summary()
70 */
71 void print_summary(void) {
72  facetT *facet;
73  int k;
74 
75  printf("\n%d vertices and %d facets with normals:\n",
76  qh num_vertices, qh num_facets);
77  FORALLfacets {
78  for (k=0; k < qh hull_dim; k++)
79  printf("%6.2g ", facet->normal[k]);
80  printf("\n");
81  }
82 }
83 
84 /*--------------------------------------------------
85 -makecube- set points to vertices of cube
86  points is numpoints X dim
87 */
88 void makecube(coordT *points, int numpoints, int dim) {
89  int j,k;
90  coordT *point;
91 
92  for (j=0; j<numpoints; j++) {
93  point= points + j*dim;
94  for (k=dim; k--; ) {
95  if (j & ( 1 << k))
96  point[k]= 1.0;
97  else
98  point[k]= -1.0;
99  }
100  }
101 } /*.makecube.*/
102 
103 /*--------------------------------------------------
104 -adddiamond- add diamond to convex hull
105  points is numpoints+numnew X dim.
106 
107 notes:
108  qh_addpoint() does not make a copy of the point coordinates.
109 
110  For inside points and some outside points, qh_findbestfacet performs
111  an exhaustive search for a visible facet. Algorithms that retain
112  previously constructed hulls should be faster for on-line construction
113  of the convex hull.
114 */
115 void adddiamond(coordT *points, int numpoints, int numnew, int dim) {
116  int j,k;
117  coordT *point;
118  facetT *facet;
119  boolT isoutside;
120  realT bestdist;
121 
122  for (j= 0; j < numnew ; j++) {
123  point= points + (numpoints+j)*dim;
124  if (points == qh first_point) /* in case of 'QRn' */
125  qh num_points= numpoints+j+1;
126  /* qh.num_points sets the size of the points array. You may
127  allocate the points elsewhere. If so, qh_addpoint records
128  the point's address in qh other_points
129  */
130  for (k=dim; k--; ) {
131  if (j/2 == k)
132  point[k]= (j & 1) ? 2.0 : -2.0;
133  else
134  point[k]= 0.0;
135  }
136  facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
137  if (isoutside) {
138  if (!qh_addpoint(point, facet, False))
139  break; /* user requested an early exit with 'TVn' or 'TCn' */
140  }
141  printf("%d vertices and %d facets\n",
142  qh num_vertices, qh num_facets);
143  /* qh_produce_output(); */
144  }
145  if (qh DOcheckmax)
146  qh_check_maxout();
147  else if (qh KEEPnearinside)
148  qh_nearcoplanar();
149 } /*.adddiamond.*/
150 
151 /*--------------------------------------------------
152 -makeDelaunay- set points for dim-1 Delaunay triangulation of random points
153  points is numpoints X dim. Each point is projected to a paraboloid.
154 */
155 void makeDelaunay(coordT *points, int numpoints, int dim) {
156  int j,k, seed;
157  coordT *point, realr;
158 
159  seed= (int)time(NULL); /* time_t to int */
160  printf("seed: %d\n", seed);
161  qh_RANDOMseed_( seed);
162  for (j=0; j<numpoints; j++) {
163  point= points + j*dim;
164  for (k= 0; k < dim-1; k++) {
165  realr= qh_RANDOMint;
166  point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
167  }
168  }
169  qh_setdelaunay(dim, numpoints, points);
170 } /*.makeDelaunay.*/
171 
172 /*--------------------------------------------------
173 -addDelaunay- add points to dim-1 Delaunay triangulation
174  points is numpoints+numnew X dim. Each point is projected to a paraboloid.
175 notes:
176  qh_addpoint() does not make a copy of the point coordinates.
177 
178  Since qh_addpoint() is not given a visible facet, it performs a directed
179  search of all facets. Algorithms that retain previously
180  constructed hulls may be faster.
181 */
182 void addDelaunay(coordT *points, int numpoints, int numnew, int dim) {
183  int j,k;
184  coordT *point, realr;
185  facetT *facet;
186  realT bestdist;
187  boolT isoutside;
188 
189  for (j= 0; j < numnew ; j++) {
190  point= points + (numpoints+j)*dim;
191  if (points == qh first_point) /* in case of 'QRn' */
192  qh num_points= numpoints+j+1;
193  /* qh.num_points sets the size of the points array. You may
194  allocate the point elsewhere. If so, qh_addpoint records
195  the point's address in qh other_points
196  */
197  for (k= 0; k < dim-1; k++) {
198  realr= qh_RANDOMint;
199  point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
200  }
201  qh_setdelaunay(dim, 1, point);
202  facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
203  if (isoutside) {
204  if (!qh_addpoint(point, facet, False))
205  break; /* user requested an early exit with 'TVn' or 'TCn' */
206  }
207  qh_printpoint(stdout, "added point", point);
208  printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
209  qh num_points, qh_setsize(qh other_points),
210  qh num_vertices, qh num_facets);
211 
212  /* qh_produce_output(); */
213  }
214  if (qh DOcheckmax)
215  qh_check_maxout();
216  else if (qh KEEPnearinside)
217  qh_nearcoplanar();
218 } /*.addDelaunay.*/
219 
220 /*--------------------------------------------------
221 -findDelaunay- find Delaunay triangle for [0.5,0.5,...]
222  assumes dim < 100
223 notes:
224  calls qh_setdelaunay() to project the point to a parabaloid
225 warning:
226  This is not implemented for tricoplanar facets ('Qt'),
227  See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
228 */
229 void findDelaunay(int dim) {
230  int k;
231  coordT point[ 100];
232  boolT isoutside;
233  realT bestdist;
234  facetT *facet;
235  vertexT *vertex, **vertexp;
236 
237  for (k= 0; k < dim-1; k++)
238  point[k]= 0.5;
239  qh_setdelaunay(dim, 1, point);
240  facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
241  if (facet->tricoplanar) {
242  fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
243  facet->id);
244  qh_errexit(qh_ERRqhull, facet, NULL);
245  }
246  FOREACHvertex_(facet->vertices) {
247  for (k=0; k < dim-1; k++)
248  printf("%5.2f ", vertex->point[k]);
249  printf("\n");
250  }
251 } /*.findDelaunay.*/
252 
253 /*--------------------------------------------------
254 -makehalf- set points to halfspaces for a (dim)-d diamond
255  points is numpoints X dim+1
256 
257  each halfspace consists of dim coefficients followed by an offset
258 */
259 void makehalf(coordT *points, int numpoints, int dim) {
260  int j,k;
261  coordT *point;
262 
263  for (j=0; j<numpoints; j++) {
264  point= points + j*(dim+1);
265  point[dim]= -1.0; /* offset */
266  for (k=dim; k--; ) {
267  if (j & ( 1 << k))
268  point[k]= 1.0;
269  else
270  point[k]= -1.0;
271  }
272  }
273 } /*.makehalf.*/
274 
275 /*--------------------------------------------------
276 -addhalf- add halfspaces for a (dim)-d cube to the intersection
277  points is numpoints+numnew X dim+1
278 notes:
279  assumes dim < 100.
280 
281  For makehalf(), points is the initial set of halfspaces with offsets.
282  It is transformed by qh_sethalfspace_all into a
283  (dim)-d set of newpoints. Qhull computed the convex hull of newpoints -
284  this is equivalent to the halfspace intersection of the
285  orginal halfspaces.
286 
287  For addhalf(), the remainder of points stores the transforms of
288  the added halfspaces. Qhull computes the convex hull of newpoints
289  and the added points. qh_addpoint() does not make a copy of these points.
290 
291  Since halfspace intersection is equivalent to a convex hull,
292  qh_findbestfacet may perform an exhaustive search
293  for a visible facet. Algorithms that retain previously constructed
294  intersections should be faster for on-line construction.
295 */
296 void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
297  int j,k;
298  coordT *point, normal[100], offset, *next;
299  facetT *facet;
300  boolT isoutside;
301  realT bestdist;
302 
303  for (j= 0; j < numnew ; j++) {
304  offset= -1.0;
305  for (k=dim; k--; ) {
306  if (j/2 == k) {
307  normal[k]= sqrt((coordT)dim); /* to normalize as in makehalf */
308  if (j & 1)
309  normal[k]= -normal[k];
310  }else
311  normal[k]= 0.0;
312  }
313  point= points + (numpoints+j)* (dim+1); /* does not use point[dim] */
314  qh_sethalfspace(dim, point, &next, normal, &offset, feasible);
315  facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
316  if (isoutside) {
317  if (!qh_addpoint(point, facet, False))
318  break; /* user requested an early exit with 'TVn' or 'TCn' */
319  }
320  qh_printpoint(stdout, "added offset -1 and normal", normal);
321  printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
322  qh num_points, qh_setsize(qh other_points),
323  qh num_vertices, qh num_facets);
324  /* qh_produce_output(); */
325  }
326  if (qh DOcheckmax)
327  qh_check_maxout();
328  else if (qh KEEPnearinside)
329  qh_nearcoplanar();
330 } /*.addhalf.*/
331 
332 #define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
333 #define SIZEcube (1<<DIM)
334 #define SIZEdiamond (2*DIM)
335 #define TOTpoints (SIZEcube + SIZEdiamond)
336 
337 /*--------------------------------------------------
338 -main- derived from unix.c
339 
340  see program header
341 
342  this contains three runs of Qhull for convex hull, Delaunay
343  triangulation or Voronoi vertices, and halfspace intersection
344 
345 */
346 int main(int argc, char *argv[]) {
347  boolT ismalloc;
348  int curlong, totlong, exitcode;
349  char options [2000];
350 
352 
353  printf("This is the output from user_eg2.c\n\n\
354 It shows how qhull() may be called from an application in the same way as\n\
355 qconvex. It is not part of qhull itself. If it appears accidently,\n\
356 please remove user_eg2.c from your project.\n\n");
357 
358 #if qh_QHpointer /* see user.h */
359  if (qh_qh){
360  printf("QH6237: Qhull link error. The global variable qh_qh was not initialized\n\
361  to NULL by global.c. Please compile user_eg2.c with -Dqh_QHpointer_dllimport\n\
362  as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
363  return -1;
364  }
365 #endif
366 
367 
368  ismalloc= False; /* True if qh_freeqhull should 'free(array)' */
369  /*
370  Run 1: convex hull
371  */
372  qh_init_A(stdin, stdout, stderr, 0, NULL);
373  exitcode= setjmp(qh errexit);
374  if (!exitcode) {
375  coordT array[TOTpoints][DIM];
376 
377  strcat(qh rbox_command, "user_eg cube");
378  sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
379  qh_initflags(options);
380  printf( "\ncompute triangulated convex hull of cube after rotating input\n");
381  makecube(array[0], SIZEcube, DIM);
382  qh_init_B(array[0], SIZEcube, DIM, ismalloc);
383  qh_qhull();
384  qh_check_output();
385  qh_triangulate(); /* requires option 'Q11' if want to add points */
386  print_summary();
387  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
388  qh_check_points();
389  printf( "\nadd points in a diamond\n");
390  adddiamond(array[0], SIZEcube, SIZEdiamond, DIM);
391  qh_check_output();
392  print_summary();
393  qh_produce_output(); /* delete this line to help avoid io.c */
394  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
395  qh_check_points();
396  }
397  qh NOerrexit= True;
399  qh_memfreeshort(&curlong, &totlong);
400  if (curlong || totlong)
401  fprintf(stderr, "qhull warning (user_eg, run 1): did not free %d bytes of long memory (%d pieces)\n",
402  totlong, curlong);
403 
404  /*
405  Run 2: Delaunay triangulation
406  */
407  qh_init_A(stdin, stdout, stderr, 0, NULL);
408  exitcode= setjmp(qh errexit);
409  if (!exitcode) {
410  coordT array[TOTpoints][DIM];
411 
412  strcat(qh rbox_command, "user_eg Delaunay");
413  sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
414  qh_initflags(options);
415  printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
416  makeDelaunay(array[0], SIZEcube, DIM);
417  /* Instead of makeDelaunay with qh_setdelaunay, you may
418  produce a 2-d array of points, set DIM to 2, and set
419  qh PROJECTdelaunay to True. qh_init_B will call
420  qh_projectinput to project the points to the paraboloid
421  and add a point "at-infinity".
422  */
423  qh_init_B(array[0], SIZEcube, DIM, ismalloc);
424  qh_qhull();
425  /* If you want Voronoi ('v') without qh_produce_output(), call
426  qh_setvoronoi_all() after qh_qhull() */
427  qh_check_output();
428  print_summary();
429  qh_produce_output(); /* delete this line to help avoid io.c */
430  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
431  qh_check_points();
432  printf( "\nadd points to triangulation\n");
433  addDelaunay(array[0], SIZEcube, SIZEdiamond, DIM);
434  qh_check_output();
435  qh_produce_output(); /* delete this line to help avoid io.c */
436  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
437  qh_check_points();
438  printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
439  findDelaunay(DIM);
440  }
441  qh NOerrexit= True;
443  qh_memfreeshort(&curlong, &totlong);
444  if (curlong || totlong)
445  fprintf(stderr, "qhull warning (user_eg, run 2): did not free %d bytes of long memory (%d pieces)\n",
446  totlong, curlong);
447 
448  /*
449  Run 3: halfspace intersection
450  */
451  qh_init_A(stdin, stdout, stderr, 0, NULL);
452  exitcode= setjmp(qh errexit);
453  if (!exitcode) {
454  coordT array[TOTpoints][DIM+1]; /* +1 for halfspace offset */
455  pointT *points;
456 
457  strcat(qh rbox_command, "user_eg halfspaces");
458  sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
459  qh_initflags(options);
460  printf( "\ncompute halfspace intersection about the origin for a diamond\n");
461  makehalf(array[0], SIZEcube, DIM);
462  qh_setfeasible(DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */
463  /* you may malloc and set qh feasible_point directly. It is only used for
464  option 'Fp' */
465  points= qh_sethalfspace_all( DIM+1, SIZEcube, array[0], qh feasible_point);
466  qh_init_B(points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
467  qh_qhull();
468  qh_check_output();
469  qh_produce_output(); /* delete this line to help avoid io.c */
470  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
471  qh_check_points();
472  printf( "\nadd halfspaces for cube to intersection\n");
473  addhalf(array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point);
474  qh_check_output();
475  qh_produce_output(); /* delete this line to help avoid io.c */
476  if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
477  qh_check_points();
478  }
479  qh NOerrexit= True;
480  qh NOerrexit= True;
482  qh_memfreeshort(&curlong, &totlong);
483  if (curlong || totlong)
484  fprintf(stderr, "qhull warning (user_eg, run 3): did not free %d bytes of long memory (%d pieces)\n",
485  totlong, curlong);
486  return exitcode;
487 } /* main */
488 
489 #if 1 /* use 1 to prevent loading of io.o and user.o */
490 /*-------------------------------------------
491 -errexit- return exitcode to system after an error
492  assumes exitcode non-zero
493  prints useful information
494  see qh_errexit2() in libqhull.c for 2 facets
495 */
496 void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
497  QHULL_UNUSED(facet);
498  QHULL_UNUSED(ridge);
499 
500  if (qh ERREXITcalled) {
501  fprintf(qh ferr, "qhull error while processing previous error. Exit program\n");
502  exit(1);
503  }
504  qh ERREXITcalled= True;
505  if (!qh QHULLfinished)
506  qh hulltime= (unsigned)clock() - qh hulltime;
507  fprintf(qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
508  fprintf(qh ferr, "Options selected:\n%s\n", qh qhull_options);
509  if (qh furthest_id >= 0) {
510  fprintf(qh ferr, "\nLast point added to hull was p%d", qh furthest_id);
511  if (zzval_(Ztotmerge))
512  fprintf(qh ferr, " Last merge was #%d.", zzval_(Ztotmerge));
513  if (qh QHULLfinished)
514  fprintf(qh ferr, "\nQhull has finished constructing the hull.");
515  else if (qh POSTmerging)
516  fprintf(qh ferr, "\nQhull has started post-merging");
517  fprintf(qh ferr, "\n\n");
518  }
519  if (qh NOerrexit) {
520  fprintf(qh ferr, "qhull error while ending program. Exit program\n");
521  exit(1);
522  }
523  if (!exitcode)
524  exitcode= qh_ERRqhull;
525  qh NOerrexit= True;
526  longjmp(qh errexit, exitcode);
527 } /* errexit */
528 
529 
530 /*-------------------------------------------
531 -errprint- prints out the information of the erroneous object
532  any parameter may be NULL, also prints neighbors and geomview output
533 */
534 void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
535 
536  fprintf(qh ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
537  string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
538  getid_(atvertex));
539 } /* errprint */
540 
541 
542 void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
543  facetT *facet, **facetp;
544 
545  /* remove these calls to help avoid io.c */
546  qh_printbegin(qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
547  FORALLfacet_(facetlist) /*io.c*/
548  qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall); /*io.c*/
549  FOREACHfacet_(facets) /*io.c*/
550  qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall); /*io.c*/
551  qh_printend(qh ferr, qh_PRINTfacets, facetlist, facets, printall); /*io.c*/
552 
553  FORALLfacet_(facetlist)
554  fprintf( qh ferr, "facet f%d\n", facet->id);
555 } /* printfacetlist */
556 
557 /* qh_printhelp_degenerate( fp )
558  prints descriptive message for precision error
559 
560  notes:
561  no message if qh_QUICKhelp
562 */
563 void qh_printhelp_degenerate(FILE *fp) {
564 
565  if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
566  qh_fprintf(fp, 9368, "\n\
567 A Qhull error has occurred. Qhull should have corrected the above\n\
568 precision error. Please send the input and all of the output to\n\
569 qhull_bug@qhull.org\n");
570  else if (!qh_QUICKhelp) {
571  qh_fprintf(fp, 9369, "\n\
572 Precision problems were detected during construction of the convex hull.\n\
573 This occurs because convex hull algorithms assume that calculations are\n\
574 exact, but floating-point arithmetic has roundoff errors.\n\
575 \n\
576 To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
577 selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
578 Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
579 in Qhull\" (qh-impre.htm).\n\
580 \n\
581 If you use 'Q0', the output may include\n\
582 coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
583 Qhull may produce a ridge with four neighbors or two facets with the same \n\
584 vertices. Qhull reports these events when they occur. It stops when a\n\
585 concave ridge, flipped facet, or duplicate facet occurs.\n");
586 #if REALfloat
587  qh_fprintf(fp, 9370, "\
588 \n\
589 Qhull is currently using single precision arithmetic. The following\n\
590 will probably remove the precision problems:\n\
591  - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
592 #endif
593  if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
594  qh_fprintf(fp, 9371, "\
595 \n\
596 When computing the Delaunay triangulation of coordinates > 1.0,\n\
597  - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
598  if (qh DELAUNAY && !qh ATinfinity)
599  qh_fprintf(fp, 9372, "\
600 When computing the Delaunay triangulation:\n\
601  - use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
602 
603  qh_fprintf(fp, 9373, "\
604 \n\
605 If you need triangular output:\n\
606  - use option 'Qt' to triangulate the output\n\
607  - use option 'QJ' to joggle the input points and remove precision errors\n\
608  - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
609 \n\
610 If you must use 'Q0',\n\
611 try one or more of the following options. They can not guarantee an output.\n\
612  - use 'QbB' to scale the input to a cube.\n\
613  - use 'Po' to produce output and prevent partitioning for flipped facets\n\
614  - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
615  - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
616  - options 'Qf', 'Qbb', and 'QR0' may also help\n",
617  qh DISTround);
618  qh_fprintf(fp, 9374, "\
619 \n\
620 To guarantee simplicial output:\n\
621  - use option 'Qt' to triangulate the output\n\
622  - use option 'QJ' to joggle the input points and remove precision errors\n\
623  - use option 'Ft' to triangulate the output by adding points\n\
624  - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
625 ");
626  }
627 } /* printhelp_degenerate */
628 
629 
630 /* qh_printhelp_narrowhull( minangle )
631  Warn about a narrow hull
632 
633  notes:
634  Alternatively, reduce qh_WARNnarrow in user.h
635 
636 */
637 void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
638 
639  qh_fprintf(fp, 9375, "qhull precision warning: \n\
640 The initial hull is narrow (cosine of min. angle is %.16f).\n\
641 A coplanar point may lead to a wide facet. Options 'QbB' (scale to unit box)\n\
642 or 'Qbb' (scale last coordinate) may remove this warning. Use 'Pp' to skip\n\
643 this warning. See 'Limitations' in qh-impre.htm.\n",
644  -minangle); /* convert from angle between normals to angle between facets */
645 } /* printhelp_narrowhull */
646 
647 /* qh_printhelp_singular
648  prints descriptive message for singular input
649 */
650 void qh_printhelp_singular(FILE *fp) {
651  facetT *facet;
652  vertexT *vertex, **vertexp;
653  realT min, max, *coord, dist;
654  int i,k;
655 
656  qh_fprintf(fp, 9376, "\n\
657 The input to qhull appears to be less than %d dimensional, or a\n\
658 computation has overflowed.\n\n\
659 Qhull could not construct a clearly convex simplex from points:\n",
660  qh hull_dim);
661  qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
662  if (!qh_QUICKhelp)
663  qh_fprintf(fp, 9377, "\n\
664 The center point is coplanar with a facet, or a vertex is coplanar\n\
665 with a neighboring facet. The maximum round off error for\n\
666 computing distances is %2.2g. The center point, facets and distances\n\
667 to the center point are as follows:\n\n", qh DISTround);
668  qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, -1);
669  qh_fprintf(fp, 9378, "\n");
670  FORALLfacets {
671  qh_fprintf(fp, 9379, "facet");
672  FOREACHvertex_(facet->vertices)
673  qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
674  zinc_(Zdistio);
675  qh_distplane(qh interior_point, facet, &dist);
676  qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
677  }
678  if (!qh_QUICKhelp) {
679  if (qh HALFspace)
680  qh_fprintf(fp, 9382, "\n\
681 These points are the dual of the given halfspaces. They indicate that\n\
682 the intersection is degenerate.\n");
683  qh_fprintf(fp, 9383,"\n\
684 These points either have a maximum or minimum x-coordinate, or\n\
685 they maximize the determinant for k coordinates. Trial points\n\
686 are first selected from points that maximize a coordinate.\n");
687  if (qh hull_dim >= qh_INITIALmax)
688  qh_fprintf(fp, 9384, "\n\
689 Because of the high dimension, the min x-coordinate and max-coordinate\n\
690 points are used if the determinant is non-zero. Option 'Qs' will\n\
691 do a better, though much slower, job. Instead of 'Qs', you can change\n\
692 the points by randomly rotating the input with 'QR0'.\n");
693  }
694  qh_fprintf(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
695  for (k=0; k < qh hull_dim; k++) {
696  min= REALmax;
697  max= -REALmin;
698  for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
699  maximize_(max, *coord);
700  minimize_(min, *coord);
701  }
702  qh_fprintf(fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
703  }
704  if (!qh_QUICKhelp) {
705  qh_fprintf(fp, 9387, "\n\
706 If the input should be full dimensional, you have several options that\n\
707 may determine an initial simplex:\n\
708  - use 'QJ' to joggle the input and make it full dimensional\n\
709  - use 'QbB' to scale the points to the unit cube\n\
710  - use 'QR0' to randomly rotate the input for different maximum points\n\
711  - use 'Qs' to search all points for the initial simplex\n\
712  - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
713  - trace execution with 'T3' to see the determinant for each point.\n",
714  qh DISTround);
715 #if REALfloat
716  qh_fprintf(fp, 9388, "\
717  - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
718 #endif
719  qh_fprintf(fp, 9389, "\n\
720 If the input is lower dimensional:\n\
721  - use 'QJ' to joggle the input and make it full dimensional\n\
722  - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
723  pick the coordinate with the least range. The hull will have the\n\
724  correct topology.\n\
725  - determine the flat containing the points, rotate the points\n\
726  into a coordinate plane, and delete the other coordinates.\n\
727  - add one or more points to make the input full dimensional.\n\
728 ");
729  if (qh DELAUNAY && !qh ATinfinity)
730  qh_fprintf(fp, 9390, "\n\n\
731 This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
732  - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
733  - or use 'QJ' to joggle the input and avoid co-circular data\n");
734  }
735 } /* printhelp_singular */
736 
737 
738 /*-----------------------------------------
739 -user_memsizes- allocate up to 10 additional, quick allocation sizes
740 */
741 void qh_user_memsizes(void) {
742 
743  /* qh_memsize(size); */
744 } /* user_memsizes */
745 
746 #endif
facetT * qh_findbestfacet(pointT *point, boolT bestoutside, realT *bestdist, boolT *isoutside)
Definition: poly2.c:1239
void seed(unsigned int seed_value)
#define qh_ERRqhull
Definition: libqhull.h:198
#define FORALLfacets
Definition: libqhull.h:840
#define zinc_(id)
Definition: stat.h:386
void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex)
Definition: user_eg2.c:534
#define boolT
Definition: libqhull.h:121
#define qh_RANDOMmax
Definition: user.h:282
Definition: qset.h:83
#define qh_INITIALmax
Definition: user.h:420
#define FOREACHvertex_(vertices)
Definition: libqhull.h:950
void qh_printpoint(FILE *fp, const char *string, pointT *point)
Definition: io.c:2852
void findDelaunay(int dim)
Definition: user_eg2.c:229
#define pointT
Definition: libqhull.h:96
void makehalf(coordT *points, int numpoints, int dim)
Definition: user_eg2.c:259
#define getid_(p)
Definition: libqhull.h:823
void qh_printhelp_singular(FILE *fp)
Definition: user_eg2.c:650
void qh_fprintf(FILE *fp, int msgcode, const char *fmt,...)
Definition: userprintf.c:42
void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge)
Definition: user_eg2.c:496
coordT * qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible)
Definition: geom2.c:1918
void qh_check_output(void)
Definition: poly2.c:302
void qh_printend(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall)
Definition: io.c:1690
#define FORALLfacet_(facetlist)
Definition: poly.h:77
void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall)
Definition: user_eg2.c:542
qhT qh_qh
Definition: global.c:26
void addDelaunay(coordT *points, int numpoints, int numnew, int dim)
Definition: user_eg2.c:182
void print_summary(void)
Definition: user_eg2.c:71
int qh_pointid(pointT *point)
Definition: poly.c:1053
#define qh_RANDOMint
Definition: user.h:283
void qh_nearcoplanar(void)
Definition: poly2.c:2198
void qh_init_A(FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[])
Definition: global.c:487
#define REALmax
Definition: user.h:155
#define SIZEcube
Definition: user_eg2.c:333
#define qh_QUICKhelp
Definition: user.h:643
void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible)
Definition: user_eg2.c:296
setT * vertices
Definition: libqhull.h:295
boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist)
Definition: libqhull.c:168
void qh_triangulate(void)
Definition: poly2.c:2767
boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp, coordT *normal, coordT *offset, coordT *feasible)
Definition: geom2.c:1844
#define coordT
Definition: libqhull.h:80
#define True
Definition: libqhull.h:129
void qh_check_points(void)
Definition: poly2.c:365
#define zzval_(id)
Definition: stat.h:413
void qh_printhelp_narrowhull(FILE *fp, realT minangle)
Definition: user_eg2.c:637
#define qh
Definition: libqhull.h:457
void qh_setdelaunay(int dim, int count, pointT *points)
Definition: geom2.c:1806
void qh_printpointid(FILE *fp, const char *string, int dim, pointT *point, int id)
Definition: io.c:2858
void qh_printhelp_degenerate(FILE *fp)
Definition: user_eg2.c:563
pointT * point
Definition: libqhull.h:399
Definition: stat.h:106
void makecube(coordT *points, int numpoints, int dim)
Definition: user_eg2.c:88
void qh_produce_output(void)
Definition: io.c:39
void qh_freeqhull(boolT allmem)
Definition: global.c:425
#define maximize_(maxval, val)
Definition: geom.h:51
#define DIM
Definition: user_eg2.c:332
void qh_init_B(coordT *points, int numpoints, int dim, boolT ismalloc)
Definition: global.c:534
void qh_setfeasible(int dim)
Definition: io.c:3967
#define SIZEdiamond
Definition: user_eg2.c:334
#define FOREACHfacet_(facets)
Definition: libqhull.h:891
#define QHULL_LIB_CHECK
Definition: libqhull.h:462
void qh_printbegin(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall)
Definition: io.c:1309
void qh_memfreeshort(int *curlong, int *totlong)
Definition: mem.c:288
#define REALmin
Definition: user.h:156
#define QHULL_UNUSED(x)
Definition: qhull_a.h:109
void qh_printafacet(FILE *fp, qh_PRINT format, facetT *facet, boolT printall)
Definition: io.c:1113
void qh_check_maxout(void)
Definition: poly2.c:218
void makeDelaunay(coordT *points, int numpoints, int dim)
Definition: user_eg2.c:155
void qh_initflags(char *command)
Definition: global.c:615
#define False
Definition: libqhull.h:128
#define qh_ALL
Definition: libqhull.h:180
void adddiamond(coordT *points, int numpoints, int numnew, int dim)
Definition: user_eg2.c:115
void qh_distplane(pointT *point, facetT *facet, realT *dist)
Definition: geom.c:36
int qh_setsize(setT *set)
Definition: qset.c:1111
#define TOTpoints
Definition: user_eg2.c:335
unsigned id
Definition: libqhull.h:311
void qh_user_memsizes(void)
Definition: user_eg2.c:741
#define qh_RANDOMseed_(seed)
Definition: user.h:284
#define realT
Definition: user.h:154
coordT * normal
Definition: libqhull.h:274
void qh_qhull(void)
Definition: libqhull.c:60
int main(int argc, char *argv[])
Definition: user_eg2.c:346
void qh_printvertexlist(FILE *fp, const char *string, facetT *facetlist, setT *facets, boolT printall)
Definition: io.c:3266
#define minimize_(minval, val)
Definition: geom.h:59
flagT tricoplanar
Definition: libqhull.h:314


hpp-fcl
Author(s):
autogenerated on Fri Jun 2 2023 02:39:02