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.7 by greg, Tue Mar 19 20:59:22 1996 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1987 Regents of the University of California */
1 > /* Copyright (c) 1996 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 10 | Line 10 | static char SCCSid[] = "$SunId$ LBL";
10   *              command line or from a file.  Their order together
11   *              with the extrude direction will determine surface
12   *              orientation.
13 *
14 *     8/24/87
13   */
14  
15   #include  <stdio.h>
# Line 22 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
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;
# Line 75 | Line 87 | char  **argv;
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;
# Line 86 | Line 113 | char  **argv;
113                          goto userr;
114                  }
115          }
116 <
117 <        printhead(argc, argv);
118 <
119 <        if (do_ends)
120 <                printends();
121 <        printsides();
122 <
123 <        return(0);
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][-c][-e]\n");
138 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
139          exit(1);
140   }
141  
# Line 119 | Line 157 | char  *fname;
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],
232 <                                vert[i][1],
233 <                                0.0);
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 <        printf("\n%s polygon %s.e\n", pmtype, pname);
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-1; i >= 0; i--) {
238 >        for (i = nverts; i--; ) {
239                  printf("\t%18.12g\t%18.12g\t%18.12g\n",
240 <                                vert[i][0]+lvect[0],
241 <                                vert[i][1]+lvect[1],
242 <                                lvect[2]);
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()                    /* print prism sides */
301 > printsides(round)               /* print prism sides */
302 > int  round;
303   {
304          register int  i;
305  
306          for (i = 0; i < nverts-1; i++)
307 <                side(i, i+1);
307 >                if (round)
308 >                        rside(i, i+1);
309 >                else
310 >                        side(i, i+1);
311          if (!iscomplete)
312 <                side(nverts-1, 0);
312 >                if (round)
313 >                        rside(nverts-1, 0);
314 >                else
315 >                        side(nverts-1, 0);
316   }
317  
318  
319 < side(n1, n2)                    /* print single side */
320 < register int  n1, n2;
319 > side(n0, n1)                    /* print single side */
320 > register int  n0, n1;
321   {
322 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n1+1);
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[n1][0],
354 <                        vert[n1][1],
355 <                        0.0);
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[n1][0]+lvect[0],
358 <                        vert[n1][1]+lvect[1],
359 <                        lvect[2]);
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[n2][0]+lvect[0],
362 <                        vert[n2][1]+lvect[1],
363 <                        lvect[2]);
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[n2][0],
366 <                        vert[n2][1],
367 <                        0.0);
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  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines