Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Analysis.AlgorithmBehavior/qhull-2012.1/src/libqhull/rboxlib.c @ 11303

Last change on this file since 11303 was 10207, checked in by ascheibe, 11 years ago

#1886 added a unit test for volume calculation and the qhull library

File size: 22.5 KB
Line 
1/*<html><pre>  -<a                             href="index.htm#TOC"
2  >-------------------------------</a><a name="TOP">-</a>
3
4   rboxlib.c
5     Generate input points
6
7   notes:
8     For documentation, see prompt[] of rbox.c
9     50 points generated for 'rbox D4'
10
11   WARNING:
12     incorrect range if qh_RANDOMmax is defined wrong (user.h)
13*/
14
15#include "random.h"
16#include "libqhull.h"
17
18#include <ctype.h>
19#include <limits.h>
20#include <math.h>
21#include <setjmp.h>
22#include <string.h>
23#include <time.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27#ifdef _MSC_VER  /* Microsoft Visual C++ */
28#pragma warning( disable : 4706)  /* assignment within conditional expression. */
29#pragma warning( disable : 4996)  /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
30#endif
31
32#define MAXdim 200
33#define PI 3.1415926535897932384
34
35/* ------------------------------ prototypes ----------------*/
36int roundi( double a);
37void out1( double a);
38void out2n( double a, double b);
39void out3n( double a, double b, double c);
40
41void    qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
42void    qh_free(void *mem);
43void   *qh_malloc(size_t size);
44int     qh_rand( void);
45void    qh_srand( int seed);
46
47
48/* ------------------------------ globals -------------------*/
49
50/* No state is carried between rbox requests */
51typedef struct rboxT rboxT;
52struct rboxT {
53  FILE *fout;
54  FILE *ferr;
55  int isinteger;
56  double out_offset;
57  jmp_buf errexit;        /* exit label for rboxpoints, defined by setjmp(), called by qh_errexit_rbox() */
58};
59
60
61int rbox_inuse= 0;
62rboxT rbox;
63
64/*-<a                             href="qh-qhull.htm#TOC"
65  >-------------------------------</a><a name="rboxpoints">-</a>
66
67  qh_rboxpoints( fout, ferr, rbox_command )
68    Generate points to fout according to rbox options
69    Report errors on ferr
70
71  returns:
72    0 (qh_ERRnone) on success
73    1 (qh_ERRinput) on input error
74    4 (qh_ERRmem) on memory error
75    5 (qh_ERRqhull) on internal error
76
77  notes:
78    To avoid stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
79    Rbox is not multithreaded.
80
81  design:
82    Straight line code (consider defining a struct and functions):
83
84    Parse arguments into variables
85    Determine the number of points
86    Generate the points
87*/
88int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
89  int i,j,k;
90  int gendim;
91  int cubesize, diamondsize, seed=0, count, apex;
92  int dim=3 , numpoints= 0, totpoints, addpoints=0;
93  int issphere=0, isaxis=0,  iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
94  int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0;
95  int israndom=0, istime=0;
96  int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
97  double width=0.0, gap=0.0, radius= 0.0;
98  double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
99  double *simplex= NULL, *simplexp;
100  int nthroot, mult[MAXdim];
101  double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
102  double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
103  double box= qh_DEFAULTbox; /* scale all numbers before output */
104  double randmax= qh_RANDOMmax;
105  char command[200], seedbuf[200];
106  char *s= command, *t, *first_point= NULL;
107  time_t timedata;
108  int exitcode;
109
110  if (rbox_inuse) {
111    qh_fprintf_rbox(rbox.ferr, 6188, "rbox error: rbox in use by another process.  Please lock calls to rbox.\n");
112    return qh_ERRqhull;
113  }
114  rbox_inuse= True;
115  rbox.ferr= ferr;
116  rbox.fout= fout;
117
118  exitcode= setjmp(rbox.errexit);
119  if (exitcode) {
120    /* same code for error exit and normal return */
121    if (simplex)
122        qh_free(simplex);
123    rbox_inuse= False;
124    return exitcode;
125  }
126
127  *command= '\0';
128  strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
129
130  while (*s && !isspace(*s))  /* skip program name */
131    s++;
132  while (*s) {
133    while (*s && isspace(*s))
134      s++;
135    if (*s == '-')
136      s++;
137    if (!*s)
138      break;
139    if (isdigit(*s)) {
140      numpoints= qh_strtol(s, &s);
141      continue;
142    }
143    /* ============= read flags =============== */
144    switch (*s++) {
145    case 'c':
146      addcube= 1;
147      t= s;
148      while (isspace(*t))
149        t++;
150      if (*t == 'G')
151        cube= qh_strtod(++t, &s);
152      break;
153    case 'd':
154      adddiamond= 1;
155      t= s;
156      while (isspace(*t))
157        t++;
158      if (*t == 'G')
159        diamond= qh_strtod(++t, &s);
160      break;
161    case 'h':
162      iscdd= 1;
163      break;
164    case 'l':
165      isspiral= 1;
166      break;
167    case 'n':
168      NOcommand= 1;
169      break;
170    case 'r':
171      isregular= 1;
172      break;
173    case 's':
174      issphere= 1;
175      break;
176    case 't':
177      istime= 1;
178      if (isdigit(*s)) {
179        seed= qh_strtol(s, &s);
180        israndom= 0;
181      }else
182        israndom= 1;
183      break;
184    case 'x':
185      issimplex= 1;
186      break;
187    case 'y':
188      issimplex2= 1;
189      break;
190    case 'z':
191      rbox.isinteger= 1;
192      break;
193    case 'B':
194      box= qh_strtod(s, &s);
195      isbox= 1;
196      break;
197    case 'D':
198      dim= qh_strtol(s, &s);
199      if (dim < 1
200      || dim > MAXdim) {
201        qh_fprintf_rbox(rbox.ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
202        qh_errexit_rbox(qh_ERRinput);
203      }
204      break;
205    case 'G':
206      if (isdigit(*s))
207        gap= qh_strtod(s, &s);
208      else
209        gap= 0.5;
210      isgap= 1;
211      break;
212    case 'L':
213      if (isdigit(*s))
214        radius= qh_strtod(s, &s);
215      else
216        radius= 10;
217      islens= 1;
218      break;
219    case 'M':
220      ismesh= 1;
221      if (*s)
222        meshn= qh_strtod(s, &s);
223      if (*s == ',') {
224        ++s;
225        meshm= qh_strtod(s, &s);
226      }else
227        meshm= 0.0;
228      if (*s == ',') {
229        ++s;
230        meshr= qh_strtod(s, &s);
231      }else
232        meshr= sqrt(meshn*meshn + meshm*meshm);
233      if (*s && !isspace(*s)) {
234        qh_fprintf_rbox(rbox.ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
235        meshn= 3.0, meshm=4.0, meshr=5.0;
236      }
237      break;
238    case 'O':
239      rbox.out_offset= qh_strtod(s, &s);
240      break;
241    case 'P':
242      if (!first_point)
243        first_point= s-1;
244      addpoints++;
245      while (*s && !isspace(*s))   /* read points later */
246        s++;
247      break;
248    case 'W':
249      width= qh_strtod(s, &s);
250      iswidth= 1;
251      break;
252    case 'Z':
253      if (isdigit(*s))
254        radius= qh_strtod(s, &s);
255      else
256        radius= 1.0;
257      isaxis= 1;
258      break;
259    default:
260      qh_fprintf_rbox(rbox.ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
261      qh_errexit_rbox(qh_ERRinput);
262    }
263    if (*s && !isspace(*s)) {
264      qh_fprintf_rbox(rbox.ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
265      qh_errexit_rbox(qh_ERRinput);
266    }
267  }
268
269  /* ============= defaults, constants, and sizes =============== */
270  if (rbox.isinteger && !isbox)
271    box= qh_DEFAULTzbox;
272  if (addcube) {
273    cubesize= (int)floor(ldexp(1.0,dim)+0.5);
274    if (cube == 0.0)
275      cube= box;
276  }else
277    cubesize= 0;
278  if (adddiamond) {
279    diamondsize= 2*dim;
280    if (diamond == 0.0)
281      diamond= box;
282  }else
283    diamondsize= 0;
284  if (islens) {
285    if (isaxis) {
286        qh_fprintf_rbox(rbox.ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
287        qh_errexit_rbox(qh_ERRinput);
288    }
289    if (radius <= 1.0) {
290        qh_fprintf_rbox(rbox.ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
291               radius);
292        qh_errexit_rbox(qh_ERRinput);
293    }
294    lensangle= asin(1.0/radius);
295    lensbase= radius * cos(lensangle);
296  }
297
298  if (!numpoints) {
299    if (issimplex2)
300        ; /* ok */
301    else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
302        qh_fprintf_rbox(rbox.ferr, 6192, "rbox error: missing count\n");
303        qh_errexit_rbox(qh_ERRinput);
304    }else if (adddiamond + addcube + addpoints)
305        ; /* ok */
306    else {
307        numpoints= 50;  /* ./rbox D4 is the test case */
308        issphere= 1;
309    }
310  }
311  if ((issimplex + islens + isspiral + ismesh > 1)
312  || (issimplex + issphere + isspiral + ismesh > 1)) {
313    qh_fprintf_rbox(rbox.ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
314    qh_errexit_rbox(qh_ERRinput);
315  }
316
317  /* ============= print header with total points =============== */
318  if (issimplex || ismesh)
319    totpoints= numpoints;
320  else if (issimplex2)
321    totpoints= numpoints+dim+1;
322  else if (isregular) {
323    totpoints= numpoints;
324    if (dim == 2) {
325        if (islens)
326          totpoints += numpoints - 2;
327    }else if (dim == 3) {
328        if (islens)
329          totpoints += 2 * numpoints;
330      else if (isgap)
331        totpoints += 1 + numpoints;
332      else
333        totpoints += 2;
334    }
335  }else
336    totpoints= numpoints + isaxis;
337  totpoints += cubesize + diamondsize + addpoints;
338
339  /* ============= seed randoms =============== */
340  if (istime == 0) {
341    for (s=command; *s; s++) {
342      if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
343        i= 'x';
344      else
345        i= *s;
346      seed= 11*seed + i;
347    }
348  }else if (israndom) {
349    seed= (int)time(&timedata);
350    sprintf(seedbuf, " t%d", seed);  /* appends an extra t, not worth removing */
351    strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
352    t= strstr(command, " t ");
353    if (t)
354      strcpy(t+1, t+3); /* remove " t " */
355  } /* else, seed explicitly set to n */
356  qh_RANDOMseed_(seed);
357
358  /* ============= print header =============== */
359
360  if (iscdd)
361      qh_fprintf_rbox(rbox.fout, 9391, "%s\nbegin\n        %d %d %s\n",
362      NOcommand ? "" : command,
363      totpoints, dim+1,
364      rbox.isinteger ? "integer" : "real");
365  else if (NOcommand)
366      qh_fprintf_rbox(rbox.fout, 9392, "%d\n%d\n", dim, totpoints);
367  else
368      qh_fprintf_rbox(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
369
370  /* ============= explicit points =============== */
371  if ((s= first_point)) {
372    while (s && *s) { /* 'P' */
373      count= 0;
374      if (iscdd)
375        out1( 1.0);
376      while (*++s) {
377        out1( qh_strtod(s, &s));
378        count++;
379        if (isspace(*s) || !*s)
380          break;
381        if (*s != ',') {
382          qh_fprintf_rbox(rbox.ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
383          qh_errexit_rbox(qh_ERRinput);
384        }
385      }
386      if (count < dim) {
387        for (k=dim-count; k--; )
388          out1( 0.0);
389      }else if (count > dim) {
390        qh_fprintf_rbox(rbox.ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
391                  count, dim, s);
392        qh_errexit_rbox(qh_ERRinput);
393      }
394      qh_fprintf_rbox(rbox.fout, 9394, "\n");
395      while ((s= strchr(s, 'P'))) {
396        if (isspace(s[-1]))
397          break;
398      }
399    }
400  }
401
402  /* ============= simplex distribution =============== */
403  if (issimplex+issimplex2) {
404    if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
405      qh_fprintf_rbox(rbox.ferr, 6196, "rbox error: insufficient memory for simplex\n");
406      qh_errexit_rbox(qh_ERRmem); /* qh_ERRmem */
407    }
408    simplexp= simplex;
409    if (isregular) {
410      for (i=0; i<dim; i++) {
411        for (k=0; k<dim; k++)
412          *(simplexp++)= i==k ? 1.0 : 0.0;
413      }
414      for (k=0; k<dim; k++)
415        *(simplexp++)= -1.0;
416    }else {
417      for (i=0; i<dim+1; i++) {
418        for (k=0; k<dim; k++) {
419          randr= qh_RANDOMint;
420          *(simplexp++)= 2.0 * randr/randmax - 1.0;
421        }
422      }
423    }
424    if (issimplex2) {
425        simplexp= simplex;
426      for (i=0; i<dim+1; i++) {
427        if (iscdd)
428          out1( 1.0);
429        for (k=0; k<dim; k++)
430          out1( *(simplexp++) * box);
431        qh_fprintf_rbox(rbox.fout, 9395, "\n");
432      }
433    }
434    for (j=0; j<numpoints; j++) {
435      if (iswidth)
436        apex= qh_RANDOMint % (dim+1);
437      else
438        apex= -1;
439      for (k=0; k<dim; k++)
440        coord[k]= 0.0;
441      norm= 0.0;
442      for (i=0; i<dim+1; i++) {
443        randr= qh_RANDOMint;
444        factor= randr/randmax;
445        if (i == apex)
446          factor *= width;
447        norm += factor;
448        for (k=0; k<dim; k++) {
449          simplexp= simplex + i*dim + k;
450          coord[k] += factor * (*simplexp);
451        }
452      }
453      for (k=0; k<dim; k++)
454        coord[k] /= norm;
455      if (iscdd)
456        out1( 1.0);
457      for (k=0; k < dim; k++)
458        out1( coord[k] * box);
459      qh_fprintf_rbox(rbox.fout, 9396, "\n");
460    }
461    isregular= 0; /* continue with isbox */
462    numpoints= 0;
463  }
464
465  /* ============= mesh distribution =============== */
466  if (ismesh) {
467    nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
468    for (k=dim; k--; )
469      mult[k]= 0;
470    for (i=0; i < numpoints; i++) {
471      for (k=0; k < dim; k++) {
472        if (k == 0)
473          out1( mult[0] * meshn + mult[1] * (-meshm));
474        else if (k == 1)
475          out1( mult[0] * meshm + mult[1] * meshn);
476        else
477          out1( mult[k] * meshr );
478      }
479      qh_fprintf_rbox(rbox.fout, 9397, "\n");
480      for (k=0; k < dim; k++) {
481        if (++mult[k] < nthroot)
482          break;
483        mult[k]= 0;
484      }
485    }
486  }
487  /* ============= regular points for 's' =============== */
488  else if (isregular && !islens) {
489    if (dim != 2 && dim != 3) {
490      qh_fprintf_rbox(rbox.ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
491      qh_errexit_rbox(qh_ERRinput);
492    }
493    if (!isaxis || radius == 0.0) {
494      isaxis= 1;
495      radius= 1.0;
496    }
497    if (dim == 3) {
498      if (iscdd)
499        out1( 1.0);
500      out3n( 0.0, 0.0, -box);
501      if (!isgap) {
502        if (iscdd)
503          out1( 1.0);
504        out3n( 0.0, 0.0, box);
505      }
506    }
507    angle= 0.0;
508    anglediff= 2.0 * PI/numpoints;
509    for (i=0; i < numpoints; i++) {
510      angle += anglediff;
511      x= radius * cos(angle);
512      y= radius * sin(angle);
513      if (dim == 2) {
514        if (iscdd)
515          out1( 1.0);
516        out2n( x*box, y*box);
517      }else {
518        norm= sqrt(1.0 + x*x + y*y);
519        if (iscdd)
520          out1( 1.0);
521        out3n( box*x/norm, box*y/norm, box/norm);
522        if (isgap) {
523          x *= 1-gap;
524          y *= 1-gap;
525          norm= sqrt(1.0 + x*x + y*y);
526          if (iscdd)
527            out1( 1.0);
528          out3n( box*x/norm, box*y/norm, box/norm);
529        }
530      }
531    }
532  }
533  /* ============= regular points for 'r Ln D2' =============== */
534  else if (isregular && islens && dim == 2) {
535    double cos_0;
536
537    angle= lensangle;
538    anglediff= 2 * lensangle/(numpoints - 1);
539    cos_0= cos(lensangle);
540    for (i=0; i < numpoints; i++, angle -= anglediff) {
541      x= radius * sin(angle);
542      y= radius * (cos(angle) - cos_0);
543      if (iscdd)
544        out1( 1.0);
545      out2n( x*box, y*box);
546      if (i != 0 && i != numpoints - 1) {
547        if (iscdd)
548          out1( 1.0);
549        out2n( x*box, -y*box);
550      }
551    }
552  }
553  /* ============= regular points for 'r Ln D3' =============== */
554  else if (isregular && islens && dim != 2) {
555    if (dim != 3) {
556      qh_fprintf_rbox(rbox.ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
557      qh_errexit_rbox(qh_ERRinput);
558    }
559    angle= 0.0;
560    anglediff= 2* PI/numpoints;
561    if (!isgap) {
562      isgap= 1;
563      gap= 0.5;
564    }
565    offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
566    for (i=0; i < numpoints; i++, angle += anglediff) {
567      x= cos(angle);
568      y= sin(angle);
569      if (iscdd)
570        out1( 1.0);
571      out3n( box*x, box*y, 0.0);
572      x *= 1-gap;
573      y *= 1-gap;
574      if (iscdd)
575        out1( 1.0);
576      out3n( box*x, box*y, box * offset);
577      if (iscdd)
578        out1( 1.0);
579      out3n( box*x, box*y, -box * offset);
580    }
581  }
582  /* ============= apex of 'Zn' distribution + gendim =============== */
583  else {
584    if (isaxis) {
585      gendim= dim-1;
586      if (iscdd)
587        out1( 1.0);
588      for (j=0; j < gendim; j++)
589        out1( 0.0);
590      out1( -box);
591      qh_fprintf_rbox(rbox.fout, 9398, "\n");
592    }else if (islens)
593      gendim= dim-1;
594    else
595      gendim= dim;
596    /* ============= generate random point in unit cube =============== */
597    for (i=0; i < numpoints; i++) {
598      norm= 0.0;
599      for (j=0; j < gendim; j++) {
600        randr= qh_RANDOMint;
601        coord[j]= 2.0 * randr/randmax - 1.0;
602        norm += coord[j] * coord[j];
603      }
604      norm= sqrt(norm);
605      /* ============= dim-1 point of 'Zn' distribution ========== */
606      if (isaxis) {
607        if (!isgap) {
608          isgap= 1;
609          gap= 1.0;
610        }
611        randr= qh_RANDOMint;
612        rangap= 1.0 - gap * randr/randmax;
613        factor= radius * rangap / norm;
614        for (j=0; j<gendim; j++)
615          coord[j]= factor * coord[j];
616      /* ============= dim-1 point of 'Ln s' distribution =========== */
617      }else if (islens && issphere) {
618        if (!isgap) {
619          isgap= 1;
620          gap= 1.0;
621        }
622        randr= qh_RANDOMint;
623        rangap= 1.0 - gap * randr/randmax;
624        factor= rangap / norm;
625        for (j=0; j<gendim; j++)
626          coord[j]= factor * coord[j];
627      /* ============= dim-1 point of 'Ln' distribution ========== */
628      }else if (islens && !issphere) {
629        if (!isgap) {
630          isgap= 1;
631          gap= 1.0;
632        }
633        j= qh_RANDOMint % gendim;
634        if (coord[j] < 0)
635          coord[j]= -1.0 - coord[j] * gap;
636        else
637          coord[j]= 1.0 - coord[j] * gap;
638      /* ============= point of 'l' distribution =============== */
639      }else if (isspiral) {
640        if (dim != 3) {
641          qh_fprintf_rbox(rbox.ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
642          longjmp(rbox.errexit,qh_ERRinput);
643        }
644        coord[0]= cos(2*PI*i/(numpoints - 1));
645        coord[1]= sin(2*PI*i/(numpoints - 1));
646        coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
647      /* ============= point of 's' distribution =============== */
648      }else if (issphere) {
649        factor= 1.0/norm;
650        if (iswidth) {
651          randr= qh_RANDOMint;
652          factor *= 1.0 - width * randr/randmax;
653        }
654        for (j=0; j<dim; j++)
655          coord[j]= factor * coord[j];
656      }
657      /* ============= project 'Zn s' point in to sphere =============== */
658      if (isaxis && issphere) {
659        coord[dim-1]= 1.0;
660        norm= 1.0;
661        for (j=0; j<gendim; j++)
662          norm += coord[j] * coord[j];
663        norm= sqrt(norm);
664        for (j=0; j<dim; j++)
665          coord[j]= coord[j] / norm;
666        if (iswidth) {
667          randr= qh_RANDOMint;
668          coord[dim-1] *= 1 - width * randr/randmax;
669        }
670      /* ============= project 'Zn' point onto cube =============== */
671      }else if (isaxis && !issphere) {  /* not very interesting */
672        randr= qh_RANDOMint;
673        coord[dim-1]= 2.0 * randr/randmax - 1.0;
674      /* ============= project 'Ln' point out to sphere =============== */
675      }else if (islens) {
676        coord[dim-1]= lensbase;
677        for (j=0, norm= 0; j<dim; j++)
678          norm += coord[j] * coord[j];
679        norm= sqrt(norm);
680        for (j=0; j<dim; j++)
681          coord[j]= coord[j] * radius/ norm;
682        coord[dim-1] -= lensbase;
683        if (iswidth) {
684          randr= qh_RANDOMint;
685          coord[dim-1] *= 1 - width * randr/randmax;
686        }
687        if (qh_RANDOMint > randmax/2)
688          coord[dim-1]= -coord[dim-1];
689      /* ============= project 'Wn' point toward boundary =============== */
690      }else if (iswidth && !issphere) {
691        j= qh_RANDOMint % gendim;
692        if (coord[j] < 0)
693          coord[j]= -1.0 - coord[j] * width;
694        else
695          coord[j]= 1.0 - coord[j] * width;
696      }
697      /* ============= write point =============== */
698      if (iscdd)
699        out1( 1.0);
700      for (k=0; k < dim; k++)
701        out1( coord[k] * box);
702      qh_fprintf_rbox(rbox.fout, 9399, "\n");
703    }
704  }
705
706  /* ============= write cube vertices =============== */
707  if (addcube) {
708    for (j=0; j<cubesize; j++) {
709      if (iscdd)
710        out1( 1.0);
711      for (k=dim-1; k>=0; k--) {
712        if (j & ( 1 << k))
713          out1( cube);
714        else
715          out1( -cube);
716      }
717      qh_fprintf_rbox(rbox.fout, 9400, "\n");
718    }
719  }
720
721  /* ============= write diamond vertices =============== */
722  if (adddiamond) {
723    for (j=0; j<diamondsize; j++) {
724      if (iscdd)
725        out1( 1.0);
726      for (k=dim-1; k>=0; k--) {
727        if (j/2 != k)
728          out1( 0.0);
729        else if (j & 0x1)
730          out1( diamond);
731        else
732          out1( -diamond);
733      }
734      qh_fprintf_rbox(rbox.fout, 9401, "\n");
735    }
736  }
737
738  if (iscdd)
739    qh_fprintf_rbox(rbox.fout, 9402, "end\nhull\n");
740
741  /* same code for error exit and normal return */
742  if (simplex)
743    qh_free(simplex);
744  rbox_inuse= False;
745  return qh_ERRnone;
746} /* rboxpoints */
747
748/*------------------------------------------------
749outxxx - output functions
750*/
751int roundi( double a) {
752  if (a < 0.0) {
753    if (a - 0.5 < INT_MIN) {
754      qh_fprintf_rbox(rbox.ferr, 6200, "rbox input error: negative coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
755      qh_errexit_rbox(qh_ERRinput);
756    }
757    return (int)(a - 0.5);
758  }else {
759    if (a + 0.5 > INT_MAX) {
760      qh_fprintf_rbox(rbox.ferr, 6201, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
761      qh_errexit_rbox(qh_ERRinput);
762    }
763    return (int)(a + 0.5);
764  }
765} /* roundi */
766
767void out1(double a) {
768
769  if (rbox.isinteger)
770    qh_fprintf_rbox(rbox.fout, 9403, "%d ", roundi( a+rbox.out_offset));
771  else
772    qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset);
773} /* out1 */
774
775void out2n( double a, double b) {
776
777  if (rbox.isinteger)
778    qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset));
779  else
780    qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset);
781} /* out2n */
782
783void out3n( double a, double b, double c) {
784
785  if (rbox.isinteger)
786    qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset), roundi(c+rbox.out_offset));
787  else
788    qh_fprintf_rbox(rbox.fout, 9408, qh_REAL_3n, a+rbox.out_offset, b+rbox.out_offset, c+rbox.out_offset);
789} /* out3n */
790
791void qh_errexit_rbox(int exitcode)
792{
793    longjmp(rbox.errexit, exitcode);
794} /* rbox_errexit */
795
Note: See TracBrowser for help on using the repository browser.