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.2 by greg, Thu Dec 19 15:08:51 1991 UTC vs.
Revision 2.15 by greg, Thu Aug 14 19:32:00 2025 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1987 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
7   *              command line or from a file.  Their order together
8   *              with the extrude direction will determine surface
9   *              orientation.
13 *
14 *     8/24/87
10   */
11  
12 < #include  <stdio.h>
13 <
12 > #include  "rtio.h"
13 > #include  "paths.h"
14 > #include  <math.h>
15   #include  <ctype.h>
16  
17   #define  MAXVERT        1024            /* maximum # vertices */
18  
19 < #ifndef atof
24 < extern double  atof();
25 < #endif
19 > #define  FTINY          1e-6
20  
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];
29   int  nverts = 0;
30  
31 + double  u[MAXVERT][2];          /* edge unit vectors */
32 + 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 (sign from lvdir) */
37  
38  
39 < main(argc, argv)
40 < int  argc;
41 < char  **argv;
39 > void
40 > readverts(char *fname)          /* read vertices from a file */
41   {
42 +        FILE  *fp;
43 +
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 +        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
52 +                if (++nverts >= MAXVERT)
53 +                        break;
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 +                }
62 +        }
63 +        fclose(fp);
64 + }
65 +
66 +
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 + void
84 + rside(int n0, int n1)                   /* print side with rounded edge */
85 + {
86 +        double  s, c, t[3];
87 +
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 +        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[*] */
142 +                v1 = vert[i];
143 +                u[i][0] = v0[0] - v1[0];
144 +                u[i][1] = v0[1] - v1[1];
145 +                l = sqrt(u[i][0]*u[i][0] + u[i][1]*u[i][1]);
146 +                if (l <= FTINY) {
147 +                        fprintf(stderr, "Degenerate side in prism\n");
148 +                        exit(1);
149 +                }
150 +                u[i][0] /= l;
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];
158 +                l = v0[0]*v1[0] + v0[1]*v1[1];
159 +                if (1+l <= FTINY) {
160 +                        fprintf(stderr, "Overlapping sides in prism\n");
161 +                        exit(1);
162 +                }
163 +                if (1-l <= 0.)
164 +                        a[i] = 0.;
165 +                else {
166 +                        a[i] = sqrt((1-l)/(1+l));
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 +        int  i;
181 +                                                /* bottom face */
182 +        printf("\n%s polygon %s.b\n", pmtype, pname);
183 +        printf("0\n0\n%d\n", nverts*3);
184 +        for (i = 0; i < nverts; i++)
185 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0],
186 +                                vert[i][1], 0.0);
187 +                                                /* top face */
188 +        printf("\n%s polygon %s.t\n", pmtype, pname);
189 +        printf("0\n0\n%d\n", nverts*3);
190 +        for (i = nverts; i--; )
191 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0]+lvect[0],
192 +                                vert[i][1]+lvect[1], lvect[2]);
193 + }
194 +
195 +
196 + void
197 + printrends()            /* print ends of prism with rounding */
198 + {
199 +        int  i;
200 +        double  c0[3], c1[3], cl[3];
201 +                                                /* bottom face */
202 +        printf("\n%s polygon %s.b\n", pmtype, pname);
203 +        printf("0\n0\n%d\n", nverts*3);
204 +        for (i = 0; i < nverts; i++) {
205 +                printf("\t%18.12g\t%18.12g\t%18.12g\n",
206 +                        vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]),
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]);
222 +        c0[1] = cl[1] = vert[nverts-1][1] +
223 +                        crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
224 +        c0[2] = cl[2] = crad;
225 +        for (i = 0; i < nverts; i++) {
226 +                if (i < nverts-1) {
227 +                        c1[0] = vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]);
228 +                        c1[1] = vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]);
229 +                        c1[2] = crad;
230 +                } else {
231 +                        c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
232 +                }
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], 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", lvdir*crad);
243 +                c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
244 +        }
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]);
248 +        c0[1] = cl[1] = vert[nverts-1][1] + lvect[1] +
249 +                        crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
250 +        c0[2] = cl[2] = lvect[2] - crad;
251 +        for (i = 0; i < nverts; i++) {
252 +                if (i < nverts-1) {
253 +                        c1[0] = vert[i][0] + lvect[0] +
254 +                                        crad*(a[i]*u[i][0] - u[i][1]);
255 +                        c1[1] = vert[i][1] + lvect[1] +
256 +                                        crad*(a[i]*u[i][1] + u[i][0]);
257 +                        c1[2] = lvect[2] - crad;
258 +                } else {
259 +                        c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
260 +                }
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], 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", lvdir*crad);
271 +                c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
272 +        }
273 + }
274 +
275 +
276 + void
277 + printsides(int round)           /* print prism sides */
278 + {
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) {
287 +                if (round)
288 +                        rside(nverts-1, 0);
289 +                else
290 +                        side(nverts-1, 0);
291 +        }
292 + }
293 +
294 +
295 + int
296 + main(int argc, char **argv)
297 + {
298          int  an;
299          
300          if (argc < 4)
# Line 55 | Line 310 | char  **argv;
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]);
# Line 66 | Line 325 | char  **argv;
325          }
326          if (nverts < 3) {
327                  fprintf(stderr, "%s: not enough vertices\n", argv[0]);
328 <                exit(1);
328 >                return(1);
329          }
330  
331          for ( ; an < argc; an++) {
# Line 77 | Line 336 | char  **argv;
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;
# Line 88 | Line 362 | char  **argv;
362                          goto userr;
363                  }
364          }
365 <
366 <        printhead(argc, argv);
367 <
368 <        if (do_ends)
369 <                printends();
370 <        printsides();
371 <
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][-c][-e]\n");
390 <        exit(1);
389 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
390 >        return(1);
391   }
392  
106
107 readverts(fname)                /* read vertices from a file */
108 char  *fname;
109 {
110        FILE  *fp;
111
112        if (fname == NULL)
113                fp = stdin;
114        else if ((fp = fopen(fname, "r")) == NULL) {
115                fprintf(stderr, "%s: cannot open\n", fname);
116                exit(1);
117        }
118        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
119                nverts++;
120        fclose(fp);
121 }
122
123
124 printends()                     /* print ends of prism */
125 {
126        register int  i;
127
128        printf("\n%s polygon %s.b\n", pmtype, pname);
129        printf("0\n0\n%d\n", nverts*3);
130        for (i = 0; i < nverts; i++) {
131                printf("\t%18.12g\t%18.12g\t%18.12g\n",
132                                vert[i][0],
133                                vert[i][1],
134                                0.0);
135        }
136        printf("\n%s polygon %s.e\n", pmtype, pname);
137        printf("0\n0\n%d\n", nverts*3);
138        for (i = nverts-1; i >= 0; i--) {
139                printf("\t%18.12g\t%18.12g\t%18.12g\n",
140                                vert[i][0]+lvect[0],
141                                vert[i][1]+lvect[1],
142                                lvect[2]);
143        }
144 }
145
146
147 printsides()                    /* print prism sides */
148 {
149        register int  i;
150
151        for (i = 0; i < nverts-1; i++)
152                side(i, i+1);
153        if (!iscomplete)
154                side(nverts-1, 0);
155 }
156
157
158 side(n1, n2)                    /* print single side */
159 register int  n1, n2;
160 {
161        printf("\n%s polygon %s.%d\n", pmtype, pname, n1+1);
162        printf("0\n0\n12\n");
163        printf("\t%18.12g\t%18.12g\t%18.12g\n",
164                        vert[n1][0],
165                        vert[n1][1],
166                        0.0);
167        printf("\t%18.12g\t%18.12g\t%18.12g\n",
168                        vert[n1][0]+lvect[0],
169                        vert[n1][1]+lvect[1],
170                        lvect[2]);
171        printf("\t%18.12g\t%18.12g\t%18.12g\n",
172                        vert[n2][0]+lvect[0],
173                        vert[n2][1]+lvect[1],
174                        lvect[2]);
175        printf("\t%18.12g\t%18.12g\t%18.12g\n",
176                        vert[n2][0],
177                        vert[n2][1],
178                        0.0);
179 }
180
181
182 printhead(ac, av)               /* print command header */
183 register int  ac;
184 register char  **av;
185 {
186        putchar('#');
187        while (ac--) {
188                putchar(' ');
189                fputs(*av++, stdout);
190        }
191        putchar('\n');
192 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines