Merge branch 'Jalview-BH/JAL-3026-JAL-3063-JAXB' of
[jalview.git] / unused / javajs / util / M3.java
1 /*
2    Copyright (C) 1997,1998,1999
3    Kenji Hiranabe, Eiwa System Management, Inc.
4
5    This program is free software.
6    Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
7    conforming to the Java(TM) 3D API specification by Sun Microsystems.
8
9    Permission to use, copy, modify, distribute and sell this software
10    and its documentation for any purpose is hereby granted without fee,
11    provided that the above copyright notice appear in all copies and
12    that both that copyright notice and this permission notice appear
13    in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
14    makes no representations about the suitability of this software for any
15    purpose.  It is provided "AS IS" with NO WARRANTY.
16 */
17 package javajs.util;
18
19 import java.io.Serializable;
20
21
22
23 /**
24  * A single precision floating point 3 by 3 matrix.
25  * 
26  * @author Kenji hiranabe
27  * 
28  *         additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
29  *         constructor and method names for the optimization of compiled
30  *         JavaScript using Java2Script
31  *         
32  *         
33  */
34 public class M3 extends M34 implements Serializable {
35
36   /**
37    * Constructs and initializes a Matrix3f to all zeros.
38    */
39   public M3() {
40   }
41
42   /**
43    * Constructs and initializes a Matrix3f from the specified 9 element array.
44    * this.m00 =v[0], this.m01=v[1], etc.
45    * 
46    * @param v
47    *        the array of length 9 containing in order
48    * @return m
49    */
50   public static M3 newA9(float[] v) {
51     M3 m = new M3();
52     m.setA(v);
53     return m;
54   }
55   
56   /**
57    * Constructs a new matrix with the same values as the Matrix3f parameter.
58    * 
59    * @param m1
60    *        The source matrix.
61    * @return m
62    */
63   public static M3 newM3(M3 m1) {
64     M3 m = new M3();
65     if (m1 == null) {
66       m.setScale(1);
67       return m;
68     }
69     m.m00 = m1.m00;
70     m.m01 = m1.m01;
71     m.m02 = m1.m02;
72
73     m.m10 = m1.m10;
74     m.m11 = m1.m11;
75     m.m12 = m1.m12;
76
77     m.m20 = m1.m20;
78     m.m21 = m1.m21;
79     m.m22 = m1.m22;
80     return m;
81   }
82
83   /**
84    * Sets this Matrix3f to a scalar * Identity.
85    * @param scale 
86    */
87   public void setScale(float scale) {
88     clear33();
89     m00 = m11 = m22 = scale;
90   }
91
92   /**
93    * Sets the value of this matrix to the double value of the Matrix3f argument.
94    * 
95    * @param m1
96    *        the matrix3f
97    */
98   public void setM3(M34 m1) {
99     setM33(m1);
100   }
101   /**
102    * Sets the values in this Matrix3f equal to the row-major array parameter
103    * (ie, the first four elements of the array will be copied into the first row
104    * of this matrix, etc.).
105    * 
106    * @param m
107    */
108   public void setA(float m[]) {
109     m00 = m[0];
110     m01 = m[1];
111     m02 = m[2];
112     m10 = m[3];
113     m11 = m[4];
114     m12 = m[5];
115     m20 = m[6];
116     m21 = m[7];
117     m22 = m[8];
118   }
119
120   /**
121    * Sets the specified element of this matrix3d to the value provided.
122    * 
123    * @param row
124    *        the row number to be modified (zero indexed)
125    * @param col
126    *        the column number to be modified (zero indexed)
127    * @param v
128    *        the new value
129    */
130   public void setElement(int row, int col, float v) {
131     set33(row, col, v);
132   }
133
134   /**
135    * Retrieves the value at the specified row and column of this matrix.
136    * 
137    * @param row
138    *        the row number to be retrieved (zero indexed)
139    * @param col
140    *        the column number to be retrieved (zero indexed)
141    * @return the value at the indexed element
142    */
143   public float getElement(int row, int col) {
144     return get33(row, col);
145   }
146
147   /**
148    * Sets the specified row of this matrix3d to the three values provided.
149    * 
150    * @param row
151    *        the row number to be modified (zero indexed)
152    * @param x
153    *        the first column element
154    * @param y
155    *        the second column element
156    * @param z
157    *        the third column element
158    */
159   public void setRow(int row, float x, float y, float z) {
160     switch (row) {
161     case 0:
162       m00 = x;
163       m01 = y;
164       m02 = z;
165       return;
166     case 1:
167       m10 = x;
168       m11 = y;
169       m12 = z;
170       return;
171     case 2:
172       m20 = x;
173       m21 = y;
174       m22 = z;
175       return;
176     default:
177       err();
178     }
179   }
180
181   /**
182    * Sets the specified row of this matrix3d to the Vector provided.
183    * 
184    * @param row
185    *        the row number to be modified (zero indexed)
186    * @param v
187    *        the replacement row
188    */
189   public void setRowV(int row, T3 v) {
190     switch (row) {
191     case 0:
192       m00 = v.x;
193       m01 = v.y;
194       m02 = v.z;
195       return;
196     case 1:
197       m10 = v.x;
198       m11 = v.y;
199       m12 = v.z;
200       return;
201     case 2:
202       m20 = v.x;
203       m21 = v.y;
204       m22 = v.z;
205       return;
206     default:
207       err();
208     }
209   }
210
211   /**
212    * Sets the specified row of this matrix3d to the four values provided.
213    * 
214    * @param row
215    *        the row number to be modified (zero indexed)
216    * @param v
217    *        the replacement row
218    */
219   public void setRowA(int row, float v[]) {
220     setRow33(row, v);
221   }
222
223   /**
224    * Copies the matrix values in the specified row into the array parameter.
225    * 
226    * @param row
227    *        the matrix row
228    * @param v
229    *        The array into which the matrix row values will be copied
230    */
231   @Override
232   public void getRow(int row, float v[]) {
233     getRow33(row, v);
234   }
235
236   /**
237    * Sets the specified column of this matrix3d to the three values provided.
238    * 
239    * @param column
240    *        the column number to be modified (zero indexed)
241    * @param x
242    *        the first row element
243    * @param y
244    *        the second row element
245    * @param z
246    *        the third row element
247    */
248   public void setColumn3(int column, float x, float y, float z) {
249     switch (column) {
250     case 0:
251       m00 = x;
252       m10 = y;
253       m20 = z;
254       break;
255     case 1:
256       m01 = x;
257       m11 = y;
258       m21 = z;
259       break;
260     case 2:
261       m02 = x;
262       m12 = y;
263       m22 = z;
264       break;
265     default:
266       err();
267     }
268   }
269
270   /**
271    * Sets the specified column of this matrix3d to the vector provided.
272    * 
273    * @param column
274    *        the column number to be modified (zero indexed)
275    * @param v
276    *        the replacement column
277    */
278   public void setColumnV(int column, T3 v) {
279     switch (column) {
280     case 0:
281       m00 = v.x;
282       m10 = v.y;
283       m20 = v.z;
284       break;
285     case 1:
286       m01 = v.x;
287       m11 = v.y;
288       m21 = v.z;
289       break;
290     case 2:
291       m02 = v.x;
292       m12 = v.y;
293       m22 = v.z;
294       break;
295     default:
296       err();
297     }
298   }
299
300   /**
301    * Copies the matrix values in the specified column into the vector parameter.
302    * 
303    * @param column
304    *        the matrix column
305    * @param v
306    *        The vector into which the matrix row values will be copied
307    */
308   public void getColumnV(int column, T3 v) {
309     switch (column) {
310     case 0:
311       v.x = m00;
312       v.y = m10;
313       v.z = m20;
314       break;
315     case 1:
316       v.x = m01;
317       v.y = m11;
318       v.z = m21;
319       break;
320     case 2:
321       v.x = m02;
322       v.y = m12;
323       v.z = m22;
324       break;
325     default:
326       err();
327     }
328   }
329
330   /**
331    * Sets the specified column of this matrix3d to the four values provided.
332    * 
333    * @param column
334    *        the column number to be modified (zero indexed)
335    * @param v
336    *        the replacement column
337    */
338   public void setColumnA(int column, float v[]) {
339     setColumn33(column, v);
340   }
341
342   /**
343    * Copies the matrix values in the specified column into the array parameter.
344    * 
345    * @param column
346    *        the matrix column
347    * @param v
348    *        The array into which the matrix row values will be copied
349    */
350   public void getColumn(int column, float v[]) {
351     getColumn33(column, v);
352   }
353
354   /**
355    * Sets the value of this matrix to sum of itself and matrix m1.
356    * 
357    * @param m1
358    *        the other matrix
359    */
360   public void add(M3 m1) {
361     add33(m1);
362   }
363
364   /**
365    * Sets the value of this matrix to the matrix difference of itself and matrix
366    * m1 (this = this - m1).
367    * 
368    * @param m1
369    *        the other matrix
370    */
371   public void sub(M3 m1) {
372     sub33(m1);
373   }
374
375   /**
376    * Sets the value of this matrix to its transpose.
377    */
378   public void transpose() {
379     transpose33();
380   }
381
382   /**
383    * Sets the value of this matrix to the transpose of the argument matrix
384    * 
385    * @param m1
386    *        the matrix to be transposed
387    */
388   public void transposeM(M3 m1) {
389     // alias-safe
390     setM33(m1);
391     transpose33();
392   }
393
394   /**
395    * Sets the value of this matrix to the matrix inverse of the passed matrix
396    * m1.
397    * 
398    * @param m1
399    *        the matrix to be inverted
400    */
401   public void invertM(M3 m1) {
402     setM33(m1);
403     invert();
404   }
405
406   /**
407    * Sets the value of this matrix to its inverse.
408    */
409   public void invert() {
410     double s = determinant3();
411     if (s == 0.0)
412       return;
413     s = 1 / s;
414     // alias-safe way.
415     set9(m11 * m22 - m12 * m21, m02 * m21 - m01 * m22, m01 * m12 - m02 * m11,
416         m12 * m20 - m10 * m22, m00 * m22 - m02 * m20, m02 * m10 - m00 * m12,
417         m10 * m21 - m11 * m20, m01 * m20 - m00 * m21, m00 * m11 - m01 * m10);
418     scale((float) s);
419   }
420
421   /**
422    * Sets the value of this matrix to a rotation matrix about the x axis by the
423    * passed angle.
424    * 
425    * @param angle
426    *        the angle to rotate about the X axis in radians
427    * @return this
428    */
429   public M3 setAsXRotation(float angle) {
430     setXRot(angle);
431     return this;
432   }
433   
434   /**
435    * Sets the value of this matrix to a rotation matrix about the y axis by the
436    * passed angle.
437    * 
438    * @param angle
439    *        the angle to rotate about the Y axis in radians
440    * @return this
441    */
442   public M3 setAsYRotation(float angle) {
443     setYRot(angle);
444     return this;
445   }
446
447   /**
448    * Sets the value of this matrix to a rotation matrix about the z axis by the
449    * passed angle.
450    * 
451    * @param angle
452    *        the angle to rotate about the Z axis in radians
453    * @return this
454    */
455   public M3 setAsZRotation(float angle) {
456     setZRot(angle);
457     return this;
458   }
459
460   /**
461    * Multiplies each element of this matrix by a scalar.
462    * 
463    * @param scalar
464    *        The scalar multiplier.
465    */
466   public void scale(float scalar) {
467     mul33(scalar);
468   }
469
470   /**
471    * Sets the value of this matrix to the result of multiplying itself with
472    * matrix m1.
473    * 
474    * @param m1
475    *        the other matrix
476    */
477   public void mul(M3 m1) {
478     mul2(this, m1);
479   }
480
481   /**
482    * Sets the value of this matrix to the result of multiplying the two argument
483    * matrices together.
484    * 
485    * @param m1
486    *        the first matrix
487    * @param m2
488    *        the second matrix
489    */
490   public void mul2(M3 m1, M3 m2) {
491     // alias-safe way.
492     set9(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20, m1.m00 * m2.m01
493         + m1.m01 * m2.m11 + m1.m02 * m2.m21, m1.m00 * m2.m02 + m1.m01 * m2.m12
494         + m1.m02 * m2.m22,
495
496     m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20, m1.m10 * m2.m01
497         + m1.m11 * m2.m11 + m1.m12 * m2.m21, m1.m10 * m2.m02 + m1.m11 * m2.m12
498         + m1.m12 * m2.m22,
499
500     m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20, m1.m20 * m2.m01
501         + m1.m21 * m2.m11 + m1.m22 * m2.m21, m1.m20 * m2.m02 + m1.m21 * m2.m12
502         + m1.m22 * m2.m22);
503   }
504
505   /**
506    * Returns true if the Object o is of type Matrix3f and all of the data
507    * members of t1 are equal to the corresponding data members in this Matrix3f.
508    * 
509    * @param o
510    *        the object with which the comparison is made.
511    */
512   @Override
513   public boolean equals(Object o) {
514     if (!(o instanceof M3))
515       return false;
516     M3 m = (M3) o;
517     return m00 == m.m00 && m01 == m.m01 && m02 == m.m02 && m10 == m.m10
518         && m11 == m.m11 && m12 == m.m12 && m20 == m.m20 && m21 == m.m21
519         && m22 == m.m22;
520   }
521
522   /**
523    * Returns a hash number based on the data values in this object. Two
524    * different Matrix3f objects with identical data values (ie, returns true for
525    * equals(Matrix3f) ) will return the same hash number. Two objects with
526    * different data members may return the same hash value, although this is not
527    * likely.
528    * 
529    * @return the integer hash value
530    */
531   @Override
532   public int hashCode() {
533     return T3.floatToIntBits(m00) ^ T3.floatToIntBits(m01)
534         ^ T3.floatToIntBits(m02) ^ T3.floatToIntBits(m10)
535         ^ T3.floatToIntBits(m11) ^ T3.floatToIntBits(m12)
536         ^ T3.floatToIntBits(m20) ^ T3.floatToIntBits(m21)
537         ^ T3.floatToIntBits(m22);
538   }
539
540   /**
541    * Sets this matrix to all zeros.
542    */
543   public void setZero() {
544     clear33();
545   }
546
547   /**
548    * Sets 9 values
549    * 
550    * @param m00
551    * @param m01
552    * @param m02
553    * @param m10
554    * @param m11
555    * @param m12
556    * @param m20
557    * @param m21
558    * @param m22
559    */
560   private void set9(float m00, float m01, float m02, float m10, float m11,
561                    float m12, float m20, float m21, float m22) {
562     this.m00 = m00;
563     this.m01 = m01;
564     this.m02 = m02;
565     this.m10 = m10;
566     this.m11 = m11;
567     this.m12 = m12;
568     this.m20 = m20;
569     this.m21 = m21;
570     this.m22 = m22;
571   }
572
573   /**
574    * Returns a string that contains the values of this Matrix3f.
575    * 
576    * @return the String representation
577    */
578   @Override
579   public String toString() {
580     return "[\n  [" + m00 + "\t" + m01 + "\t" + m02 + "]" + "\n  [" + m10
581         + "\t" + m11 + "\t" + m12 + "]" + "\n  [" + m20 + "\t" + m21 + "\t"
582         + m22 + "] ]";
583   }
584
585   /**
586    * Sets the value of this matrix to the matrix conversion of the single
587    * precision axis and angle argument.
588    * 
589    * @param a
590    *        the axis and angle to be converted
591    * @return this
592    */
593   public M3 setAA(A4 a) {
594     setAA33(a);
595     return this;
596   }
597
598   /**
599    * 3D ball rotation from dx dy in-plane mouse motion
600    * adapted from Andrew Hanson
601    * Computer Graphics beyond the Third Dimension:
602    * Geometry, Orientation Control, and Rendering for
603    * Graphics in Dimensions Greater than Three
604    * Course Notes for SIGGRAPH ’98
605    * http://www.cse.ohio-state.edu/~hwshen/888_su02/hanson_note.pdf
606    * 
607    * @param responseFactor Jmol uses 0.02 here
608    * @param dx
609    * @param dy
610    * @return true if successful; false if not;
611    */
612   public boolean setAsBallRotation(float responseFactor, float dx, float dy) {
613     float r = (float) Math.sqrt(dx * dx + dy * dy);
614     float th =  r * responseFactor;
615     if (th == 0) {
616       setScale(1);
617       return false;
618     }
619     float c = (float) Math.cos(th);
620     float s = (float) Math.sin(th);
621     float nx = -dy / r;
622     float ny = dx / r;
623     float c1 = c - 1;
624     m00 = 1 + c1 * nx * nx;
625     m01 = m10 = c1 * nx * ny;
626     m20 = -(m02 = s * nx);
627     m11 = 1 + c1 * ny * ny;
628     m21 = -(m12 = s * ny);
629     m22 = c;
630     return true;
631   }
632
633   public boolean isRotation() {
634     return (Math.abs(determinant3() - 1) < 0.001f);
635   }
636
637 }