1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package math.geom3d.transform;
28
29 import math.geom3d.Point3D;
30 import math.geom3d.Shape3D;
31 import math.geom3d.Vector3D;
32
33
34
35
36 public class AffineTransform3D implements Bijection3D {
37
38
39
40
41 protected double m00, m01, m02, m03;
42
43
44 protected double m10, m11, m12, m13;
45
46
47 protected double m20, m21, m22, m23;
48
49
50
51
52 public final static AffineTransform3D createTranslation(Vector3D vec) {
53 return createTranslation(vec.getX(), vec.getY(), vec.getZ());
54 }
55
56 public final static AffineTransform3D createTranslation(double x, double y,
57 double z) {
58 return new AffineTransform3D(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z);
59 }
60
61 public final static AffineTransform3D createRotationOx(double theta) {
62 double cot = Math.cos(theta);
63 double sit = Math.sin(theta);
64 return new AffineTransform3D(1, 0, 0, 0, 0, cot, -sit, 0, 0, sit, cot,
65 0);
66 }
67
68 public final static AffineTransform3D createRotationOy(double theta) {
69 double cot = Math.cos(theta);
70 double sit = Math.sin(theta);
71 return new AffineTransform3D(cot, 0, sit, 0, 0, 1, 0, 0, -sit, 0, cot,
72 0);
73 }
74
75 public final static AffineTransform3D createRotationOz(double theta) {
76 double cot = Math.cos(theta);
77 double sit = Math.sin(theta);
78 return new AffineTransform3D(cot, -sit, 0, 0, sit, cot, 0, 0, 0, 0, 1,
79 0);
80 }
81
82 AffineTransform3D createScaling(double s) {
83 return createScaling(s, s, s);
84 }
85
86 AffineTransform3D createScaling(double sx, double sy, double sz) {
87 return new AffineTransform3D(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0);
88 }
89
90
91
92
93
94 public AffineTransform3D() {
95
96 m00 = m11 = m22 = 1;
97 m01 = m02 = m03 = 0;
98 m10 = m12 = m13 = 0;
99 m20 = m21 = m23 = 0;
100 }
101
102 public AffineTransform3D(double[] coefs) {
103 if (coefs.length==9) {
104 m00 = coefs[0];
105 m01 = coefs[1];
106 m02 = coefs[2];
107 m10 = coefs[3];
108 m11 = coefs[4];
109 m12 = coefs[5];
110 m20 = coefs[6];
111 m21 = coefs[7];
112 m22 = coefs[8];
113 } else if (coefs.length==12) {
114 m00 = coefs[0];
115 m01 = coefs[1];
116 m02 = coefs[2];
117 m03 = coefs[3];
118 m10 = coefs[4];
119 m11 = coefs[5];
120 m12 = coefs[6];
121 m13 = coefs[7];
122 m20 = coefs[8];
123 m21 = coefs[9];
124 m22 = coefs[10];
125 m23 = coefs[11];
126 }
127 }
128
129 public AffineTransform3D(double xx, double yx, double zx, double tx,
130 double xy, double yy, double zy, double ty, double xz, double yz,
131 double zz, double tz) {
132 m00 = xx;
133 m01 = yx;
134 m02 = zx;
135 m03 = tx;
136 m10 = xy;
137 m11 = yy;
138 m12 = zy;
139 m13 = ty;
140 m20 = xz;
141 m21 = yz;
142 m22 = zz;
143 m23 = tz;
144 }
145
146
147
148
149 public boolean isIdentity() {
150 if (m00!=1)
151 return false;
152 if (m11!=1)
153 return false;
154 if (m22!=0)
155 return false;
156 if (m01!=0)
157 return false;
158 if (m02!=0)
159 return false;
160 if (m03!=0)
161 return false;
162 if (m10!=0)
163 return false;
164 if (m12!=0)
165 return false;
166 if (m13!=0)
167 return false;
168 if (m20!=0)
169 return false;
170 if (m21!=0)
171 return false;
172 if (m23!=0)
173 return false;
174 return true;
175 }
176
177
178
179
180
181 public double[] getCoefficients() {
182 double[] tab = { m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22,
183 m23 };
184 return tab;
185 }
186
187
188
189
190
191
192 private double getDeterminant() {
193 return +m00*(m11*m22-m12*m21)-m01*(m10*m22-m20*m12)+m02
194 *(m10*m21-m20*m11);
195 }
196
197
198
199
200 public AffineTransform3D getInverseTransform() {
201 double det = this.getDeterminant();
202 return new AffineTransform3D((m11*m22-m21*m12)/det, (m21*m01-m01*m22)
203 /det, (m01*m12-m11*m02)/det, (m01*(m22*m13-m12*m23)+m02
204 *(m11*m23-m21*m13)-m03*(m11*m22-m21*m12))
205 /det, (m20*m12-m10*m22)/det, (m00*m22-m20*m02)/det,
206 (m10*m02-m00*m12)/det, (m00*(m12*m23-m22*m13)-m02
207 *(m10*m23-m20*m13)+m03*(m10*m22-m20*m12))
208 /det, (m10*m21-m20*m11)/det, (m20*m01-m00*m21)/det,
209 (m00*m11-m10*m01)/det, (m00*(m21*m13-m11*m23)+m01
210 *(m10*m23-m20*m13)-m03*(m10*m21-m20*m11))
211 /det);
212 }
213
214
215
216
217
218
219
220 @Deprecated
221 public void setTransform(double n00, double n01, double n02, double n03,
222 double n10, double n11, double n12, double n13, double n20,
223 double n21, double n22, double n23) {
224 m00 = n00;
225 m01 = n01;
226 m02 = n02;
227 m03 = n03;
228 m10 = n10;
229 m11 = n11;
230 m12 = n12;
231 m13 = n13;
232 m20 = n20;
233 m21 = n21;
234 m22 = n22;
235 m23 = n23;
236 }
237
238
239
240
241 @Deprecated
242 public void setTransform(AffineTransform3D trans) {
243 m00 = trans.m00;
244 m01 = trans.m01;
245 m02 = trans.m02;
246 m03 = trans.m03;
247 m10 = trans.m10;
248 m11 = trans.m11;
249 m12 = trans.m12;
250 m13 = trans.m13;
251 m20 = trans.m20;
252 m21 = trans.m21;
253 m22 = trans.m22;
254 m23 = trans.m23;
255 }
256
257
258
259
260 @Deprecated
261 public void setToIdentity() {
262 m00 = m11 = m22 = 1;
263 m01 = m02 = m03 = 0;
264 m10 = m12 = m13 = 0;
265 m20 = m21 = m23 = 0;
266 }
267
268
269
270
271
272
273
274
275
276 public void transform(AffineTransform3D trans) {
277 double n00 = m00*trans.m00+m10*trans.m01;
278 double n10 = m00*trans.m10+m10*trans.m11;
279 double n01 = m01*trans.m00+m11*trans.m01;
280 double n11 = m01*trans.m10+m11*trans.m11;
281 double n02 = m02*trans.m00+m12*trans.m01+trans.m02;
282 double n12 = m02*trans.m10+m12*trans.m11+trans.m12;
283 m00 = n00;
284 m01 = n01;
285 m02 = n02;
286 m10 = n10;
287 m11 = n11;
288 m12 = n12;
289 }
290
291
292
293
294 public void preConcatenate(AffineTransform3D trans) {
295 double n00 = trans.m00*m00+trans.m10*m01;
296 double n10 = trans.m00*m10+trans.m10*m11;
297 double n01 = trans.m01*m00+trans.m11*m01;
298 double n11 = trans.m01*m10+trans.m11*m11;
299 double n02 = trans.m02*m00+trans.m12*m01+m02;
300 double n12 = trans.m02*m10+trans.m12*m11+m12;
301 m00 = n00;
302 m01 = n01;
303 m02 = n02;
304 m10 = n10;
305 m11 = n11;
306 m12 = n12;
307 }
308
309
310
311
312 @Deprecated
313 public Shape3D transform(Shape3D shape) {
314 return shape.transform(this);
315 }
316
317 public Point3D[] transformPoints(Point3D[] src, Point3D[] dst) {
318 if (dst==null)
319 dst = new Point3D[src.length];
320 if (dst[0]==null)
321 for (int i = 0; i<src.length; i++)
322 dst[i] = new Point3D();
323
324 double coef[] = getCoefficients();
325
326 for (int i = 0; i<src.length; i++)
327 dst[i].setLocation(new Point3D(src[i].getX()*coef[0]+src[i].getY()
328 *coef[1]+src[i].getZ()*coef[2]+coef[3], src[i].getX()
329 *coef[4]+src[i].getY()*coef[5]+src[i].getZ()*coef[6]
330 +coef[7], src[i].getX()*coef[8]+src[i].getY()*coef[9]
331 +src[i].getZ()*coef[10]+coef[12]));
332 return dst;
333 }
334
335 public Point3D transformPoint(Point3D src, Point3D dst) {
336 double coef[] = getCoefficients();
337 if (dst==null)
338 dst = new Point3D();
339 dst.setLocation(new Point3D(src.getX()*coef[0]+src.getY()*coef[1]
340 +src.getZ()*coef[2]+coef[3], src.getX()*coef[4]+src.getY()
341 *coef[5]+src.getZ()*coef[6]+coef[7], src.getX()*coef[8]
342 +src.getY()*coef[9]+src.getZ()*coef[10]+coef[12]));
343 return dst;
344 }
345
346
347
348
349
350 @Override
351 public boolean equals(Object obj) {
352 if (!(obj instanceof AffineTransform3D))
353 return false;
354
355 double tab[] = ((AffineTransform3D) obj).getCoefficients();
356
357 if (Math.abs(tab[0]-m00)>Shape3D.ACCURACY)
358 return false;
359 if (Math.abs(tab[1]-m01)>Shape3D.ACCURACY)
360 return false;
361 if (Math.abs(tab[2]-m02)>Shape3D.ACCURACY)
362 return false;
363 if (Math.abs(tab[3]-m03)>Shape3D.ACCURACY)
364 return false;
365 if (Math.abs(tab[4]-m10)>Shape3D.ACCURACY)
366 return false;
367 if (Math.abs(tab[5]-m11)>Shape3D.ACCURACY)
368 return false;
369 if (Math.abs(tab[6]-m12)>Shape3D.ACCURACY)
370 return false;
371 if (Math.abs(tab[7]-m13)>Shape3D.ACCURACY)
372 return false;
373 if (Math.abs(tab[8]-m20)>Shape3D.ACCURACY)
374 return false;
375 if (Math.abs(tab[9]-m21)>Shape3D.ACCURACY)
376 return false;
377 if (Math.abs(tab[10]-m22)>Shape3D.ACCURACY)
378 return false;
379 if (Math.abs(tab[11]-m23)>Shape3D.ACCURACY)
380 return false;
381 return true;
382 }
383
384 }