Statistics
| Revision:

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