ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
(Generate patch)

Comparing ray/src/gen/genprism.c (file contents):
Revision 2.3 by greg, Fri Jun 4 14:32:05 1993 UTC vs.
Revision 2.9 by schorsch, Sun Jun 8 12:03:09 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1987 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
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.
13 *
14 *     8/24/87
10   */
11  
12   #include  <stdio.h>
13 <
13 > #include  <string.h>
14 > #include <stdlib.h>
15   #include  <math.h>
20
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 + extern double  compute_rounding();
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 + static void
291 + printhead(ac, av)               /* print command header */
292 + register int  ac;
293 + register char  **av;
294 + {
295 +        putchar('#');
296 +        while (ac--) {
297 +                putchar(' ');
298 +                fputs(*av++, stdout);
299 +        }
300 +        putchar('\n');
301 + }
302 +
303 +
304   main(argc, argv)
305   int  argc;
306   char  **argv;
# Line 75 | Line 342 | char  **argv;
342                          lvect[0] = atof(argv[++an]);
343                          lvect[1] = atof(argv[++an]);
344                          lvect[2] = atof(argv[++an]);
345 +                        if (lvect[2] < -FTINY)
346 +                                lvdir = -1;
347 +                        else if (lvect[2] > FTINY)
348 +                                lvdir = 1;
349 +                        else {
350 +                                fprintf(stderr,
351 +                                        "%s: illegal extrusion vector\n",
352 +                                                argv[0]);
353 +                                exit(1);
354 +                        }
355 +                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
356 +                                        lvect[2]*lvect[2]);
357                          break;
358 +                case 'r':                               /* radius */
359 +                        crad = atof(argv[++an]);
360 +                        break;
361                  case 'e':                               /* ends */
362                          do_ends = !do_ends;
363                          break;
# Line 86 | Line 368 | char  **argv;
368                          goto userr;
369                  }
370          }
371 <
372 <        printhead(argc, argv);
373 <
374 <        if (do_ends)
375 <                printends();
376 <        printsides();
377 <
378 <        return(0);
371 >        if (crad > FTINY) {
372 >                if (crad > lvdir*lvect[2]) {
373 >                        fprintf(stderr, "%s: rounding greater than height\n",
374 >                                        argv[0]);
375 >                        exit(1);
376 >                }
377 >                crad *= lvdir;          /* simplifies formulas */
378 >                compute_rounding();
379 >                printhead(argc, argv);
380 >                if (do_ends)
381 >                        printrends();
382 >                printsides(1);
383 >        } else {
384 >                printhead(argc, argv);
385 >                if (do_ends)
386 >                        printends();
387 >                printsides(0);
388 >        }
389 >        exit(0);
390   userr:
391          fprintf(stderr, "Usage: %s material name ", argv[0]);
392          fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
393 <        fprintf(stderr, "[-l lvect][-c][-e]\n");
393 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
394          exit(1);
395   }
396  
104
105 readverts(fname)                /* read vertices from a file */
106 char  *fname;
107 {
108        FILE  *fp;
109
110        if (fname == NULL)
111                fp = stdin;
112        else if ((fp = fopen(fname, "r")) == NULL) {
113                fprintf(stderr, "%s: cannot open\n", fname);
114                exit(1);
115        }
116        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
117                nverts++;
118        fclose(fp);
119 }
120
121
122 printends()                     /* print ends of prism */
123 {
124        register int  i;
125
126        printf("\n%s polygon %s.b\n", pmtype, pname);
127        printf("0\n0\n%d\n", nverts*3);
128        for (i = 0; i < nverts; i++) {
129                printf("\t%18.12g\t%18.12g\t%18.12g\n",
130                                vert[i][0],
131                                vert[i][1],
132                                0.0);
133        }
134        printf("\n%s polygon %s.e\n", pmtype, pname);
135        printf("0\n0\n%d\n", nverts*3);
136        for (i = nverts-1; i >= 0; i--) {
137                printf("\t%18.12g\t%18.12g\t%18.12g\n",
138                                vert[i][0]+lvect[0],
139                                vert[i][1]+lvect[1],
140                                lvect[2]);
141        }
142 }
143
144
145 printsides()                    /* print prism sides */
146 {
147        register int  i;
148
149        for (i = 0; i < nverts-1; i++)
150                side(i, i+1);
151        if (!iscomplete)
152                side(nverts-1, 0);
153 }
154
155
156 side(n1, n2)                    /* print single side */
157 register int  n1, n2;
158 {
159        printf("\n%s polygon %s.%d\n", pmtype, pname, n1+1);
160        printf("0\n0\n12\n");
161        printf("\t%18.12g\t%18.12g\t%18.12g\n",
162                        vert[n1][0],
163                        vert[n1][1],
164                        0.0);
165        printf("\t%18.12g\t%18.12g\t%18.12g\n",
166                        vert[n1][0]+lvect[0],
167                        vert[n1][1]+lvect[1],
168                        lvect[2]);
169        printf("\t%18.12g\t%18.12g\t%18.12g\n",
170                        vert[n2][0]+lvect[0],
171                        vert[n2][1]+lvect[1],
172                        lvect[2]);
173        printf("\t%18.12g\t%18.12g\t%18.12g\n",
174                        vert[n2][0],
175                        vert[n2][1],
176                        0.0);
177 }
178
179
180 printhead(ac, av)               /* print command header */
181 register int  ac;
182 register char  **av;
183 {
184        putchar('#');
185        while (ac--) {
186                putchar(' ');
187                fputs(*av++, stdout);
188        }
189        putchar('\n');
190 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines