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

# Content
1 /* Copyright (c) 1996 Regents of the University of California */
2
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 #include <math.h>
18
19 #include <ctype.h>
20
21 #define MAXVERT 1024 /* maximum # vertices */
22
23 #define FTINY 1e-6
24
25 #ifdef DCL_ATOF
26 extern double atof();
27 #endif
28
29 char *pmtype; /* material type */
30 char *pname; /* name */
31
32 double lvect[3] = {0.0, 0.0, 1.0};
33 int lvdir = 1;
34 double llen = 1.0;
35
36 double vert[MAXVERT][2];
37 int nverts = 0;
38
39 double u[MAXVERT][2]; /* edge unit vectors */
40 double a[MAXVERT]; /* corner trim sizes */
41
42 int do_ends = 1; /* include end caps */
43 int iscomplete = 0; /* polygon is already completed */
44 double crad = 0.0; /* radius for corners (sign from lvdir) */
45
46 extern double compute_rounding();
47
48
49 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 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 argv[0]);
98 exit(1);
99 }
100 llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
101 lvect[2]*lvect[2]);
102 break;
103 case 'r': /* radius */
104 crad = atof(argv[++an]);
105 break;
106 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 if (crad > FTINY) {
117 if (crad > lvdir*lvect[2]) {
118 fprintf(stderr, "%s: rounding greater than height\n",
119 argv[0]);
120 exit(1);
121 }
122 crad *= lvdir; /* simplifies formulas */
123 compute_rounding();
124 printhead(argc, argv);
125 if (do_ends)
126 printrends();
127 printsides(1);
128 } else {
129 printhead(argc, argv);
130 if (do_ends)
131 printends();
132 printsides(0);
133 }
134 exit(0);
135 userr:
136 fprintf(stderr, "Usage: %s material name ", argv[0]);
137 fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
138 fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
139 exit(1);
140 }
141
142
143 readverts(fname) /* read vertices from a file */
144 char *fname;
145 {
146 FILE *fp;
147
148 if (fname == NULL)
149 fp = stdin;
150 else if ((fp = fopen(fname, "r")) == NULL) {
151 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 nverts++;
156 fclose(fp);
157 }
158
159
160 double
161 compute_rounding() /* compute vectors for rounding operations */
162 {
163 register int i;
164 register double *v0, *v1;
165 double l, asum;
166
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 exit(1);
176 }
177 u[i][0] /= l;
178 u[i][1] /= l;
179 v0 = v1;
180 }
181 asum = 0.;
182 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 asum += l = v1[0]*v0[1]-v1[1]*v0[0];
195 if (l < 0.)
196 a[i] = -a[i];
197 }
198 v1 = v0;
199 }
200 return(asum*.5);
201 }
202
203
204 printends() /* print ends of prism */
205 {
206 register int i;
207 /* 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
221
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 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 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 }
235 /* 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 /* 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 if (lvdir*a[i] > 0.) {
259 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 c1[0], c1[1], c1[2], lvdir*crad);
262 }
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 printf("\t%18.12g\n", lvdir*crad);
268 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 if (lvdir*a[i] > 0.) {
287 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 c1[0], c1[1], c1[2], lvdir*crad);
290 }
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 printf("\t%18.12g\n", lvdir*crad);
296 c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
297 }
298 }
299
300
301 printsides(round) /* print prism sides */
302 int round;
303 {
304 register int i;
305
306 for (i = 0; i < nverts-1; i++)
307 if (round)
308 rside(i, i+1);
309 else
310 side(i, i+1);
311 if (!iscomplete)
312 if (round)
313 rside(nverts-1, 0);
314 else
315 side(nverts-1, 0);
316 }
317
318
319 side(n0, n1) /* print single side */
320 register int n0, n1;
321 {
322 printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
323 printf("0\n0\n12\n");
324 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 s = lvdir*(lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
342 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 printf("\t%18.12g\t%18.12g\t%18.12g\n",
353 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 printf("\t%18.12g\t%18.12g\t%18.12g\n",
357 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 printf("\t%18.12g\t%18.12g\t%18.12g\n",
361 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 printf("\t%18.12g\t%18.12g\t%18.12g\n",
365 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 if (lvdir*a[n1] < 0.)
370 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 printf("\t%18.12g\n", lvdir*crad);
382 }
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 }