ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.8
Committed: Sat Feb 22 02:07:23 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.7: +3 -8 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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