ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 1.6
Committed: Fri Oct 13 19:34:51 1989 UTC (34 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +26 -25 lines
Log Message:
Made argument error checking more efficient.

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1986 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * xf.c - routines to convert transform arguments into 4X4 matrix.
9     *
10     * 1/28/86
11     */
12    
13    
14     #define PI 3.14159265358979323846
15 greg 1.6 #define d2r(a) ((PI/180.)*(a))
16 greg 1.1
17 greg 1.6 #define checkarg(a,n) if (av[i][a] || i+n >= ac) goto done
18 greg 1.1
19 greg 1.2
20 greg 1.1 int
21 greg 1.4 xf(retmat, retsca, ac, av) /* get transform specification */
22     double retmat[4][4];
23     double *retsca;
24 greg 1.1 int ac;
25     char *av[];
26     {
27     double atof(), sin(), cos();
28 greg 1.4 double xfmat[4][4], m4[4][4];
29     double xfsca, theta;
30 greg 1.5 int i, icnt;
31 greg 1.1
32 greg 1.4 setident4(retmat);
33     *retsca = 1.0;
34    
35     setident4(xfmat);
36     xfsca = 1.0;
37    
38 greg 1.1 for (i = 0; i < ac && av[i][0] == '-'; i++) {
39    
40     setident4(m4);
41    
42     switch (av[i][1]) {
43    
44     case 't': /* translate */
45 greg 1.6 checkarg(2,3);
46 greg 1.1 m4[3][0] = atof(av[++i]);
47     m4[3][1] = atof(av[++i]);
48     m4[3][2] = atof(av[++i]);
49     break;
50    
51     case 'r': /* rotate */
52     switch (av[i][2]) {
53     case 'x':
54 greg 1.6 checkarg(3,1);
55     theta = d2r(atof(av[++i]));
56 greg 1.1 m4[1][1] = m4[2][2] = cos(theta);
57     m4[2][1] = -(m4[1][2] = sin(theta));
58     break;
59     case 'y':
60 greg 1.6 checkarg(3,1);
61     theta = d2r(atof(av[++i]));
62 greg 1.1 m4[0][0] = m4[2][2] = cos(theta);
63     m4[0][2] = -(m4[2][0] = sin(theta));
64     break;
65     case 'z':
66 greg 1.6 checkarg(3,1);
67     theta = d2r(atof(av[++i]));
68 greg 1.1 m4[0][0] = m4[1][1] = cos(theta);
69     m4[1][0] = -(m4[0][1] = sin(theta));
70     break;
71     default:
72     return(i);
73     }
74     break;
75    
76     case 's': /* scale */
77 greg 1.6 checkarg(2,1);
78 greg 1.4 xfsca *=
79 greg 1.1 m4[0][0] =
80     m4[1][1] =
81     m4[2][2] = atof(av[++i]);
82     break;
83    
84     case 'm': /* mirror */
85     switch (av[i][2]) {
86     case 'x':
87 greg 1.6 checkarg(3,0);
88 greg 1.4 xfsca *=
89 greg 1.1 m4[0][0] = -1.0;
90     break;
91     case 'y':
92 greg 1.6 checkarg(3,0);
93 greg 1.4 xfsca *=
94 greg 1.1 m4[1][1] = -1.0;
95     break;
96     case 'z':
97 greg 1.6 checkarg(3,0);
98 greg 1.4 xfsca *=
99 greg 1.1 m4[2][2] = -1.0;
100     break;
101     default:
102     return(i);
103     }
104     break;
105    
106 greg 1.4 case 'i': /* iterate */
107 greg 1.6 checkarg(2,1);
108 greg 1.5 icnt = atoi(av[++i]);
109     while (icnt-- > 0) {
110 greg 1.4 multmat4(retmat, retmat, xfmat);
111     *retsca *= xfsca;
112     }
113     setident4(xfmat);
114     xfsca = 1.0;
115     break;
116    
117 greg 1.1 default:
118     return(i);
119    
120     }
121     multmat4(xfmat, xfmat, m4);
122     }
123 greg 1.4 done:
124 greg 1.5 multmat4(retmat, retmat, xfmat);
125     *retsca *= xfsca;
126 greg 1.1 return(i);
127     }
128    
129    
130     #ifdef INVXF
131     int
132 greg 1.4 invxf(retmat, retsca, ac, av) /* invert transform specification */
133     double retmat[4][4];
134     double *retsca;
135 greg 1.1 int ac;
136     char *av[];
137     {
138     double atof(), sin(), cos();
139 greg 1.4 double xfmat[4][4], m4[4][4];
140     double xfsca, theta;
141 greg 1.5 int i, icnt;
142 greg 1.1
143 greg 1.4 setident4(retmat);
144     *retsca = 1.0;
145    
146     setident4(xfmat);
147     xfsca = 1.0;
148    
149 greg 1.1 for (i = 0; i < ac && av[i][0] == '-'; i++) {
150    
151     setident4(m4);
152    
153     switch (av[i][1]) {
154    
155     case 't': /* translate */
156 greg 1.6 checkarg(2,3);
157 greg 1.1 m4[3][0] = -atof(av[++i]);
158     m4[3][1] = -atof(av[++i]);
159     m4[3][2] = -atof(av[++i]);
160     break;
161    
162     case 'r': /* rotate */
163     switch (av[i][2]) {
164     case 'x':
165 greg 1.6 checkarg(3,1);
166     theta = -d2r(atof(av[++i]));
167 greg 1.1 m4[1][1] = m4[2][2] = cos(theta);
168     m4[2][1] = -(m4[1][2] = sin(theta));
169     break;
170     case 'y':
171 greg 1.6 checkarg(3,1);
172     theta = -d2r(atof(av[++i]));
173 greg 1.1 m4[0][0] = m4[2][2] = cos(theta);
174     m4[0][2] = -(m4[2][0] = sin(theta));
175     break;
176     case 'z':
177 greg 1.6 checkarg(3,1);
178     theta = -d2r(atof(av[++i]));
179 greg 1.1 m4[0][0] = m4[1][1] = cos(theta);
180     m4[1][0] = -(m4[0][1] = sin(theta));
181     break;
182     default:
183     return(i);
184     }
185     break;
186    
187     case 's': /* scale */
188 greg 1.6 checkarg(2,1);
189 greg 1.5 xfsca *=
190 greg 1.1 m4[0][0] =
191     m4[1][1] =
192     m4[2][2] = 1.0 / atof(av[++i]);
193     break;
194    
195     case 'm': /* mirror */
196     switch (av[i][2]) {
197     case 'x':
198 greg 1.6 checkarg(3,0);
199 greg 1.5 xfsca *=
200 greg 1.1 m4[0][0] = -1.0;
201     break;
202     case 'y':
203 greg 1.6 checkarg(3,0);
204 greg 1.5 xfsca *=
205 greg 1.1 m4[1][1] = -1.0;
206     break;
207     case 'z':
208 greg 1.6 checkarg(3,0);
209 greg 1.5 xfsca *=
210 greg 1.1 m4[2][2] = -1.0;
211     break;
212     default:
213     return(i);
214     }
215     break;
216    
217 greg 1.4 case 'i': /* iterate */
218 greg 1.6 checkarg(2,1);
219 greg 1.5 icnt = atoi(av[++i]);
220     while (icnt-- > 0) {
221 greg 1.4 multmat4(retmat, xfmat, retmat);
222     *retsca *= xfsca;
223     }
224     setident4(xfmat);
225     xfsca = 1.0;
226     break;
227    
228 greg 1.1 default:
229     return(i);
230    
231     }
232     multmat4(xfmat, m4, xfmat); /* left multiply */
233 greg 1.4 }
234     done:
235 greg 1.5 multmat4(retmat, xfmat, retmat);
236     *retsca *= xfsca;
237 greg 1.1 return(i);
238     }
239     #endif