ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.13
Committed: Sat Jul 25 19:18:01 2020 UTC (3 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R3, HEAD
Changes since 2.12: +22 -41 lines
Log Message:
fix(genbox, genprism, gensky): normalizing headers for Windows

File Contents

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