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 (14 hours, 2 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

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