ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 2.6
Committed: Fri Jun 27 06:53:22 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +4 -5 lines
Log Message:
Broke standard.h into rtio.h, rterror.h, rtmath.h, and rtmisc.h

File Contents

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