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.6 by greg, Tue Mar 19 16:30:56 1996 UTC vs.
Revision 2.13 by greg, Sat Jul 25 19:18:01 2020 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1996 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 12 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9   *              orientation.
10   */
11  
12 < #include  <stdio.h>
13 <
12 > #include  "rtio.h"
13 > #include  <stdlib.h>
14   #include  <math.h>
18
15   #include  <ctype.h>
16  
17   #define  MAXVERT        1024            /* maximum # vertices */
18  
19   #define  FTINY          1e-6
20  
25 #ifdef  DCL_ATOF
26 extern double  atof();
27 #endif
28
21   char  *pmtype;          /* material type */
22   char  *pname;           /* name */
23  
24   double  lvect[3] = {0.0, 0.0, 1.0};
25 + int     lvdir = 1;
26   double  llen = 1.0;
27  
28   double  vert[MAXVERT][2];
# Line 40 | Line 33 | double a[MAXVERT];             /* corner trim sizes */
33  
34   int  do_ends = 1;               /* include end caps */
35   int  iscomplete = 0;            /* polygon is already completed */
36 < double  crad = 0.0;             /* radius for corners */
36 > double  crad = 0.0;             /* radius for corners (sign from lvdir) */
37  
38 < #define rounding        (crad > FTINY)
38 > static double  compute_rounding(void);
39  
40  
41 < main(argc, argv)
42 < int  argc;
50 < char  **argv;
41 > static void
42 > readverts(char *fname)          /* read vertices from a file */
43   {
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 {
44          FILE  *fp;
45  
46          if (fname == NULL)
# Line 151 | Line 55 | char  *fname;
55   }
56  
57  
58 < compute_rounding()              /* compute vectors for rounding operations */
58 > static void
59 > side(int n0, int n1)                    /* print single side */
60   {
61 <        register int  i;
62 <        register double *v0, *v1;
63 <        double  l;
61 >        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
62 >        printf("0\n0\n12\n");
63 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
64 >                        vert[n0][1], 0.0);
65 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0]+lvect[0],
66 >                        vert[n0][1]+lvect[1], lvect[2]);
67 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0]+lvect[0],
68 >                        vert[n1][1]+lvect[1], lvect[2]);
69 >        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0],
70 >                        vert[n1][1], 0.0);
71 > }
72  
73 +
74 + static void
75 + rside(int n0, int n1)                   /* print side with rounded edge */
76 + {
77 +        double  s, c, t[3];
78 +
79 +                                        /* compute tanget offset vector */
80 +        s = lvdir*(lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
81 +        if (s < -FTINY || s > FTINY) {
82 +                c = sqrt(1. - s*s);
83 +                t[0] = (c - 1.)*u[n1][1];
84 +                t[1] = (1. - c)*u[n1][0];
85 +                t[2] = s;
86 +        } else
87 +                t[0] = t[1] = t[2] = 0.;
88 +                                        /* output side */
89 +        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
90 +        printf("0\n0\n12\n");
91 +        printf("\t%18.12g\t%18.12g\t%18.12g\n",
92 +                        vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
93 +                        vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
94 +                        crad*(t[2] + 1.));
95 +        printf("\t%18.12g\t%18.12g\t%18.12g\n",
96 +                        vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
97 +                        vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
98 +                        lvect[2] + crad*(t[2] - 1.));
99 +        printf("\t%18.12g\t%18.12g\t%18.12g\n",
100 +                        vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
101 +                        vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*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] + crad*(t[0] + a[n1]*u[n1][0]),
105 +                        vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
106 +                        crad*(t[2] + 1.));
107 +                                        /* output joining edge */
108 +        if (lvdir*a[n1] < 0.)
109 +                return;
110 +        printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
111 +        printf("0\n0\n7\n");
112 +        printf("\t%18.12g\t%18.12g\t%18.12g\n",
113 +                vert[n1][0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
114 +                vert[n1][1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
115 +                crad);
116 +        printf("\t%18.12g\t%18.12g\t%18.12g\n",
117 +                vert[n1][0] + lvect[0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
118 +                vert[n1][1] + lvect[1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
119 +                lvect[2] - crad);
120 +        printf("\t%18.12g\n", lvdir*crad);
121 + }
122 +
123 +
124 + static double
125 + compute_rounding(void)          /* compute vectors for rounding operations */
126 + {
127 +        int  i;
128 +        double  *v0, *v1;
129 +        double  l, asum;
130 +
131          v0 = vert[nverts-1];
132          for (i = 0; i < nverts; i++) {          /* compute u[*] */
133                  v1 = vert[i];
# Line 171 | Line 142 | compute_rounding()             /* compute vectors for rounding op
142                  u[i][1] /= l;
143                  v0 = v1;
144          }
145 +        asum = 0.;
146          v1 = u[0];
147          for (i = nverts; i--; ) {               /* compute a[*] */
148                  v0 = u[i];
# Line 183 | Line 155 | compute_rounding()             /* compute vectors for rounding op
155                          a[i] = 0.;
156                  else {
157                          a[i] = sqrt((1-l)/(1+l));
158 <                        if ((v1[0]*v0[1]-v1[1]*v0[0] > 0.) != (lvect[2] > 0.))
158 >                        asum += l = v1[0]*v0[1]-v1[1]*v0[0];
159 >                        if (l < 0.)
160                                  a[i] = -a[i];
161                  }
162                  v1 = v0;
163          }
164 +        return(asum*.5);
165   }
166  
167  
168 < printends()                     /* print ends of prism */
168 > static void
169 > printends(void)                 /* print ends of prism */
170   {
171 <        register int  i;
171 >        int  i;
172                                                  /* bottom face */
173          printf("\n%s polygon %s.b\n", pmtype, pname);
174          printf("0\n0\n%d\n", nverts*3);
# Line 209 | Line 184 | printends()                    /* print ends of prism */
184   }
185  
186  
187 < printrends()                    /* print ends of prism with rounding */
187 > static void
188 > printrends(void)                /* print ends of prism with rounding */
189   {
190 <        register int  i;
190 >        int  i;
191          double  c0[3], c1[3], cl[3];
192                                                  /* bottom face */
193          printf("\n%s polygon %s.b\n", pmtype, pname);
# Line 222 | Line 198 | printrends()                   /* print ends of prism with rounding */
198                          vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]),
199                          0.0);
200          }
201 +                                                /* top face */
202 +        printf("\n%s polygon %s.t\n", pmtype, pname);
203 +        printf("0\n0\n%d\n", nverts*3);
204 +        for (i = nverts; i--; ) {
205 +                printf("\t%18.12g\t%18.12g\t%18.12g\n",
206 +                vert[i][0] + lvect[0] + crad*(a[i]*u[i][0] - u[i][1]),
207 +                vert[i][1] + lvect[1] + crad*(a[i]*u[i][1] + u[i][0]),
208 +                lvect[2]);
209 +        }
210                                                  /* bottom corners and edges */
211          c0[0] = cl[0] = vert[nverts-1][0] +
212                          crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
# Line 236 | Line 221 | printrends()                   /* print ends of prism with rounding */
221                  } else {
222                          c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
223                  }
224 <                if (a[i] > 0.) {
224 >                if (lvdir*a[i] > 0.) {
225                          printf("\n%s sphere %s.bc%d\n", pmtype, pname, i+1);
226                          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
227 <                                c1[0], c1[1], c1[2], crad);
227 >                                c1[0], c1[1], c1[2], lvdir*crad);
228                  }
229                  printf("\n%s cylinder %s.be%d\n", pmtype, pname, i+1);
230                  printf("0\n0\n7\n");
231                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
232                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
233 <                printf("\t%18.12g\n", crad);
233 >                printf("\t%18.12g\n", lvdir*crad);
234                  c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
235          }
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        }
236                                                  /* top corners and edges */
237          c0[0] = cl[0] = vert[nverts-1][0] + lvect[0] +
238                          crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
# Line 273 | Line 249 | printrends()                   /* print ends of prism with rounding */
249                  } else {
250                          c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
251                  }
252 <                if (a[i] > 0.) {
252 >                if (lvdir*a[i] > 0.) {
253                          printf("\n%s sphere %s.tc%d\n", pmtype, pname, i+1);
254                          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
255 <                                c1[0], c1[1], c1[2], crad);
255 >                                c1[0], c1[1], c1[2], lvdir*crad);
256                  }
257                  printf("\n%s cylinder %s.te%d\n", pmtype, pname, i+1);
258                  printf("0\n0\n7\n");
259                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
260                  printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
261 <                printf("\t%18.12g\n", crad);
261 >                printf("\t%18.12g\n", lvdir*crad);
262                  c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
263          }
264   }
265  
266  
267 < printsides(round)               /* print prism sides */
268 < int  round;
267 > static void
268 > printsides(int round)           /* print prism sides */
269   {
270 <        register int  i;
270 >        int  i;
271  
272          for (i = 0; i < nverts-1; i++)
273                  if (round)
274                          rside(i, i+1);
275                  else
276                          side(i, i+1);
277 <        if (!iscomplete)
277 >        if (!iscomplete) {
278                  if (round)
279                          rside(nverts-1, 0);
280                  else
281                          side(nverts-1, 0);
282 +        }
283   }
284  
285  
286 < side(n0, n1)                    /* print single side */
287 < register int  n0, n1;
286 > int
287 > main(int argc, char **argv)
288   {
289 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
290 <        printf("0\n0\n12\n");
291 <        printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
292 <                        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 < }
289 >        int  an;
290 >        
291 >        if (argc < 4)
292 >                goto userr;
293  
294 +        pmtype = argv[1];
295 +        pname = argv[2];
296  
297 < rside(n0, n1)                   /* print side with rounded edge */
298 < register int  n0, n1;
299 < {
300 <        double  s, c, t[3];
297 >        if (!strcmp(argv[3], "-")) {
298 >                readverts(NULL);
299 >                an = 4;
300 >        } else if (isdigit(argv[3][0])) {
301 >                nverts = atoi(argv[3]);
302 >                if (argc-3 < 2*nverts)
303 >                        goto userr;
304 >                for (an = 0; an < nverts; an++) {
305 >                        vert[an][0] = atof(argv[2*an+4]);
306 >                        vert[an][1] = atof(argv[2*an+5]);
307 >                }
308 >                an = 2*nverts+4;
309 >        } else {
310 >                readverts(argv[3]);
311 >                an = 4;
312 >        }
313 >        if (nverts < 3) {
314 >                fprintf(stderr, "%s: not enough vertices\n", argv[0]);
315 >                exit(1);
316 >        }
317  
318 <                                        /* compute tanget offset vector */
319 <        s = (lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
320 <        if (s < -FTINY || s > FTINY) {
321 <                c = sqrt(1. - s*s);
322 <                t[0] = (c - 1.)*u[n1][1];
323 <                t[1] = (1. - c)*u[n1][0];
324 <                t[2] = s;
325 <        } else
326 <                t[0] = t[1] = t[2] = 0.;
327 <                                        /* output side */
328 <        printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
329 <        printf("0\n0\n12\n");
330 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
331 <                        vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
332 <                        vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
333 <                        crad*(t[2] + 1.));
334 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
335 <                        vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
336 <                        vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
337 <                        lvect[2] + crad*(t[2] - 1.));
338 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
339 <                        vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
340 <                        vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*u[n1][1]),
341 <                        lvect[2] + crad*(t[2] - 1.));
342 <        printf("\t%18.12g\t%18.12g\t%18.12g\n",
343 <                        vert[n1][0] + crad*(t[0] + a[n1]*u[n1][0]),
344 <                        vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
345 <                        crad*(t[2] + 1.));
346 <                                        /* output joining edge */
347 <        if (a[n1] < 0.)
348 <                return;
349 <        printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
350 <        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);
318 >        for ( ; an < argc; an++) {
319 >                if (argv[an][0] != '-')
320 >                        goto userr;
321 >                switch (argv[an][1]) {
322 >                case 'l':                               /* length vector */
323 >                        lvect[0] = atof(argv[++an]);
324 >                        lvect[1] = atof(argv[++an]);
325 >                        lvect[2] = atof(argv[++an]);
326 >                        if (lvect[2] < -FTINY)
327 >                                lvdir = -1;
328 >                        else if (lvect[2] > FTINY)
329 >                                lvdir = 1;
330 >                        else {
331 >                                fprintf(stderr,
332 >                                        "%s: illegal extrusion vector\n",
333 >                                                argv[0]);
334 >                                exit(1);
335 >                        }
336 >                        llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
337 >                                        lvect[2]*lvect[2]);
338 >                        break;
339 >                case 'r':                               /* radius */
340 >                        crad = atof(argv[++an]);
341 >                        break;
342 >                case 'e':                               /* ends */
343 >                        do_ends = !do_ends;
344 >                        break;
345 >                case 'c':                               /* complete */
346 >                        iscomplete = !iscomplete;
347 >                        break;
348 >                default:
349 >                        goto userr;
350 >                }
351          }
352 <        putchar('\n');
352 >        if (crad > FTINY) {
353 >                if (crad > lvdir*lvect[2]) {
354 >                        fprintf(stderr, "%s: rounding greater than height\n",
355 >                                        argv[0]);
356 >                        exit(1);
357 >                }
358 >                crad *= lvdir;          /* simplifies formulas */
359 >                compute_rounding();
360 >                fputs("# ", stdout);
361 >                printargs(argc, argv, stdout);
362 >                if (do_ends)
363 >                        printrends();
364 >                printsides(1);
365 >        } else {
366 >                fputs("# ", stdout);
367 >                printargs(argc, argv, stdout);
368 >                if (do_ends)
369 >                        printends();
370 >                printsides(0);
371 >        }
372 >        return(0);
373 > userr:
374 >        fprintf(stderr, "Usage: %s material name ", argv[0]);
375 >        fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
376 >        fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
377 >        return(1);
378   }
379 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines