ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 2.9
Committed: Mon Jun 23 15:11:04 2025 UTC (8 hours, 18 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.8: +20 -1 lines
Log Message:
fix: Made check for transform a little more robust with isxfopt() function

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: xf.c,v 2.8 2020/04/02 20:44:15 greg Exp $";
3 #endif
4 /*
5 * xf.c - routines to convert transform arguments into 4X4 matrix.
6 *
7 * External symbols declared in rtmath.h
8 */
9
10 #include <stdlib.h>
11 #include "rtmath.h"
12 #include "rtio.h"
13
14 #define d2r(a) ((PI/180.)*(a))
15
16 #define checkarg(a,l) if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
17
18
19 int
20 isxfopt(char *p) /* check whether option begins transform */
21 {
22 if (*p++ != '-')
23 return(0);
24
25 if ((p[0] == 't') | (p[0] == 's') | (p[0] == 'i') &&
26 !p[1])
27 return(1);
28
29 if ((p[0] == 'r') | (p[0] == 'm') &&
30 ('x' <= p[1]) & (p[1] <= 'z') &&
31 !p[2])
32 return(1);
33
34 return(0);
35 }
36
37
38 int
39 xf(XF *ret, int ac, char *av[]) /* get transform specification */
40 {
41 MAT4 xfmat, m4;
42 double xfsca, dtmp;
43 int i, icnt;
44
45 setident4(ret->xfm);
46 ret->sca = 1.0;
47
48 icnt = 1;
49 setident4(xfmat);
50 xfsca = 1.0;
51
52 for (i = 0; i < ac && av[i][0] == '-'; i++) {
53
54 setident4(m4);
55
56 switch (av[i][1]) {
57
58 case 't': /* translate */
59 checkarg(2,"fff");
60 m4[3][0] = atof(av[++i]);
61 m4[3][1] = atof(av[++i]);
62 m4[3][2] = atof(av[++i]);
63 break;
64
65 case 'r': /* rotate */
66 switch (av[i][2]) {
67 case 'x':
68 checkarg(3,"f");
69 dtmp = d2r(atof(av[++i]));
70 m4[1][1] = m4[2][2] = cos(dtmp);
71 m4[2][1] = -(m4[1][2] = sin(dtmp));
72 break;
73 case 'y':
74 checkarg(3,"f");
75 dtmp = d2r(atof(av[++i]));
76 m4[0][0] = m4[2][2] = cos(dtmp);
77 m4[0][2] = -(m4[2][0] = sin(dtmp));
78 break;
79 case 'z':
80 checkarg(3,"f");
81 dtmp = d2r(atof(av[++i]));
82 m4[0][0] = m4[1][1] = cos(dtmp);
83 m4[1][0] = -(m4[0][1] = sin(dtmp));
84 break;
85 default:
86 goto done;
87 }
88 break;
89
90 case 's': /* scale */
91 checkarg(2,"f");
92 dtmp = atof(av[i+1]);
93 if (dtmp == 0.0) goto done;
94 i++;
95 xfsca *=
96 m4[0][0] =
97 m4[1][1] =
98 m4[2][2] = dtmp;
99 break;
100
101 case 'm': /* mirror */
102 switch (av[i][2]) {
103 case 'x':
104 checkarg(3,"");
105 xfsca *=
106 m4[0][0] = -1.0;
107 break;
108 case 'y':
109 checkarg(3,"");
110 xfsca *=
111 m4[1][1] = -1.0;
112 break;
113 case 'z':
114 checkarg(3,"");
115 xfsca *=
116 m4[2][2] = -1.0;
117 break;
118 default:
119 goto done;
120 }
121 break;
122
123 case 'i': /* iterate */
124 checkarg(2,"i");
125 while (icnt-- > 0) {
126 multmat4(ret->xfm, ret->xfm, xfmat);
127 ret->sca *= xfsca;
128 }
129 icnt = atoi(av[++i]);
130 setident4(xfmat);
131 xfsca = 1.0;
132 continue;
133
134 default:
135 goto done;
136
137 }
138 multmat4(xfmat, xfmat, m4);
139 }
140 done:
141 while (icnt-- > 0) {
142 multmat4(ret->xfm, ret->xfm, xfmat);
143 ret->sca *= xfsca;
144 }
145 return(i);
146 }
147
148
149 int
150 invxf(XF *ret, int ac, char *av[]) /* invert transform specification */
151 {
152 MAT4 xfmat, m4;
153 double xfsca, dtmp;
154 int i, icnt;
155
156 setident4(ret->xfm);
157 ret->sca = 1.0;
158
159 icnt = 1;
160 setident4(xfmat);
161 xfsca = 1.0;
162
163 for (i = 0; i < ac && av[i][0] == '-'; i++) {
164
165 setident4(m4);
166
167 switch (av[i][1]) {
168
169 case 't': /* translate */
170 checkarg(2,"fff");
171 m4[3][0] = -atof(av[++i]);
172 m4[3][1] = -atof(av[++i]);
173 m4[3][2] = -atof(av[++i]);
174 break;
175
176 case 'r': /* rotate */
177 switch (av[i][2]) {
178 case 'x':
179 checkarg(3,"f");
180 dtmp = -d2r(atof(av[++i]));
181 m4[1][1] = m4[2][2] = cos(dtmp);
182 m4[2][1] = -(m4[1][2] = sin(dtmp));
183 break;
184 case 'y':
185 checkarg(3,"f");
186 dtmp = -d2r(atof(av[++i]));
187 m4[0][0] = m4[2][2] = cos(dtmp);
188 m4[0][2] = -(m4[2][0] = sin(dtmp));
189 break;
190 case 'z':
191 checkarg(3,"f");
192 dtmp = -d2r(atof(av[++i]));
193 m4[0][0] = m4[1][1] = cos(dtmp);
194 m4[1][0] = -(m4[0][1] = sin(dtmp));
195 break;
196 default:
197 goto done;
198 }
199 break;
200
201 case 's': /* scale */
202 checkarg(2,"f");
203 dtmp = atof(av[i+1]);
204 if (dtmp == 0.0) goto done;
205 i++;
206 xfsca *=
207 m4[0][0] =
208 m4[1][1] =
209 m4[2][2] = 1.0 / dtmp;
210 break;
211
212 case 'm': /* mirror */
213 switch (av[i][2]) {
214 case 'x':
215 checkarg(3,"");
216 xfsca *=
217 m4[0][0] = -1.0;
218 break;
219 case 'y':
220 checkarg(3,"");
221 xfsca *=
222 m4[1][1] = -1.0;
223 break;
224 case 'z':
225 checkarg(3,"");
226 xfsca *=
227 m4[2][2] = -1.0;
228 break;
229 default:
230 goto done;
231 }
232 break;
233
234 case 'i': /* iterate */
235 checkarg(2,"i");
236 while (icnt-- > 0) {
237 multmat4(ret->xfm, xfmat, ret->xfm);
238 ret->sca *= xfsca;
239 }
240 icnt = atoi(av[++i]);
241 setident4(xfmat);
242 xfsca = 1.0;
243 break;
244
245 default:
246 goto done;
247
248 }
249 multmat4(xfmat, m4, xfmat); /* left multiply */
250 }
251 done:
252 while (icnt-- > 0) {
253 multmat4(ret->xfm, xfmat, ret->xfm);
254 ret->sca *= xfsca;
255 }
256 return(i);
257 }
258
259
260 int
261 fullxf(FULLXF *fx, int ac, char *av[]) /* compute both forward and inverse */
262 {
263 xf(&fx->f, ac, av);
264 return(invxf(&fx->b, ac, av));
265 }