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.8 by greg, Sat Feb 22 02:07:23 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  
14 + #include <stdlib.h>
15 +
16   #include  <math.h>
17  
18   #include  <ctype.h>
19  
20   #define  MAXVERT        1024            /* maximum # vertices */
21  
22 + #define  FTINY          1e-6
23 +
24   char  *pmtype;          /* material type */
25   char  *pname;           /* name */
26  
27   double  lvect[3] = {0.0, 0.0, 1.0};
28 + int     lvdir = 1;
29 + double  llen = 1.0;
30  
31   double  vert[MAXVERT][2];
32   int  nverts = 0;
33  
34 + double  u[MAXVERT][2];          /* edge unit vectors */
35 + double  a[MAXVERT];             /* corner trim sizes */
36 +
37   int  do_ends = 1;               /* include end caps */
38   int  iscomplete = 0;            /* polygon is already completed */
39 + double  crad = 0.0;             /* radius for corners (sign from lvdir) */
40  
41 + extern double  compute_rounding();
42  
43 +
44   main(argc, argv)
45   int  argc;
46   char  **argv;
# Line 75 | Line 82 | char  **argv;
82                          lvect[0] = atof(argv[++an]);
83                          lvect[1] = atof(argv[++an]);
84                          lvect[2] = atof(argv[++an]);
85 +                        if (lvect[2] < -FTINY)
86 +                                lvdir = -1;
87 +                        else if (lvect[2] > FTINY)
88 +                                lvdir = 1;
89 +                        else {
90 +                                fprintf(stderr,
91 +                                        "%s: illegal extrusion vector\n",
92 +                                                argv[0]);
93 +                                exit(1);
94 +                        }
95 +                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
96 +                                        lvect[2]*lvect[2]);
97                          break;
98 +                case 'r':                               /* radius */
99 +                        crad = atof(argv[++an]);
100 +                        break;
101                  case 'e':                               /* ends */
102                          do_ends = !do_ends;
103                          break;
# Line 86 | Line 108 | char  **argv;
108                          goto userr;
109                  }
110          }
111 <
112 <        printhead(argc, argv);
113 <
114 <        if (do_ends)
115 <                printends();
116 <        printsides();
117 <
118 <        return(0);
111 >        if (crad > FTINY) {
112 >                if (crad > lvdir*lvect[2]) {
113 >                        fprintf(stderr, "%s: rounding greater than height\n",
114 >                                        argv[0]);
115 >                        exit(1);
116 >                }
117 >                crad *= lvdir;          /* simplifies formulas */
118 >                compute_rounding();
119 >                printhead(argc, argv);
120 >                if (do_ends)
121 >                        printrends();
122 >                printsides(1);
123 >        } else {
124 >                printhead(argc, argv);
125 >                if (do_ends)
126 >                        printends();
127 >                printsides(0);
128 >        }
129 >        exit(0);
130   userr:
131          fprintf(stderr, "Usage: %s material name ", argv[0]);
132          fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
133 <        fprintf(stderr, "[-l lvect][-c][-e]\n");
133 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
134          exit(1);
135   }
136  
# Line 119 | Line 152 | char  *fname;
152   }
153  
154  
155 + double
156 + compute_rounding()              /* compute vectors for rounding operations */
157 + {
158 +        register int  i;
159 +        register double *v0, *v1;
160 +        double  l, asum;
161 +
162 +        v0 = vert[nverts-1];
163 +        for (i = 0; i < nverts; i++) {          /* compute u[*] */
164 +                v1 = vert[i];
165 +                u[i][0] = v0[0] - v1[0];
166 +                u[i][1] = v0[1] - v1[1];
167 +                l = sqrt(u[i][0]*u[i][0] + u[i][1]*u[i][1]);
168 +                if (l <= FTINY) {
169 +                        fprintf(stderr, "Degenerate side in prism\n");
170 +                        exit(1);
171 +                }
172 +                u[i][0] /= l;
173 +                u[i][1] /= l;
174 +                v0 = v1;
175 +        }
176 +        asum = 0.;
177 +        v1 = u[0];
178 +        for (i = nverts; i--; ) {               /* compute a[*] */
179 +                v0 = u[i];
180 +                l = v0[0]*v1[0] + v0[1]*v1[1];
181 +                if (1+l <= FTINY) {
182 +                        fprintf(stderr, "Overlapping sides in prism\n");
183 +                        exit(1);
184 +                }
185 +                if (1-l <= 0.)
186 +                        a[i] = 0.;
187 +                else {
188 +                        a[i] = sqrt((1-l)/(1+l));
189 +                        asum += l = v1[0]*v0[1]-v1[1]*v0[0];
190 +                        if (l < 0.)
191 +                                a[i] = -a[i];
192 +                }
193 +                v1 = v0;
194 +        }
195 +        return(asum*.5);
196 + }
197 +
198 +
199   printends()                     /* print ends of prism */
200   {
201          register int  i;
202 +                                                /* bottom face */
203 +        printf("\n%s polygon %s.b\n", pmtype, pname);
204 +        printf("0\n0\n%d\n", nverts*3);
205 +        for (i = 0; i < nverts; i++)
206 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0],
207 +                                vert[i][1], 0.0);
208 +                                                /* top face */
209 +        printf("\n%s polygon %s.t\n", pmtype, pname);
210 +        printf("0\n0\n%d\n", nverts*3);
211 +        for (i = nverts; i--; )
212 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0]+lvect[0],
213 +                                vert[i][1]+lvect[1], lvect[2]);
214 + }
215  
216 +
217 + printrends()                    /* print ends of prism with rounding */
218 + {
219 +        register int  i;
220 +        double  c0[3], c1[3], cl[3];
221 +                                                /* bottom face */
222          printf("\n%s polygon %s.b\n", pmtype, pname);
223          printf("0\n0\n%d\n", nverts*3);
224          for (i = 0; i < nverts; i++) {
225                  printf("\t%18.12g\t%18.12g\t%18.12g\n",
226 <                                vert[i][0],
227 <                                vert[i][1],
228 <                                0.0);
226 >                        vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]),
227 >                        vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]),
228 >                        0.0);
229          }
230 <        printf("\n%s polygon %s.e\n", pmtype, pname);
230 >                                                /* top face */
231 >        printf("\n%s polygon %s.t\n", pmtype, pname);
232          printf("0\n0\n%d\n", nverts*3);
233 <        for (i = nverts-1; i >= 0; i--) {
233 >        for (i = nverts; i--; ) {
234                  printf("\t%18.12g\t%18.12g\t%18.12g\n",
235 <                                vert[i][0]+lvect[0],
236 <                                vert[i][1]+lvect[1],
237 <                                lvect[2]);
235 >                vert[i][0] + lvect[0] + crad*(a[i]*u[i][0] - u[i][1]),
236 >                vert[i][1] + lvect[1] + crad*(a[i]*u[i][1] + u[i][0]),
237 >                lvect[2]);
238          }
239 +                                                /* bottom corners and edges */
240 +        c0[0] = cl[0] = vert[nverts-1][0] +
241 +                        crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
242 +        c0[1] = cl[1] = vert[nverts-1][1] +
243 +                        crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
244 +        c0[2] = cl[2] = crad;
245 +        for (i = 0; i < nverts; i++) {
246 +                if (i < nverts-1) {
247 +                        c1[0] = vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]);
248 +                        c1[1] = vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]);
249 +                        c1[2] = crad;
250 +                } else {
251 +                        c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
252 +                }
253 +                if (lvdir*a[i] > 0.) {
254 +                        printf("\n%s sphere %s.bc%d\n", pmtype, pname, i+1);
255 +                        printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
256 +                                c1[0], c1[1], c1[2], lvdir*crad);
257 +                }
258 +                printf("\n%s cylinder %s.be%d\n", pmtype, pname, i+1);
259 +                printf("0\n0\n7\n");
260 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
261 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
262 +                printf("\t%18.12g\n", lvdir*crad);
263 +                c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
264 +        }
265 +                                                /* top corners and edges */
266 +        c0[0] = cl[0] = vert[nverts-1][0] + lvect[0] +
267 +                        crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
268 +        c0[1] = cl[1] = vert[nverts-1][1] + lvect[1] +
269 +                        crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
270 +        c0[2] = cl[2] = lvect[2] - crad;
271 +        for (i = 0; i < nverts; i++) {
272 +                if (i < nverts-1) {
273 +                        c1[0] = vert[i][0] + lvect[0] +
274 +                                        crad*(a[i]*u[i][0] - u[i][1]);
275 +                        c1[1] = vert[i][1] + lvect[1] +
276 +                                        crad*(a[i]*u[i][1] + u[i][0]);
277 +                        c1[2] = lvect[2] - crad;
278 +                } else {
279 +                        c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
280 +                }
281 +                if (lvdir*a[i] > 0.) {
282 +                        printf("\n%s sphere %s.tc%d\n", pmtype, pname, i+1);
283 +                        printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
284 +                                c1[0], c1[1], c1[2], lvdir*crad);
285 +                }
286 +                printf("\n%s cylinder %s.te%d\n", pmtype, pname, i+1);
287 +                printf("0\n0\n7\n");
288 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
289 +                printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
290 +                printf("\t%18.12g\n", lvdir*crad);
291 +                c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
292 +        }
293   }
294  
295  
296 < printsides()                    /* print prism sides */
296 > printsides(round)               /* print prism sides */
297 > int  round;
298   {
299          register int  i;
300  
301          for (i = 0; i < nverts-1; i++)
302 <                side(i, i+1);
302 >                if (round)
303 >                        rside(i, i+1);
304 >                else
305 >                        side(i, i+1);
306          if (!iscomplete)
307 <                side(nverts-1, 0);
307 >                if (round)
308 >                        rside(nverts-1, 0);
309 >                else
310 >                        side(nverts-1, 0);
311   }
312  
313  
314 < side(n1, n2)                    /* print single side */
315 < register int  n1, n2;
314 > side(n0, n1)                    /* print single side */
315 > register int  n0, n1;
316   {
317 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n1+1);
317 >        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
318          printf("0\n0\n12\n");
319 +        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
320 +                        vert[n0][1], 0.0);
321 +        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0]+lvect[0],
322 +                        vert[n0][1]+lvect[1], lvect[2]);
323 +        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0]+lvect[0],
324 +                        vert[n1][1]+lvect[1], lvect[2]);
325 +        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0],
326 +                        vert[n1][1], 0.0);
327 + }
328 +
329 +
330 + rside(n0, n1)                   /* print side with rounded edge */
331 + register int  n0, n1;
332 + {
333 +        double  s, c, t[3];
334 +
335 +                                        /* compute tanget offset vector */
336 +        s = lvdir*(lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
337 +        if (s < -FTINY || s > FTINY) {
338 +                c = sqrt(1. - s*s);
339 +                t[0] = (c - 1.)*u[n1][1];
340 +                t[1] = (1. - c)*u[n1][0];
341 +                t[2] = s;
342 +        } else
343 +                t[0] = t[1] = t[2] = 0.;
344 +                                        /* output side */
345 +        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
346 +        printf("0\n0\n12\n");
347          printf("\t%18.12g\t%18.12g\t%18.12g\n",
348 <                        vert[n1][0],
349 <                        vert[n1][1],
350 <                        0.0);
348 >                        vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
349 >                        vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
350 >                        crad*(t[2] + 1.));
351          printf("\t%18.12g\t%18.12g\t%18.12g\n",
352 <                        vert[n1][0]+lvect[0],
353 <                        vert[n1][1]+lvect[1],
354 <                        lvect[2]);
352 >                        vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
353 >                        vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
354 >                        lvect[2] + crad*(t[2] - 1.));
355          printf("\t%18.12g\t%18.12g\t%18.12g\n",
356 <                        vert[n2][0]+lvect[0],
357 <                        vert[n2][1]+lvect[1],
358 <                        lvect[2]);
356 >                        vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
357 >                        vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*u[n1][1]),
358 >                        lvect[2] + crad*(t[2] - 1.));
359          printf("\t%18.12g\t%18.12g\t%18.12g\n",
360 <                        vert[n2][0],
361 <                        vert[n2][1],
362 <                        0.0);
360 >                        vert[n1][0] + crad*(t[0] + a[n1]*u[n1][0]),
361 >                        vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
362 >                        crad*(t[2] + 1.));
363 >                                        /* output joining edge */
364 >        if (lvdir*a[n1] < 0.)
365 >                return;
366 >        printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
367 >        printf("0\n0\n7\n");
368 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
369 >                vert[n1][0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
370 >                vert[n1][1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
371 >                crad);
372 >        printf("\t%18.12g\t%18.12g\t%18.12g\n",
373 >                vert[n1][0] + lvect[0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
374 >                vert[n1][1] + lvect[1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
375 >                lvect[2] - crad);
376 >        printf("\t%18.12g\n", lvdir*crad);
377   }
378  
379  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines