svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libDwg / src / org / gvsig / dwg / lib / util / Matrix4D.java @ 28969
History | View | Annotate | Download (12 KB)
1 |
|
---|---|
2 |
package org.gvsig.dwg.lib.util; |
3 |
|
4 |
|
5 |
/**
|
6 |
* 4x4dim double matrix used for perspective transformations.
|
7 |
* The class is now declared final to allow a more aggresive optimization.
|
8 |
*
|
9 |
*/
|
10 |
public final class Matrix4D { |
11 |
static private final double DEG2RAD = Math.PI/180.0; // conversion from degree to radians |
12 |
|
13 |
public double xx, xy, xz, xw, // 1st row |
14 |
yx, yy, yz, yw, // 2nd row
|
15 |
zx, zy, zz, zw, // 3rd row
|
16 |
wx, wy, wz, ww; // 4th row
|
17 |
|
18 |
/**
|
19 |
* Create identity matrix.
|
20 |
*/
|
21 |
public Matrix4D() {
|
22 |
// set to identity mat
|
23 |
xx = yy = zz = ww = 1f;
|
24 |
} |
25 |
|
26 |
/**
|
27 |
* Copy constructor.
|
28 |
* @param m matrix to copy
|
29 |
*/
|
30 |
public Matrix4D(Matrix4D m) {
|
31 |
xx = m.xx; |
32 |
xy = m.xy; |
33 |
xz = m.xz; |
34 |
xw = m.xw; |
35 |
yx = m.yx; |
36 |
yy = m.yy; |
37 |
yz = m.yz; |
38 |
yw = m.yw; |
39 |
zx = m.zx; |
40 |
zy = m.zy; |
41 |
zz = m.zz; |
42 |
zw = m.zw; |
43 |
wx = m.wx; |
44 |
wy = m.wy; |
45 |
wz = m.wz; |
46 |
ww = m.ww; |
47 |
} |
48 |
|
49 |
/**
|
50 |
* @param mxx 1st elem in 1st row
|
51 |
* @param mxy 2nd elem in 1st row
|
52 |
* @param mxz 3rd elem in 1st row
|
53 |
* @param mxw 4th elem in 1st row
|
54 |
* @param myx 1st elem in 2nd row
|
55 |
* @param myy 2nd elem in 2nd row
|
56 |
* @param myz 3rd elem in 2nd row
|
57 |
* @param myw 4th elem in 2nd row
|
58 |
* @param mzx 1st elem in 3rd row
|
59 |
* @param mzy 2nd elem in 3rd row
|
60 |
* @param mzz 3rd elem in 3rd row
|
61 |
* @param mzw 4th elem in 3rd row
|
62 |
* @param mwx 1st elem in 4th row
|
63 |
* @param mwy 2nd elem in 4th row
|
64 |
* @param mwz 3rd elem in 4th row
|
65 |
* @param mww 4th elem in 4th row
|
66 |
*/
|
67 |
public Matrix4D(double mxx, double mxy, double mxz, double mxw, |
68 |
double myx, double myy, double myz, double myw, |
69 |
double mzx, double mzy, double mzz, double mzw, |
70 |
double mwx, double mwy, double mwz, double mww) { |
71 |
xx = mxx; |
72 |
xy = mxy; |
73 |
xz = mxz; |
74 |
xw = mxw; |
75 |
yx = myx; |
76 |
yy = myy; |
77 |
yz = myz; |
78 |
yw = myw; |
79 |
zx = mzx; |
80 |
zy = mzy; |
81 |
zz = mzz; |
82 |
zw = mzw; |
83 |
wx = mwx; |
84 |
wy = mwy; |
85 |
wz = mwz; |
86 |
ww = mww; |
87 |
} |
88 |
|
89 |
/**
|
90 |
* Reset to identity
|
91 |
*/
|
92 |
public void identity() { |
93 |
xx = yy = zz = ww = 1f;
|
94 |
xy = xz = xw = |
95 |
yx = yz = yw = |
96 |
zx = zy = zw = |
97 |
wx = wy = wz = 0f;
|
98 |
} |
99 |
|
100 |
/**
|
101 |
* Transponize.
|
102 |
*/
|
103 |
public void transponize() { |
104 |
// switch rows and columns
|
105 |
double t;
|
106 |
t = xy; xy = yx; yx = t; |
107 |
t = xz; xz = zx; zx = t; |
108 |
t = xw; xw = wx; wx = t; |
109 |
t = yz; yz = zy; zy = t; |
110 |
t = yw; yw = wy; wy = t; |
111 |
t = zw; zw = wz; wz = t; |
112 |
} |
113 |
|
114 |
/**
|
115 |
* Matrix multiplication of vector.
|
116 |
* @param v vector to transform
|
117 |
* @return transformed vector
|
118 |
*/
|
119 |
public Vector3D mult(Vector3D v) {
|
120 |
return new Vector3D(xx*v.x + xy*v.y + xz*v.z, |
121 |
yx*v.x + yy*v.y + yz*v.z, |
122 |
zx*v.x + zy*v.y + zz*v.z); |
123 |
} |
124 |
|
125 |
/**
|
126 |
* Transformation of 1 vector.
|
127 |
* @param v vector to transform
|
128 |
*/
|
129 |
public void transform(Vector3D v) { |
130 |
double x = xx*v.x + xy*v.y + xz*v.z,
|
131 |
y = yx*v.x + yy*v.y + yz*v.z, |
132 |
z = zx*v.x + zy*v.y + zz*v.z; |
133 |
|
134 |
v.x = x; |
135 |
v.y = y; |
136 |
v.z = z; |
137 |
} |
138 |
|
139 |
/**
|
140 |
* Matrix multiplication of point.
|
141 |
* @param p point to transform
|
142 |
* @return transformed point
|
143 |
*/
|
144 |
public Point3D mult(Point3D p) {
|
145 |
Point3D ret = new Point3D(xx*p.x + xy*p.y + xz*p.z + xw,
|
146 |
yx*p.x + yy*p.y + yz*p.z + yw, |
147 |
zx*p.x + zy*p.y + zz*p.z + zw); |
148 |
ret.scale(1f/(wx*p.x + wy*p.y + wz*p.z + ww));
|
149 |
return ret;
|
150 |
} |
151 |
|
152 |
/**
|
153 |
* Transformation of 1 point.
|
154 |
* @param p point to transform
|
155 |
*/
|
156 |
public void transform(Point3D p) { |
157 |
double x = xx*p.x + xy*p.y + xz*p.z + xw,
|
158 |
y = yx*p.x + yy*p.y + yz*p.z + yw, |
159 |
z = zx*p.x + zy*p.y + zz*p.z + zw, |
160 |
w = wx*p.x + wy*p.y + wz*p.z + ww; |
161 |
|
162 |
p.x = x/w; |
163 |
p.y = y/w; |
164 |
p.z = z/w; |
165 |
} |
166 |
|
167 |
/**Transformacion de un punto considerando solo el plano horizontal
|
168 |
*/
|
169 |
public void transformXY(Point3D p){ |
170 |
double x = xx*p.x + xy*p.y+ xw,
|
171 |
y = yx*p.x + yy*p.y + yw, |
172 |
w = wx*p.x + wy*p.y + ww; |
173 |
p.x = x/w; |
174 |
p.y = y/w; |
175 |
} |
176 |
|
177 |
/**
|
178 |
* Matrix multiplication.
|
179 |
* @param m matrix to multiply with
|
180 |
* @return this * m
|
181 |
*/
|
182 |
public Matrix4D mult(Matrix4D m) {
|
183 |
if (m != null) { |
184 |
return new Matrix4D(xx*m.xx + xy*m.yx + xz*m.zx + xw*m.wx, |
185 |
xx*m.xy + xy*m.yy + xz*m.zy + xw*m.wy, |
186 |
xx*m.xz + xy*m.yz + xz*m.zz + xw*m.wz, |
187 |
xx*m.xw + xy*m.yw + xz*m.zw + xw*m.ww, |
188 |
yx*m.xx + yy*m.yx + yz*m.zx + yw*m.wx, |
189 |
yx*m.xy + yy*m.yy + yz*m.zy + yw*m.wy, |
190 |
yx*m.xz + yy*m.yz + yz*m.zz + yw*m.wz, |
191 |
yx*m.xw + yy*m.yw + yz*m.zw + yw*m.ww, |
192 |
zx*m.xx + zy*m.yx + zz*m.zx + zw*m.wx, |
193 |
zx*m.xy + zy*m.yy + zz*m.zy + zw*m.wy, |
194 |
zx*m.xz + zy*m.yz + zz*m.zz + zw*m.wz, |
195 |
zx*m.xw + zy*m.yw + zz*m.zw + zw*m.ww, |
196 |
wx*m.xx + wy*m.yx + wz*m.zx + ww*m.wx, |
197 |
wx*m.xy + wy*m.yy + wz*m.zy + ww*m.wy, |
198 |
wx*m.xz + wy*m.yz + wz*m.zz + ww*m.wz, |
199 |
wx*m.xw + wy*m.yw + wz*m.zw + ww*m.ww); |
200 |
} |
201 |
else {
|
202 |
return new Matrix4D(this); |
203 |
} |
204 |
} |
205 |
|
206 |
/**
|
207 |
* Matrix multiplication.
|
208 |
* @param m matrix to multply with
|
209 |
*/
|
210 |
public void multBy(Matrix4D m) { |
211 |
double x = xx*m.xx + xy*m.yx + xz*m.zx + xw*m.wx,
|
212 |
y = xx*m.xy + xy*m.yy + xz*m.zy + xw*m.wy, |
213 |
z = xx*m.xz + xy*m.yz + xz*m.zz + xw*m.wz, |
214 |
w = xx*m.xw + xy*m.yw + xz*m.zw + xw*m.ww; |
215 |
xx = x; |
216 |
xy = y; |
217 |
xz = z; |
218 |
xw = w; |
219 |
|
220 |
x = yx*m.xx + yy*m.yx + yz*m.zx + yw*m.wx; |
221 |
y = yx*m.xy + yy*m.yy + yz*m.zy + yw*m.wy; |
222 |
z = yx*m.xz + yy*m.yz + yz*m.zz + yw*m.wz; |
223 |
w = yx*m.xw + yy*m.yw + yz*m.zw + yw*m.ww; |
224 |
yx = x; |
225 |
yy = y; |
226 |
yz = z; |
227 |
yw = w; |
228 |
|
229 |
x = zx*m.xx + zy*m.yx + zz*m.zx + zw*m.wx; |
230 |
y = zx*m.xy + zy*m.yy + zz*m.zy + zw*m.wy; |
231 |
z = zx*m.xz + zy*m.yz + zz*m.zz + zw*m.wz; |
232 |
w = zx*m.xw + zy*m.yw + zz*m.zw + zw*m.ww; |
233 |
zx = x; |
234 |
zy = y; |
235 |
zz = z; |
236 |
zw = w; |
237 |
|
238 |
x = wx*m.xx + wy*m.yx + wz*m.zx + ww*m.wx; |
239 |
y = wx*m.xy + wy*m.yy + wz*m.zy + ww*m.wy; |
240 |
z = wx*m.xz + wy*m.yz + wz*m.zz + ww*m.wz; |
241 |
w = wx*m.xw + wy*m.yw + wz*m.zw + ww*m.ww; |
242 |
wx = x; |
243 |
wy = y; |
244 |
wz = z; |
245 |
ww = w; |
246 |
} |
247 |
|
248 |
/**
|
249 |
* Matrix multiplication from left.
|
250 |
* @param m matrix to multiply with.
|
251 |
*/
|
252 |
public void multLeftBy(Matrix4D m) { |
253 |
double x = m.xx*xx + m.xy*yx + m.xz*zx + m.xw*wx,
|
254 |
y = m.yx*xx + m.yy*yx + m.yz*zx + m.yw*wx, |
255 |
z = m.zx*xx + m.zy*yx + m.zz*zx + m.zw*wx, |
256 |
w = m.wx*xx + m.wy*yx + m.wz*zx + m.ww*wx; |
257 |
xx = x; |
258 |
yx = y; |
259 |
zx = z; |
260 |
wx = w; |
261 |
|
262 |
x = m.xx*xy + m.xy*yy + m.xz*zy + m.xw*wy; |
263 |
y = m.yx*xy + m.yy*yy + m.yz*zy + m.yw*wy; |
264 |
z = m.zx*xy + m.zy*yy + m.zz*zy + m.zw*wy; |
265 |
w = m.wx*xy + m.wy*yy + m.wz*zy + m.ww*wy; |
266 |
xy = x; |
267 |
yy = y; |
268 |
zy = z; |
269 |
wy = w; |
270 |
|
271 |
x = m.xx*xz + m.xy*yz + m.xz*zz + m.xw*wz; |
272 |
y = m.yx*xz + m.yy*yz + m.yz*zz + m.yw*wz; |
273 |
z = m.zx*xz + m.zy*yz + m.zz*zz + m.zw*wz; |
274 |
w = m.wx*xz + m.wy*yz + m.wz*zz + m.ww*wz; |
275 |
xz = x; |
276 |
yz = y; |
277 |
zz = z; |
278 |
wz = w; |
279 |
|
280 |
x = m.xx*xw + m.xy*yw + m.xz*zw + m.xw*ww; |
281 |
y = m.yx*xw + m.yy*yw + m.yz*zw + m.yw*ww; |
282 |
z = m.zx*xw + m.zy*yw + m.zz*zw + m.zw*ww; |
283 |
w = m.wx*xw + m.wy*yw + m.wz*zw + m.ww*ww; |
284 |
xw = x; |
285 |
yw = y; |
286 |
zw = z; |
287 |
ww = w; |
288 |
} |
289 |
|
290 |
/**
|
291 |
* Translate the origin.
|
292 |
* @param x translation in x
|
293 |
* @param y translation in y
|
294 |
* @param z translation in z
|
295 |
*/
|
296 |
public void translate(double x, double y, double z) { |
297 |
xw += x*xx+y*xy+z*xz; |
298 |
yw += x*yx+y*yy+z*yz; |
299 |
zw += x*zx+y*zy+z*zz; |
300 |
ww += x*wx+y*wy+z*wz; |
301 |
} |
302 |
|
303 |
/**
|
304 |
* Translate the origin
|
305 |
* @param v translation vector
|
306 |
*/
|
307 |
public void translate(Vector3D v) { |
308 |
translate(v.x, v.y, v.z); |
309 |
} |
310 |
|
311 |
/**
|
312 |
* Translate.
|
313 |
* @param x translation in x
|
314 |
* @param y translation in y
|
315 |
* @param z translation in z
|
316 |
*/
|
317 |
public void translateLeft(double x, double y, double z) { |
318 |
if (x != 0f) { |
319 |
xx += x*wx; xy += x*wy; xz += x*wz; xw += x*ww; |
320 |
} |
321 |
if (y != 0f) { |
322 |
yx += y*wx; yy += y*wy; yz += y*wz; yw += y*ww; |
323 |
} |
324 |
if (z != 0f) { |
325 |
zx += z*wx; zy += z*wy; zz += z*wz; zw += z*ww; |
326 |
} |
327 |
} |
328 |
|
329 |
/**
|
330 |
* Translate the origin
|
331 |
* @param v tranbslation vector
|
332 |
*/
|
333 |
public void translateLeft(Vector3D v) { |
334 |
translateLeft(v.x, v.y, v.z); |
335 |
} |
336 |
|
337 |
|
338 |
/**
|
339 |
* Move the stuff.
|
340 |
* @param x translation in x
|
341 |
* @param y translation in y
|
342 |
* @param z translation in z
|
343 |
*/
|
344 |
public void moveBy(double x, double y, double z) { |
345 |
if (x != 0f) { |
346 |
xx += x*xw; yx += x*yw; zx += x*zw; wx += x*ww; |
347 |
} |
348 |
if (y != 0f) { |
349 |
xy += y*xw; yy += y*yw; zy += y*zw; wy += y*ww; |
350 |
} |
351 |
if (z != 0f) { |
352 |
xz += z*xw; yz += z*yw; zz += z*zw; wz += z*ww; |
353 |
} |
354 |
} |
355 |
|
356 |
/**
|
357 |
* Translate the origin
|
358 |
* @param v translation vector
|
359 |
*/
|
360 |
public void moveBy(Vector3D v) { |
361 |
moveBy(v.x, v.y, v.z); |
362 |
} |
363 |
|
364 |
|
365 |
/**
|
366 |
* Rotate theta degrees about the y axis.
|
367 |
* @param theta rotation angle in rad
|
368 |
*/
|
369 |
public void yrot(double theta) { |
370 |
if (theta == 0.0) { |
371 |
return;
|
372 |
} |
373 |
double ct = Math.cos(theta); |
374 |
double st = -Math.sin(theta); |
375 |
|
376 |
double Nx = (double) (xx * ct - zx * st); |
377 |
double Nz = (double) (xx * st + zx * ct); |
378 |
xx = Nx; |
379 |
zx = Nz; |
380 |
|
381 |
Nx = (double) (xy * ct - zy * st);
|
382 |
Nz = (double) (xy * st + zy * ct);
|
383 |
xy = Nx; |
384 |
zy = Nz; |
385 |
|
386 |
Nx = (double) (xz * ct - zz * st);
|
387 |
Nz = (double) (xz * st + zz * ct);
|
388 |
xz = Nx; |
389 |
zz = Nz; |
390 |
|
391 |
Nx = (double) (xw * ct - zw * st);
|
392 |
Nz = (double) (xw * st + zw * ct);
|
393 |
xw = Nx; |
394 |
zw = Nz; |
395 |
} |
396 |
|
397 |
/**
|
398 |
* Rotate theta degrees about the x axis.
|
399 |
* @param theta rotation angle in rad
|
400 |
*/
|
401 |
public void xrot(double theta) { |
402 |
if (theta == 0.0) { |
403 |
return;
|
404 |
} |
405 |
double ct = Math.cos(theta); |
406 |
double st = Math.sin(theta); |
407 |
|
408 |
double Ny = (double) (yx * ct - zx * st); |
409 |
double Nz = (double) (yx * st + zx * ct); |
410 |
yx = Ny; |
411 |
zx = Nz; |
412 |
|
413 |
Ny = (double) (yy * ct - zy * st);
|
414 |
Nz = (double) (yy * st + zy * ct);
|
415 |
yy = Ny; |
416 |
zy = Nz; |
417 |
|
418 |
Ny = (double) (yz * ct - zz * st);
|
419 |
Nz = (double) (yz * st + zz * ct);
|
420 |
yz = Ny; |
421 |
zz = Nz; |
422 |
|
423 |
Ny = (double) (yw * ct - zw * st);
|
424 |
Nz = (double) (yw * st + zw * ct);
|
425 |
yw = Ny; |
426 |
zw = Nz; |
427 |
} |
428 |
|
429 |
/**
|
430 |
* Rotate theta degrees about the z axis.
|
431 |
* @param theta rotation angle in rad
|
432 |
*/
|
433 |
public void zrot(double theta) { |
434 |
if (theta == 0.0) { |
435 |
return;
|
436 |
} |
437 |
double ct = Math.cos(theta); |
438 |
double st = Math.sin(theta); |
439 |
|
440 |
double Nx = (double) (xx * ct - yx * st); |
441 |
double Ny = (double) (xx * st + yx * ct); |
442 |
xx = Nx; |
443 |
yx = Ny; |
444 |
|
445 |
Nx = (double) (xy * ct - yy * st);
|
446 |
Ny = (double) (xy * st + yy * ct);
|
447 |
xy = Nx; |
448 |
yy = Ny; |
449 |
|
450 |
Nx = (double) (xz * ct - yz * st);
|
451 |
Ny = (double) (xz * st + yz * ct);
|
452 |
xz = Nx; |
453 |
yz = Ny; |
454 |
|
455 |
Nx = (double) (xw * ct - yw * st);
|
456 |
Ny = (double) (xw * st + yw * ct);
|
457 |
xw = Nx; |
458 |
yw = Ny; |
459 |
} |
460 |
|
461 |
/**
|
462 |
* Scale.
|
463 |
* @param f factor to scale with.
|
464 |
*/
|
465 |
public void scale(double f) { |
466 |
xx *= f; |
467 |
yx *= f; |
468 |
zx *= f; |
469 |
wx *= f; |
470 |
xy *= f; |
471 |
yy *= f; |
472 |
zy *= f; |
473 |
wy *= f; |
474 |
xz *= f; |
475 |
yz *= f; |
476 |
zz *= f; |
477 |
wz *= f; |
478 |
} |
479 |
|
480 |
/**
|
481 |
* Scale different in x,y,z.
|
482 |
* @param fx scaling factor in x
|
483 |
* @param fy scaling factor in y
|
484 |
* @param fz scaling factor in z
|
485 |
*/
|
486 |
public void scale(double fx, double fy, double fz) { |
487 |
xx *= fx; |
488 |
yx *= fx; |
489 |
zx *= fx; |
490 |
wx *= fx; |
491 |
xy *= fy; |
492 |
yy *= fy; |
493 |
zy *= fy; |
494 |
wy *= fy; |
495 |
xz *= fz; |
496 |
yz *= fz; |
497 |
zz *= fz; |
498 |
wz *= fz; |
499 |
} |
500 |
|
501 |
|
502 |
private static final double MIN_INT = (double)Short.MIN_VALUE; |
503 |
private static final double MAX_INT = (double)Short.MAX_VALUE; |
504 |
|
505 |
/**
|
506 |
* Transform some points.
|
507 |
* @param v points to transform
|
508 |
* @param tx transformed points x coord
|
509 |
* @param ty transformed points y coord
|
510 |
* @param tz transformed points z coord
|
511 |
* @param npoints nr of points to transform
|
512 |
*/
|
513 |
public void transform(Point3D v[], int tx[], int ty[], int tz[], int npoints) { |
514 |
Point3D tmp; |
515 |
|
516 |
for (int i = npoints; --i >= 0;) { |
517 |
tmp = mult(v[i]); |
518 |
|
519 |
if (tmp.x < MIN_INT) {
|
520 |
tmp.x = MIN_INT; |
521 |
} |
522 |
else if (tmp.x > MAX_INT) { |
523 |
tmp.x = MAX_INT; |
524 |
} |
525 |
if (tmp.y < MIN_INT) {
|
526 |
tmp.y = MIN_INT; |
527 |
} |
528 |
else if (tmp.y > MAX_INT) { |
529 |
tmp.y = MAX_INT; |
530 |
} |
531 |
if (tmp.z < MIN_INT) {
|
532 |
tmp.z = MIN_INT; |
533 |
} |
534 |
else if (tmp.z > MAX_INT) { |
535 |
tmp.z = MAX_INT; |
536 |
} |
537 |
|
538 |
tx[i] = (int) tmp.x;
|
539 |
ty[i] = (int) tmp.y;
|
540 |
tz[i] = (int) tmp.z;
|
541 |
} |
542 |
} |
543 |
|
544 |
/**
|
545 |
* Output
|
546 |
* @return String representing this.
|
547 |
*/
|
548 |
public String toString() { |
549 |
return new String(new StringBuffer().append("{{"). |
550 |
append(xx).append(",").append(xy).append(",").append(xz).append(",").append(xw). |
551 |
append("},{").
|
552 |
append(yx).append(",").append(yy).append(",").append(yz).append(",").append(yw). |
553 |
append("},{").
|
554 |
append(zx).append(",").append(zy).append(",").append(zz).append(",").append(zw). |
555 |
append("},{").
|
556 |
append(wx).append(",").append(wy).append(",").append(wz).append(",").append(ww). |
557 |
append("}}"));
|
558 |
} |
559 |
} |
560 |
|
561 |
|