ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.12
Committed: Sun Nov 16 10:29:38 2003 UTC (20 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.11: +2 -1 lines
Log Message:
Continued ANSIfication and reduced other compile warnings.

File Contents

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