ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.7
Committed: Tue Mar 19 20:59:22 1996 UTC (28 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +47 -37 lines
Log Message:
numerous bug fixes associated with the -r option

File Contents

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