2 Copyright (C) 1997,1998,1999
3 Kenji Hiranabe, Eiwa System Management, Inc.
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.
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.
20 * A single precision floating point 4 by 4 matrix.
22 * @author Kenji hiranabe
24 * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
25 * constructor and method names for the optimization of compiled
26 * JavaScript using Java2Script
28 public class M4 extends M34 {
31 * The fourth element of the first row.
36 * The fourth element of the second row.
41 * The fourth element of the third row.
46 * The first element of the fourth row.
51 * The second element of the fourth row.
56 * The third element of the fourth row.
61 * The fourth element of the fourth row.
71 * Constructs and initializes a Matrix4f from the specified 16 element array.
72 * this.m00 =v[0], this.m01=v[1], etc.
75 * the array of length 16 containing in order
78 public static M4 newA16(float[] v) {
104 * Constructs a new matrix with the same values as the Matrix4f parameter.
110 public static M4 newM4(M4 m1) {
128 * Constructs and initializes a Matrix4f from the rotation matrix and
132 * The rotation matrix representing the rotational components
134 * The translational components of the matrix
137 public static M4 newMV(M3 m1, T3 t) {
144 * Sets this matrix to all zeros.
146 public void setZero() {
148 m03 = m13 = m23 = m30 = m31 = m32 = m33 = 0.0f;
152 * Sets this Matrix4f to identity.
154 public void setIdentity() {
156 m00 = m11 = m22 = m33 = 1.0f;
160 * Sets the value of this matrix to a copy of the passed matrix m1.
163 * the matrix to be copied
166 public M4 setM4(M4 m1) {
179 * Initializes a Matrix4f from the rotation matrix and translation.
182 * The rotation matrix representing the rotational components
184 * The translational components of the matrix
186 public void setMV(M3 m1, T3 t) {
193 * Sets the rotational component (upper 3x3) of this matrix to the matrix
194 * values in the single precision Matrix3f argument; the other elements of
195 * this matrix are initialized as if this were an identity matrix (ie, affine
196 * matrix with no translational component).
201 public void setToM3(M34 m1) {
203 m03 = m13 = m23 = m30 = m31 = m32 = 0.0f;
208 * Sets the rotational component (upper 3x3) of this matrix
209 * to a rotation given by an axis angle
212 * the axis and angle to be converted
214 public void setToAA(A4 a) {
220 * Sets the values in this Matrix4f equal to the row-major array parameter
221 * (ie, the first four elements of the array will be copied into the first row
222 * of this matrix, etc.).
226 public void setA(float m[]) {
246 * Modifies the translational components of this matrix to the values of the
247 * Vector3f argument; the other values of this matrix are not modified.
250 * the translational component
252 public void setTranslation(T3 trans) {
259 * Sets the specified element of this matrix4f to the value provided.
262 * the row number to be modified (zero indexed)
264 * the column number to be modified (zero indexed)
268 public void setElement(int row, int col, float v) {
269 if (row < 3 && col < 3) {
273 if (row > 3 || col > 3)
303 * Retrieves the value at the specified row and column of this matrix.
306 * the row number to be retrieved (zero indexed)
308 * the column number to be retrieved (zero indexed)
309 * @return the value at the indexed element
311 public float getElement(int row, int col) {
312 if (row < 3 && col < 3)
313 return get33(row, col);
314 if (row > 3 || col > 3) {
340 * Retrieves the translational components of this matrix.
343 * the vector that will receive the translational component
345 public void getTranslation(T3 trans) {
352 * Gets the upper 3x3 values of this matrix and places them into the matrix
356 * The matrix that will hold the values
358 public void getRotationScale(M3 m1) {
371 * Replaces the upper 3x3 matrix values of this matrix with the values in the
375 * The matrix that will be the new upper 3x3
377 public void setRotationScale(M3 m1) {
390 * Sets the specified row of this matrix4f to the four values provided.
393 * the row number to be modified (zero indexed)
395 * the replacement row
397 public void setRowA(int row, float v[]) {
421 * Copies the matrix values in the specified row into the array parameter.
426 * The array into which the matrix row values will be copied
429 public void getRow(int row, float v[]) {
453 * Sets the specified column of this matrix4f to the four values provided.
456 * the column number to be modified (zero indexed)
458 * the first row element
460 * the second row element
462 * the third row element
464 * the fourth row element
466 public void setColumn4(int column, float x, float y, float z, float w) {
472 } else if (column == 1) {
477 } else if (column == 2) {
482 } else if (column == 3) {
493 * Sets the specified column of this matrix4f to the four values provided.
496 * the column number to be modified (zero indexed)
498 * the replacement column
500 public void setColumnA(int column, float v[]) {
502 setColumn33(column, v);
525 * Copies the matrix values in the specified column into the array parameter.
530 * The array into which the matrix column values will be copied
532 public void getColumn(int column, float v[]) {
534 getColumn33(column, v);
557 * Sets the value of this matrix to the matrix difference of itself and matrix
558 * m1 (this = this - m1).
563 public void sub(M4 m1) {
575 * Sets the value of this matrix to its transpose.
577 public void transpose() {
593 * Sets the value of this matrix to its inverse.
597 float s = determinant4();
602 // less *,+,- calculation than expanded expression.
603 set(m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13
604 * (m21 * m32 - m22 * m31), m21 * (m02 * m33 - m03 * m32) + m22
605 * (m03 * m31 - m01 * m33) + m23 * (m01 * m32 - m02 * m31), m31
606 * (m02 * m13 - m03 * m12) + m32 * (m03 * m11 - m01 * m13) + m33
607 * (m01 * m12 - m02 * m11), m01 * (m13 * m22 - m12 * m23) + m02
608 * (m11 * m23 - m13 * m21) + m03 * (m12 * m21 - m11 * m22),
610 m12 * (m20 * m33 - m23 * m30) + m13 * (m22 * m30 - m20 * m32) + m10
611 * (m23 * m32 - m22 * m33), m22 * (m00 * m33 - m03 * m30) + m23
612 * (m02 * m30 - m00 * m32) + m20 * (m03 * m32 - m02 * m33), m32
613 * (m00 * m13 - m03 * m10) + m33 * (m02 * m10 - m00 * m12) + m30
614 * (m03 * m12 - m02 * m13), m02 * (m13 * m20 - m10 * m23) + m03
615 * (m10 * m22 - m12 * m20) + m00 * (m12 * m23 - m13 * m22),
617 m13 * (m20 * m31 - m21 * m30) + m10 * (m21 * m33 - m23 * m31) + m11
618 * (m23 * m30 - m20 * m33), m23 * (m00 * m31 - m01 * m30) + m20
619 * (m01 * m33 - m03 * m31) + m21 * (m03 * m30 - m00 * m33), m33
620 * (m00 * m11 - m01 * m10) + m30 * (m01 * m13 - m03 * m11) + m31
621 * (m03 * m10 - m00 * m13), m03 * (m11 * m20 - m10 * m21) + m00
622 * (m13 * m21 - m11 * m23) + m01 * (m10 * m23 - m13 * m20),
624 m10 * (m22 * m31 - m21 * m32) + m11 * (m20 * m32 - m22 * m30) + m12
625 * (m21 * m30 - m20 * m31), m20 * (m02 * m31 - m01 * m32) + m21
626 * (m00 * m32 - m02 * m30) + m22 * (m01 * m30 - m00 * m31), m30
627 * (m02 * m11 - m01 * m12) + m31 * (m00 * m12 - m02 * m10) + m32
628 * (m01 * m10 - m00 * m11), m00 * (m11 * m22 - m12 * m21) + m01
629 * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20));
654 private void set(float m00, float m01, float m02, float m03, float m10,
655 float m11, float m12, float m13, float m20, float m21,
656 float m22, float m23, float m30, float m31, float m32,
676 * Computes the determinant of this matrix.
678 * @return the determinant of the matrix
680 public float determinant4() {
681 // less *,+,- calculation than expanded expression.
682 return (m00 * m11 - m01 * m10) * (m22 * m33 - m23 * m32)
683 - (m00 * m12 - m02 * m10) * (m21 * m33 - m23 * m31)
684 + (m00 * m13 - m03 * m10) * (m21 * m32 - m22 * m31)
685 + (m01 * m12 - m02 * m11) * (m20 * m33 - m23 * m30)
686 - (m01 * m13 - m03 * m11) * (m20 * m32 - m22 * m30)
687 + (m02 * m13 - m03 * m12) * (m20 * m31 - m21 * m30);
692 * Multiplies each element of this matrix by a scalar.
695 * The scalar multiplier.
697 public void scale(float scalar) {
709 * Sets the value of this matrix to the result of multiplying itself with
715 public void mul(M4 m1) {
720 * Sets the value of this matrix to the result of multiplying the two argument
728 public void mul2(M4 m1, M4 m2) {
730 set(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30,
731 m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31,
732 m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32,
733 m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33,
735 m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30,
736 m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31,
737 m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32,
738 m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33,
740 m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30,
741 m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31,
742 m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32,
743 m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33,
745 m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30,
746 m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31,
747 m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32,
748 m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33);
752 * Transform the vector vec using this Matrix4f and place the result back into
756 * the single precision vector to be transformed
758 public void transform(T4 vec) {
759 transform2(vec, vec);
763 * Transform the vector vec using this Matrix4f and place the result into
767 * the single precision vector to be transformed
769 * the vector into which the transformed values are placed
771 public void transform2(T4 vec, T4 vecOut) {
773 vecOut.set4(m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, m10
774 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, m20 * vec.x + m21
775 * vec.y + m22 * vec.z + m23 * vec.w, m30 * vec.x + m31 * vec.y + m32
776 * vec.z + m33 * vec.w);
780 * Transforms the point parameter with this Matrix4f and places the result
781 * back into point. The fourth element of the point input parameter is assumed
785 * the input point to be transformed.
787 public void rotTrans(T3 point) {
788 rotTrans2(point, point);
792 * Transforms the point parameter with this Matrix4f and places the result
793 * into pointOut. The fourth element of the point input parameter is assumed to
794 * be one. point may be pointOut
797 * the input point to be transformed.
799 * the transformed point
802 public T3 rotTrans2(T3 point, T3 pointOut) {
804 m00 * point.x + m01 * point.y + m02 * point.z + m03,
805 m10 * point.x + m11 * point.y + m12 * point.z + m13,
806 m20 * point.x + m21 * point.y + m22 * point.z + m23);
811 * Sets the value of this matrix to a rotation matrix about the w axis by the
815 * the angle to rotate about the W axis in radians
818 public M4 setAsXYRotation(float angle) {
820 double c = Math.cos(angle);
821 double s = Math.sin(angle);
830 * Sets the value of this matrix to a rotation matrix about the w axis by the
834 * the angle to rotate about the W axis in radians
837 public M4 setAsYZRotation(float angle) {
839 double c = Math.cos(angle);
840 double s = Math.sin(angle);
849 * Sets the value of this matrix to a rotation matrix about the w axis by the
853 * the angle to rotate about the W axis in radians
856 public M4 setAsXZRotation(float angle) {
858 double c = Math.cos(angle);
859 double s = Math.sin(angle);
868 * Returns true if the Object o is of type Matrix4f and all of the data
869 * members of t1 are equal to the corresponding data members in this Matrix4f.
872 * the object with which the comparison is made.
875 public boolean equals(Object o) {
876 if (!(o instanceof M4))
879 return (this.m00 == m.m00 && this.m01 == m.m01 && this.m02 == m.m02
880 && this.m03 == m.m03 && this.m10 == m.m10 && this.m11 == m.m11
881 && this.m12 == m.m12 && this.m13 == m.m13 && this.m20 == m.m20
882 && this.m21 == m.m21 && this.m22 == m.m22 && this.m23 == m.m23
883 && this.m30 == m.m30 && this.m31 == m.m31 && this.m32 == m.m32 && this.m33 == m.m33);
887 * Returns a hash number based on the data values in this object. Two
888 * different Matrix4f objects with identical data values (ie, returns true for
889 * equals(Matrix4f) ) will return the same hash number. Two objects with
890 * different data members may return the same hash value, although this is not
893 * @return the integer hash value
896 public int hashCode() {
897 return T3.floatToIntBits(m00) ^ T3.floatToIntBits(m01)
898 ^ T3.floatToIntBits(m02) ^ T3.floatToIntBits(m03)
899 ^ T3.floatToIntBits(m10) ^ T3.floatToIntBits(m11)
900 ^ T3.floatToIntBits(m12) ^ T3.floatToIntBits(m13)
901 ^ T3.floatToIntBits(m20) ^ T3.floatToIntBits(m21)
902 ^ T3.floatToIntBits(m22) ^ T3.floatToIntBits(m23)
903 ^ T3.floatToIntBits(m30) ^ T3.floatToIntBits(m31)
904 ^ T3.floatToIntBits(m32) ^ T3.floatToIntBits(m33);
908 * Returns a string that contains the values of this Matrix4f.
910 * @return the String representation
913 public String toString() {
914 return "[\n [" + m00 + "\t" + m01 + "\t" + m02 + "\t" + m03 + "]"
915 + "\n [" + m10 + "\t" + m11 + "\t" + m12 + "\t" + m13 + "]" + "\n ["
916 + m20 + "\t" + m21 + "\t" + m22 + "\t" + m23 + "]" + "\n [" + m30
917 + "\t" + m31 + "\t" + m32 + "\t" + m33 + "] ]";
919 public M4 round(float f) {
939 private float rnd(float n, float f) {
940 return (Math.abs(n) < f ? 0 : n);