ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.6
Committed: Tue Mar 19 16:30:56 1996 UTC (28 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +227 -44 lines
Log Message:
added -r option for smoothed edges

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