ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/gen/genprism.c
(Generate patch)

Comparing ray/src/gen/genprism.c (file contents):
Revision 2.6 by greg, Tue Mar 19 16:30:56 1996 UTC vs.
Revision 2.15 by greg, Thu Aug 14 19:32:00 2025 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1996 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  genprism.c - generate a prism.
6   *              2D vertices in the xy plane are given on the
# Line 12 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9   *              orientation.
10   */
11  
12 < #include  <stdio.h>
13 <
12 > #include  "rtio.h"
13 > #include  "paths.h"
14   #include  <math.h>
18
15   #include  <ctype.h>
16  
17   #define  MAXVERT        1024            /* maximum # vertices */
18  
19   #define  FTINY          1e-6
20  
25 #ifdef  DCL_ATOF
26 extern double  atof();
27 #endif
28
21   char  *pmtype;          /* material type */
22   char  *pname;           /* name */
23  
24   double  lvect[3] = {0.0, 0.0, 1.0};
25 + int     lvdir = 1;
26   double  llen = 1.0;
27  
28   double  vert[MAXVERT][2];
# Line 40 | Line 33 | double a[MAXVERT];             /* corner trim sizes */
33  
34   int  do_ends = 1;               /* include end caps */
35   int  iscomplete = 0;            /* polygon is already completed */
36 < double  crad = 0.0;             /* radius for corners */
36 > double  crad = 0.0;             /* radius for corners (sign from lvdir) */
37  
45 #define rounding        (crad > FTINY)
38  
39 <
40 < main(argc, argv)
49 < int  argc;
50 < char  **argv;
39 > void
40 > readverts(char *fname)          /* read vertices from a file */
41   {
42 <        int  an;
53 <        
54 <        if (argc < 4)
55 <                goto userr;
42 >        FILE  *fp;
43  
44 <        pmtype = argv[1];
45 <        pname = argv[2];
46 <
47 <        if (!strcmp(argv[3], "-")) {
48 <                readverts(NULL);
62 <                an = 4;
63 <        } else if (isdigit(argv[3][0])) {
64 <                nverts = atoi(argv[3]);
65 <                if (argc-3 < 2*nverts)
66 <                        goto userr;
67 <                for (an = 0; an < nverts; an++) {
68 <                        vert[an][0] = atof(argv[2*an+4]);
69 <                        vert[an][1] = atof(argv[2*an+5]);
70 <                }
71 <                an = 2*nverts+4;
72 <        } else {
73 <                readverts(argv[3]);
74 <                an = 4;
75 <        }
76 <        if (nverts < 3) {
77 <                fprintf(stderr, "%s: not enough vertices\n", argv[0]);
44 >        if (fname == NULL) {
45 >                fp = stdin;
46 >                fname = "<stdin>";
47 >        } else if ((fp = fopen(fname, "r")) == NULL) {
48 >                fprintf(stderr, "%s: cannot open\n", fname);
49                  exit(1);
50          }
51 <
52 <        for ( ; an < argc; an++) {
82 <                if (argv[an][0] != '-')
83 <                        goto userr;
84 <                switch (argv[an][1]) {
85 <                case 'l':                               /* length vector */
86 <                        lvect[0] = atof(argv[++an]);
87 <                        lvect[1] = atof(argv[++an]);
88 <                        lvect[2] = atof(argv[++an]);
89 <                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
90 <                                        lvect[2]*lvect[2]);
91 <                        if (llen <= FTINY) {
92 <                                fprintf(stderr, "%s: zero extrusion vector\n",
93 <                                                argv[0]);
94 <                                exit(1);
95 <                        }
51 >        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
52 >                if (++nverts >= MAXVERT)
53                          break;
54 <                case 'r':                               /* radius */
55 <                        crad = atof(argv[++an]);
56 <                        break;
57 <                case 'e':                               /* ends */
58 <                        do_ends = !do_ends;
59 <                        break;
103 <                case 'c':                               /* complete */
104 <                        iscomplete = !iscomplete;
105 <                        break;
106 <                default:
107 <                        goto userr;
108 <                }
109 <        }
110 <        if (rounding) {
111 <                if (crad > fabs(lvect[2])) {
112 <                        fprintf(stderr, "%s: rounding greater than height\n",
113 <                                        argv[0]);
54 >
55 >        if (!feof(fp)) {
56 >                if (nverts < MAXVERT) {
57 >                        fprintf(stderr, "%s: warning - non-numerical data\n", fname);
58 >                } else {
59 >                        fprintf(stderr, "%s: too many vertices\n", fname);
60                          exit(1);
61                  }
116                compute_rounding();
62          }
63 <        printhead(argc, argv);
63 >        fclose(fp);
64 > }
65  
120        if (do_ends)
121                if (rounding)
122                        printrends();
123                else
124                        printends();
66  
67 <        printsides(rounding);
68 <
69 <        exit(0);
70 < userr:
71 <        fprintf(stderr, "Usage: %s material name ", argv[0]);
72 <        fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
73 <        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
74 <        exit(1);
67 > void
68 > side(int n0, int n1)                    /* print single side */
69 > {
70 >        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
71 >        printf("0\n0\n12\n");
72 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
73 >                        vert[n0][1], 0.0);
74 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0]+lvect[0],
75 >                        vert[n0][1]+lvect[1], lvect[2]);
76 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0]+lvect[0],
77 >                        vert[n1][1]+lvect[1], lvect[2]);
78 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0],
79 >                        vert[n1][1], 0.0);
80   }
81  
82  
83 < readverts(fname)                /* read vertices from a file */
84 < char  *fname;
83 > void
84 > rside(int n0, int n1)                   /* print side with rounded edge */
85   {
86 <        FILE  *fp;
86 >        double  s, c, t[3];
87  
88 <        if (fname == NULL)
89 <                fp = stdin;
90 <        else if ((fp = fopen(fname, "r")) == NULL) {
91 <                fprintf(stderr, "%s: cannot open\n", fname);
92 <                exit(1);
93 <        }
94 <        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
95 <                nverts++;
96 <        fclose(fp);
88 >                                        /* compute tanget offset vector */
89 >        s = lvdir*(lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
90 >        if (s < -FTINY || s > FTINY) {
91 >                c = sqrt(1. - s*s);
92 >                t[0] = (c - 1.)*u[n1][1];
93 >                t[1] = (1. - c)*u[n1][0];
94 >                t[2] = s;
95 >        } else
96 >                t[0] = t[1] = t[2] = 0.;
97 >                                        /* output side */
98 >        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
99 >        printf("0\n0\n12\n");
100 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
101 >                        vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
102 >                        vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
103 >                        crad*(t[2] + 1.));
104 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
105 >                        vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
106 >                        vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
107 >                        lvect[2] + crad*(t[2] - 1.));
108 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
109 >                        vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
110 >                        vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*u[n1][1]),
111 >                        lvect[2] + crad*(t[2] - 1.));
112 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
113 >                        vert[n1][0] + crad*(t[0] + a[n1]*u[n1][0]),
114 >                        vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
115 >                        crad*(t[2] + 1.));
116 >                                        /* output joining edge */
117 >        if (lvdir*a[n1] < 0.)
118 >                return;
119 >        printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
120 >        printf("0\n0\n7\n");
121 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
122 >                vert[n1][0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
123 >                vert[n1][1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
124 >                crad);
125 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
126 >                vert[n1][0] + lvect[0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
127 >                vert[n1][1] + lvect[1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
128 >                lvect[2] - crad);
129 >        printf("\t%18.12g\n", lvdir*crad);
130   }
131  
132  
133 + double
134   compute_rounding()              /* compute vectors for rounding operations */
135   {
136 <        register int  i;
137 <        register double *v0, *v1;
138 <        double  l;
136 >        int  i;
137 >        double  *v0, *v1;
138 >        double  l, asum;
139  
140          v0 = vert[nverts-1];
141          for (i = 0; i < nverts; i++) {          /* compute u[*] */
# Line 171 | Line 151 | compute_rounding()             /* compute vectors for rounding op
151                  u[i][1] /= l;
152                  v0 = v1;
153          }
154 +        asum = 0.;
155          v1 = u[0];
156          for (i = nverts; i--; ) {               /* compute a[*] */
157                  v0 = u[i];
# Line 183 | Line 164 | compute_rounding()             /* compute vectors for rounding op
164                          a[i] = 0.;
165                  else {
166                          a[i] = sqrt((1-l)/(1+l));
167 <                        if ((v1[0]*v0[1]-v1[1]*v0[0] > 0.) != (lvect[2] > 0.))
167 >                        asum += l = v1[0]*v0[1]-v1[1]*v0[0];
168 >                        if (l < 0.)
169                                  a[i] = -a[i];
170                  }
171                  v1 = v0;
172          }
173 +        return(asum*.5);
174   }
175  
176  
177 + void
178   printends()                     /* print ends of prism */
179   {
180 <        register int  i;
180 >        int  i;
181                                                  /* bottom face */
182          printf("\n%s polygon %s.b\n", pmtype, pname);
183          printf("0\n0\n%d\n", nverts*3);
# Line 209 | Line 193 | printends()                    /* print ends of prism */
193   }
194  
195  
196 < printrends()                    /* print ends of prism with rounding */
196 > void
197 > printrends()            /* print ends of prism with rounding */
198   {
199 <        register int  i;
199 >        int  i;
200          double  c0[3], c1[3], cl[3];
201                                                  /* bottom face */
202          printf("\n%s polygon %s.b\n", pmtype, pname);
# Line 222 | Line 207 | printrends()                   /* print ends of prism with rounding */
207                          vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]),
208                          0.0);
209          }
210 +                                                /* top face */
211 +        printf("\n%s polygon %s.t\n", pmtype, pname);
212 +        printf("0\n0\n%d\n", nverts*3);
213 +        for (i = nverts; i--; ) {
214 +                printf("\t%18.12g\t%18.12g\t%18.12g\n",
215 +                vert[i][0] + lvect[0] + crad*(a[i]*u[i][0] - u[i][1]),
216 +                vert[i][1] + lvect[1] + crad*(a[i]*u[i][1] + u[i][0]),
217 +                lvect[2]);
218 +        }
219                                                  /* bottom corners and edges */
220          c0[0] = cl[0] = vert[nverts-1][0] +
221                          crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
# Line 236 | Line 230 | printrends()                   /* print ends of prism with rounding */
230                  } else {
231                          c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
232                  }
233 <                if (a[i] > 0.) {
233 >                if (lvdir*a[i] > 0.) {
234                          printf("\n%s sphere %s.bc%d\n", pmtype, pname, i+1);
235                          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
236 <                                c1[0], c1[1], c1[2], crad);
236 >                                c1[0], c1[1], c1[2], lvdir*crad);
237                  }
238                  printf("\n%s cylinder %s.be%d\n", pmtype, pname, i+1);
239                  printf("0\n0\n7\n");
240                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
241                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
242 <                printf("\t%18.12g\n", crad);
242 >                printf("\t%18.12g\n", lvdir*crad);
243                  c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
244          }
251                                                /* top face */
252        printf("\n%s polygon %s.t\n", pmtype, pname);
253        printf("0\n0\n%d\n", nverts*3);
254        for (i = nverts; i--; ) {
255                printf("\t%18.12g\t%18.12g\t%18.12g\n",
256                vert[i][0] + lvect[0] + crad*(a[i]*u[i][0] - u[i][1]),
257                vert[i][1] + lvect[1] + crad*(a[i]*u[i][1] + u[i][0]),
258                lvect[2]);
259        }
245                                                  /* top corners and edges */
246          c0[0] = cl[0] = vert[nverts-1][0] + lvect[0] +
247                          crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
# Line 273 | Line 258 | printrends()                   /* print ends of prism with rounding */
258                  } else {
259                          c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
260                  }
261 <                if (a[i] > 0.) {
261 >                if (lvdir*a[i] > 0.) {
262                          printf("\n%s sphere %s.tc%d\n", pmtype, pname, i+1);
263                          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
264 <                                c1[0], c1[1], c1[2], crad);
264 >                                c1[0], c1[1], c1[2], lvdir*crad);
265                  }
266                  printf("\n%s cylinder %s.te%d\n", pmtype, pname, i+1);
267                  printf("0\n0\n7\n");
268                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
269                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
270 <                printf("\t%18.12g\n", crad);
270 >                printf("\t%18.12g\n", lvdir*crad);
271                  c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
272          }
273   }
274  
275  
276 < printsides(round)               /* print prism sides */
277 < int  round;
276 > void
277 > printsides(int round)           /* print prism sides */
278   {
279 <        register int  i;
279 >        int  i;
280  
281          for (i = 0; i < nverts-1; i++)
282                  if (round)
283                          rside(i, i+1);
284                  else
285                          side(i, i+1);
286 <        if (!iscomplete)
286 >        if (!iscomplete) {
287                  if (round)
288                          rside(nverts-1, 0);
289                  else
290                          side(nverts-1, 0);
291 +        }
292   }
293  
294  
295 < side(n0, n1)                    /* print single side */
296 < register int  n0, n1;
295 > int
296 > main(int argc, char **argv)
297   {
298 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
299 <        printf("0\n0\n12\n");
300 <        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
301 <                        vert[n0][1], 0.0);
316 <        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0]+lvect[0],
317 <                        vert[n0][1]+lvect[1], lvect[2]);
318 <        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0]+lvect[0],
319 <                        vert[n1][1]+lvect[1], lvect[2]);
320 <        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0],
321 <                        vert[n1][1], 0.0);
322 < }
298 >        int  an;
299 >        
300 >        if (argc < 4)
301 >                goto userr;
302  
303 +        pmtype = argv[1];
304 +        pname = argv[2];
305  
306 < rside(n0, n1)                   /* print side with rounded edge */
307 < register int  n0, n1;
308 < {
309 <        double  s, c, t[3];
306 >        if (!strcmp(argv[3], "-")) {
307 >                readverts(NULL);
308 >                an = 4;
309 >        } else if (isdigit(argv[3][0])) {
310 >                nverts = atoi(argv[3]);
311 >                if (argc-3 < 2*nverts)
312 >                        goto userr;
313 >                if (nverts > MAXVERT) {
314 >                        fprintf(stderr, "%s: too many vertices\n", argv[0]);
315 >                        return(1);
316 >                }
317 >                for (an = 0; an < nverts; an++) {
318 >                        vert[an][0] = atof(argv[2*an+4]);
319 >                        vert[an][1] = atof(argv[2*an+5]);
320 >                }
321 >                an = 2*nverts+4;
322 >        } else {
323 >                readverts(argv[3]);
324 >                an = 4;
325 >        }
326 >        if (nverts < 3) {
327 >                fprintf(stderr, "%s: not enough vertices\n", argv[0]);
328 >                return(1);
329 >        }
330  
331 <                                        /* compute tanget offset vector */
332 <        s = (lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
333 <        if (s < -FTINY || s > FTINY) {
334 <                c = sqrt(1. - s*s);
335 <                t[0] = (c - 1.)*u[n1][1];
336 <                t[1] = (1. - c)*u[n1][0];
337 <                t[2] = s;
338 <        } else
339 <                t[0] = t[1] = t[2] = 0.;
340 <                                        /* output side */
341 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
342 <        printf("0\n0\n12\n");
343 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
344 <                        vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
345 <                        vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
346 <                        crad*(t[2] + 1.));
347 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
348 <                        vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
349 <                        vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
350 <                        lvect[2] + crad*(t[2] - 1.));
351 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
352 <                        vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
353 <                        vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*u[n1][1]),
354 <                        lvect[2] + crad*(t[2] - 1.));
355 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
356 <                        vert[n1][0] + crad*(t[0] + a[n1]*u[n1][0]),
357 <                        vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
358 <                        crad*(t[2] + 1.));
359 <                                        /* output joining edge */
360 <        if (a[n1] < 0.)
361 <                return;
362 <        printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
363 <        printf("0\n0\n7\n");
363 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
364 <                vert[n1][0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
365 <                vert[n1][1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
366 <                crad);
367 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
368 <                vert[n1][0] + lvect[0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
369 <                vert[n1][1] + lvect[1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
370 <                lvect[2] - crad);
371 <        printf("\t%18.12g\n", crad);
372 < }
373 <
374 <
375 < printhead(ac, av)               /* print command header */
376 < register int  ac;
377 < register char  **av;
378 < {
379 <        putchar('#');
380 <        while (ac--) {
381 <                putchar(' ');
382 <                fputs(*av++, stdout);
331 >        for ( ; an < argc; an++) {
332 >                if (argv[an][0] != '-')
333 >                        goto userr;
334 >                switch (argv[an][1]) {
335 >                case 'l':                               /* length vector */
336 >                        lvect[0] = atof(argv[++an]);
337 >                        lvect[1] = atof(argv[++an]);
338 >                        lvect[2] = atof(argv[++an]);
339 >                        if (lvect[2] < -FTINY)
340 >                                lvdir = -1;
341 >                        else if (lvect[2] > FTINY)
342 >                                lvdir = 1;
343 >                        else {
344 >                                fprintf(stderr,
345 >                                        "%s: illegal extrusion vector\n",
346 >                                                argv[0]);
347 >                                return(1);
348 >                        }
349 >                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
350 >                                        lvect[2]*lvect[2]);
351 >                        break;
352 >                case 'r':                               /* radius */
353 >                        crad = atof(argv[++an]);
354 >                        break;
355 >                case 'e':                               /* ends */
356 >                        do_ends = !do_ends;
357 >                        break;
358 >                case 'c':                               /* complete */
359 >                        iscomplete = !iscomplete;
360 >                        break;
361 >                default:
362 >                        goto userr;
363 >                }
364          }
365 <        putchar('\n');
365 >        if (crad > FTINY) {
366 >                if (crad > lvdir*lvect[2]) {
367 >                        fprintf(stderr, "%s: rounding greater than height\n",
368 >                                        argv[0]);
369 >                        return(1);
370 >                }
371 >                crad *= lvdir;          /* simplifies formulas */
372 >                compute_rounding();
373 >                fputs("# ", stdout);
374 >                printargs(argc, argv, stdout);
375 >                if (do_ends)
376 >                        printrends();
377 >                printsides(1);
378 >        } else {
379 >                fputs("# ", stdout);
380 >                printargs(argc, argv, stdout);
381 >                if (do_ends)
382 >                        printends();
383 >                printsides(0);
384 >        }
385 >        return(0);
386 > userr:
387 >        fprintf(stderr, "Usage: %s material name ", argv[0]);
388 >        fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
389 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
390 >        return(1);
391   }
392 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines