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.5 by greg, Thu Feb 22 14:38:51 1996 UTC vs.
Revision 2.11 by schorsch, Mon Jul 21 22:30:18 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
# Line 13 | Line 10 | static char SCCSid[] = "$SunId$ LBL";
10   */
11  
12   #include  <stdio.h>
13 <
13 > #include  <string.h>
14 > #include <stdlib.h>
15   #include  <math.h>
18
16   #include  <ctype.h>
17  
18   #define  MAXVERT        1024            /* maximum # vertices */
19  
20 < #ifdef  DCL_ATOF
24 < extern double  atof();
25 < #endif
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   main(argc, argv)
306   int  argc;
307   char  **argv;
# Line 53 | Line 319 | char  **argv;
319                  an = 4;
320          } else if (isdigit(argv[3][0])) {
321                  nverts = atoi(argv[3]);
56                if (nverts > MAXVERT) {
57                        fprintf(stderr, "%s: too many vertices (%d limit)\n",
58                                        argv[0], MAXVERT);
59                        exit(1);
60                }
322                  if (argc-3 < 2*nverts)
323                          goto userr;
324                  for (an = 0; an < nverts; an++) {
# Line 82 | Line 343 | char  **argv;
343                          lvect[0] = atof(argv[++an]);
344                          lvect[1] = atof(argv[++an]);
345                          lvect[2] = atof(argv[++an]);
346 +                        if (lvect[2] < -FTINY)
347 +                                lvdir = -1;
348 +                        else if (lvect[2] > FTINY)
349 +                                lvdir = 1;
350 +                        else {
351 +                                fprintf(stderr,
352 +                                        "%s: illegal extrusion vector\n",
353 +                                                argv[0]);
354 +                                exit(1);
355 +                        }
356 +                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
357 +                                        lvect[2]*lvect[2]);
358                          break;
359 +                case 'r':                               /* radius */
360 +                        crad = atof(argv[++an]);
361 +                        break;
362                  case 'e':                               /* ends */
363                          do_ends = !do_ends;
364                          break;
# Line 93 | Line 369 | char  **argv;
369                          goto userr;
370                  }
371          }
372 <
373 <        printhead(argc, argv);
374 <
375 <        if (do_ends)
376 <                printends();
377 <        printsides();
378 <
379 <        return(0);
372 >        if (crad > FTINY) {
373 >                if (crad > lvdir*lvect[2]) {
374 >                        fprintf(stderr, "%s: rounding greater than height\n",
375 >                                        argv[0]);
376 >                        exit(1);
377 >                }
378 >                crad *= lvdir;          /* simplifies formulas */
379 >                compute_rounding();
380 >                printhead(argc, argv);
381 >                if (do_ends)
382 >                        printrends();
383 >                printsides(1);
384 >        } else {
385 >                printhead(argc, argv);
386 >                if (do_ends)
387 >                        printends();
388 >                printsides(0);
389 >        }
390 >        exit(0);
391   userr:
392          fprintf(stderr, "Usage: %s material name ", argv[0]);
393          fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
394 <        fprintf(stderr, "[-l lvect][-c][-e]\n");
394 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
395          exit(1);
396   }
397  
111
112 readverts(fname)                /* read vertices from a file */
113 char  *fname;
114 {
115        FILE  *fp;
116
117        if (fname == NULL) {
118                fp = stdin;
119                fname = "<stdin>";
120        } else if ((fp = fopen(fname, "r")) == NULL) {
121                fprintf(stderr, "%s: cannot open\n", fname);
122                exit(1);
123        }
124        while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
125                if (++nverts >= MAXVERT) {
126                        fprintf(stderr, "%s: too many vertices (%d limit)\n",
127                                        fname, MAXVERT-1);
128                        exit(1);
129                }
130        fclose(fp);
131 }
132
133
134 printends()                     /* print ends of prism */
135 {
136        register int  i;
137
138        printf("\n%s polygon %s.b\n", pmtype, pname);
139        printf("0\n0\n%d\n", nverts*3);
140        for (i = 0; i < nverts; i++) {
141                printf("\t%18.12g\t%18.12g\t%18.12g\n",
142                                vert[i][0],
143                                vert[i][1],
144                                0.0);
145        }
146        printf("\n%s polygon %s.e\n", pmtype, pname);
147        printf("0\n0\n%d\n", nverts*3);
148        for (i = nverts-1; i >= 0; i--) {
149                printf("\t%18.12g\t%18.12g\t%18.12g\n",
150                                vert[i][0]+lvect[0],
151                                vert[i][1]+lvect[1],
152                                lvect[2]);
153        }
154 }
155
156
157 printsides()                    /* print prism sides */
158 {
159        register int  i;
160
161        for (i = 0; i < nverts-1; i++)
162                side(i, i+1);
163        if (!iscomplete)
164                side(nverts-1, 0);
165 }
166
167
168 side(n1, n2)                    /* print single side */
169 register int  n1, n2;
170 {
171        printf("\n%s polygon %s.%d\n", pmtype, pname, n1+1);
172        printf("0\n0\n12\n");
173        printf("\t%18.12g\t%18.12g\t%18.12g\n",
174                        vert[n1][0],
175                        vert[n1][1],
176                        0.0);
177        printf("\t%18.12g\t%18.12g\t%18.12g\n",
178                        vert[n1][0]+lvect[0],
179                        vert[n1][1]+lvect[1],
180                        lvect[2]);
181        printf("\t%18.12g\t%18.12g\t%18.12g\n",
182                        vert[n2][0]+lvect[0],
183                        vert[n2][1]+lvect[1],
184                        lvect[2]);
185        printf("\t%18.12g\t%18.12g\t%18.12g\n",
186                        vert[n2][0],
187                        vert[n2][1],
188                        0.0);
189 }
190
191
192 printhead(ac, av)               /* print command header */
193 register int  ac;
194 register char  **av;
195 {
196        putchar('#');
197        while (ac--) {
198                putchar(' ');
199                fputs(*av++, stdout);
200        }
201        putchar('\n');
202 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines