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

# Content
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 #define d2r(a) ((PI/180.)*(a))
16
17 #define checkarg(a,n) if (av[i][a] || i+n >= ac) goto done
18
19
20 int
21 xf(retmat, retsca, ac, av) /* get transform specification */
22 double retmat[4][4];
23 double *retsca;
24 int ac;
25 char *av[];
26 {
27 double atof(), sin(), cos();
28 double xfmat[4][4], m4[4][4];
29 double xfsca, theta;
30 int i, icnt;
31
32 setident4(retmat);
33 *retsca = 1.0;
34
35 setident4(xfmat);
36 xfsca = 1.0;
37
38 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 checkarg(2,3);
46 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 checkarg(3,1);
55 theta = d2r(atof(av[++i]));
56 m4[1][1] = m4[2][2] = cos(theta);
57 m4[2][1] = -(m4[1][2] = sin(theta));
58 break;
59 case 'y':
60 checkarg(3,1);
61 theta = d2r(atof(av[++i]));
62 m4[0][0] = m4[2][2] = cos(theta);
63 m4[0][2] = -(m4[2][0] = sin(theta));
64 break;
65 case 'z':
66 checkarg(3,1);
67 theta = d2r(atof(av[++i]));
68 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 checkarg(2,1);
78 xfsca *=
79 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 checkarg(3,0);
88 xfsca *=
89 m4[0][0] = -1.0;
90 break;
91 case 'y':
92 checkarg(3,0);
93 xfsca *=
94 m4[1][1] = -1.0;
95 break;
96 case 'z':
97 checkarg(3,0);
98 xfsca *=
99 m4[2][2] = -1.0;
100 break;
101 default:
102 return(i);
103 }
104 break;
105
106 case 'i': /* iterate */
107 checkarg(2,1);
108 icnt = atoi(av[++i]);
109 while (icnt-- > 0) {
110 multmat4(retmat, retmat, xfmat);
111 *retsca *= xfsca;
112 }
113 setident4(xfmat);
114 xfsca = 1.0;
115 break;
116
117 default:
118 return(i);
119
120 }
121 multmat4(xfmat, xfmat, m4);
122 }
123 done:
124 multmat4(retmat, retmat, xfmat);
125 *retsca *= xfsca;
126 return(i);
127 }
128
129
130 #ifdef INVXF
131 int
132 invxf(retmat, retsca, ac, av) /* invert transform specification */
133 double retmat[4][4];
134 double *retsca;
135 int ac;
136 char *av[];
137 {
138 double atof(), sin(), cos();
139 double xfmat[4][4], m4[4][4];
140 double xfsca, theta;
141 int i, icnt;
142
143 setident4(retmat);
144 *retsca = 1.0;
145
146 setident4(xfmat);
147 xfsca = 1.0;
148
149 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 checkarg(2,3);
157 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 checkarg(3,1);
166 theta = -d2r(atof(av[++i]));
167 m4[1][1] = m4[2][2] = cos(theta);
168 m4[2][1] = -(m4[1][2] = sin(theta));
169 break;
170 case 'y':
171 checkarg(3,1);
172 theta = -d2r(atof(av[++i]));
173 m4[0][0] = m4[2][2] = cos(theta);
174 m4[0][2] = -(m4[2][0] = sin(theta));
175 break;
176 case 'z':
177 checkarg(3,1);
178 theta = -d2r(atof(av[++i]));
179 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 checkarg(2,1);
189 xfsca *=
190 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 checkarg(3,0);
199 xfsca *=
200 m4[0][0] = -1.0;
201 break;
202 case 'y':
203 checkarg(3,0);
204 xfsca *=
205 m4[1][1] = -1.0;
206 break;
207 case 'z':
208 checkarg(3,0);
209 xfsca *=
210 m4[2][2] = -1.0;
211 break;
212 default:
213 return(i);
214 }
215 break;
216
217 case 'i': /* iterate */
218 checkarg(2,1);
219 icnt = atoi(av[++i]);
220 while (icnt-- > 0) {
221 multmat4(retmat, xfmat, retmat);
222 *retsca *= xfsca;
223 }
224 setident4(xfmat);
225 xfsca = 1.0;
226 break;
227
228 default:
229 return(i);
230
231 }
232 multmat4(xfmat, m4, xfmat); /* left multiply */
233 }
234 done:
235 multmat4(retmat, xfmat, retmat);
236 *retsca *= xfsca;
237 return(i);
238 }
239 #endif