2 * $RCSfile: Matrix3f.java,v $
4 * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation. Sun designates this
10 * particular file as subject to the "Classpath" exception as provided
11 * by Sun in the LICENSE file that accompanied this code.
13 * This code is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * version 2 for more details (a copy is included in the LICENSE file that
17 * accompanied this code).
19 * You should have received a copy of the GNU General Public License version
20 * 2 along with this work; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24 * CA 95054 USA or visit www.sun.com if you need additional information or
28 * $Date: 2008/02/28 20:18:50 $
32 package javax.vecmath;
34 import java.lang.Math;
37 * A single precision floating point 3 by 3 matrix.
38 * Primarily to support 3D rotations.
41 public class Matrix3f implements java.io.Serializable, Cloneable {
43 // Compatible with 1.1
44 static final long serialVersionUID = 329697160112089834L;
47 * The first matrix element in the first row.
52 * The second matrix element in the first row.
57 * The third matrix element in the first row.
62 * The first matrix element in the second row.
67 * The second matrix element in the second row.
72 * The third matrix element in the second row.
77 * The first matrix element in the third row.
82 * The second matrix element in the third row.
87 * The third matrix element in the third row.
91 double[] tmp = new double[9]; // scratch matrix
92 double[] tmp_rot = new double[9]; // scratch matrix
93 double[] tmp_scale = new double[3]; // scratch matrix
95 private static final double EPS = 1.0E-8;
100 * Constructs and initializes a Matrix3f from the specified nine values.
101 * @param m00 the [0][0] element
102 * @param m01 the [0][1] element
103 * @param m02 the [0][2] element
104 * @param m10 the [1][0] element
105 * @param m11 the [1][1] element
106 * @param m12 the [1][2] element
107 * @param m20 the [2][0] element
108 * @param m21 the [2][1] element
109 * @param m22 the [2][2] element
111 public Matrix3f(float m00, float m01, float m02,
112 float m10, float m11, float m12,
113 float m20, float m21, float m22)
130 * Constructs and initializes a Matrix3f from the specified
131 * nine-element array. this.m00 =v[0], this.m01=v[1], etc.
132 * @param v the array of length 9 containing in order
134 public Matrix3f(float[] v)
151 * Constructs a new matrix with the same values as the
152 * Matrix3d parameter.
153 * @param m1 the source matrix
155 public Matrix3f(Matrix3d m1)
157 this.m00 = (float)m1.m00;
158 this.m01 = (float)m1.m01;
159 this.m02 = (float)m1.m02;
161 this.m10 = (float)m1.m10;
162 this.m11 = (float)m1.m11;
163 this.m12 = (float)m1.m12;
165 this.m20 = (float)m1.m20;
166 this.m21 = (float)m1.m21;
167 this.m22 = (float)m1.m22;
173 * Constructs a new matrix with the same values as the
174 * Matrix3f parameter.
175 * @param m1 the source matrix
177 public Matrix3f(Matrix3f m1)
195 * Constructs and initializes a Matrix3f to all zeros.
199 this.m00 = (float) 0.0;
200 this.m01 = (float) 0.0;
201 this.m02 = (float) 0.0;
203 this.m10 = (float) 0.0;
204 this.m11 = (float) 0.0;
205 this.m12 = (float) 0.0;
207 this.m20 = (float) 0.0;
208 this.m21 = (float) 0.0;
209 this.m22 = (float) 0.0;
214 * Returns a string that contains the values of this Matrix3f.
215 * @return the String representation
217 public String toString() {
219 this.m00 + ", " + this.m01 + ", " + this.m02 + "\n" +
220 this.m10 + ", " + this.m11 + ", " + this.m12 + "\n" +
221 this.m20 + ", " + this.m21 + ", " + this.m22 + "\n";
225 * Sets this Matrix3f to identity.
227 public final void setIdentity()
229 this.m00 = (float) 1.0;
230 this.m01 = (float) 0.0;
231 this.m02 = (float) 0.0;
233 this.m10 = (float) 0.0;
234 this.m11 = (float) 1.0;
235 this.m12 = (float) 0.0;
237 this.m20 = (float) 0.0;
238 this.m21 = (float) 0.0;
239 this.m22 = (float) 1.0;
243 * Sets the scale component of the current matrix by factoring
244 * out the current scale (by doing an SVD) and multiplying by
246 * @param scale the new scale amount
248 public final void setScale(float scale)
250 double[] tmp_rot = new double[9]; // scratch matrix
251 double[] tmp_scale = new double[3]; // scratch matrix
253 getScaleRotate( tmp_scale, tmp_rot );
255 this.m00 = (float)(tmp_rot[0] * scale);
256 this.m01 = (float)(tmp_rot[1] * scale);
257 this.m02 = (float)(tmp_rot[2] * scale);
259 this.m10 = (float)(tmp_rot[3] * scale);
260 this.m11 = (float)(tmp_rot[4] * scale);
261 this.m12 = (float)(tmp_rot[5] * scale);
263 this.m20 = (float)(tmp_rot[6] * scale);
264 this.m21 = (float)(tmp_rot[7] * scale);
265 this.m22 = (float)(tmp_rot[8] * scale);
270 * Sets the specified element of this matrix3f to the value provided.
271 * @param row the row number to be modified (zero indexed)
272 * @param column the column number to be modified (zero indexed)
273 * @param value the new value
275 public final void setElement(int row, int column, float value)
292 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
309 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
327 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
332 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
337 * Copies the matrix values in the specified row into the vector parameter.
338 * @param row the matrix row
339 * @param v the vector into which the matrix row values will be copied
341 public final void getRow(int row, Vector3f v) {
346 } else if(row == 1) {
350 } else if(row == 2) {
355 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f1"));
361 * Copies the matrix values in the specified row into the array parameter.
362 * @param row the matrix row
363 * @param v the array into which the matrix row values will be copied
365 public final void getRow(int row, float v[]) {
370 } else if(row == 1) {
374 } else if(row == 2) {
379 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f1"));
385 * Copies the matrix values in the specified column into the vector
387 * @param column the matrix column
388 * @param v the vector into which the matrix row values will be copied
390 public final void getColumn(int column, Vector3f v) {
395 } else if(column == 1) {
399 }else if(column == 2){
404 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f3"));
410 * Copies the matrix values in the specified column into the array
412 * @param column the matrix column
413 * @param v the array into which the matrix row values will be copied
415 public final void getColumn(int column, float v[]) {
420 } else if(column == 1) {
424 }else if(column == 2) {
429 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f3"));
434 * Retrieves the value at the specified row and column of this
436 * @param row the row number to be retrieved (zero indexed)
437 * @param column the column number to be retrieved (zero indexed)
438 * @return the value at the indexed element.
440 public final float getElement(int row, int column)
488 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f5"));
492 * Sets the specified row of this matrix3f to the three values provided.
493 * @param row the row number to be modified (zero indexed)
494 * @param x the first column element
495 * @param y the second column element
496 * @param z the third column element
498 public final void setRow(int row, float x, float y, float z)
520 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
525 * Sets the specified row of this matrix3f to the Vector provided.
526 * @param row the row number to be modified (zero indexed)
527 * @param v the replacement row
529 public final void setRow(int row, Vector3f v)
551 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
556 * Sets the specified row of this matrix3f to the three values provided.
557 * @param row the row number to be modified (zero indexed)
558 * @param v the replacement row
560 public final void setRow(int row, float v[])
582 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
587 * Sets the specified column of this matrix3f to the three values provided.
588 * @param column the column number to be modified (zero indexed)
589 * @param x the first row element
590 * @param y the second row element
591 * @param z the third row element
593 public final void setColumn(int column, float x, float y, float z)
615 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
620 * Sets the specified column of this matrix3f to the vector provided.
621 * @param column the column number to be modified (zero indexed)
622 * @param v the replacement column
624 public final void setColumn(int column, Vector3f v)
646 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
651 * Sets the specified column of this matrix3f to the three values provided.
652 * @param column the column number to be modified (zero indexed)
653 * @param v the replacement column
655 public final void setColumn(int column, float v[])
677 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
682 * Performs an SVD normalization of this matrix to calculate
683 * and return the uniform scale factor. If the matrix has non-uniform
684 * scale factors, the largest of the x, y, and z scale factors will
685 * be returned. This matrix is not modified.
686 * @return the scale factor of this matrix
688 public final float getScale()
691 double[] tmp_rot = new double[9]; // scratch matrix
692 double[] tmp_scale = new double[3]; // scratch matrix
693 getScaleRotate(tmp_scale, tmp_rot);
695 return( (float)Matrix3d.max3(tmp_scale ));
700 * Adds a scalar to each component of this matrix.
701 * @param scalar the scalar adder
703 public final void add(float scalar)
717 * Adds a scalar to each component of the matrix m1 and places
718 * the result into this. Matrix m1 is not modified.
719 * @param scalar the scalar adder.
720 * @param m1 the original matrix values
722 public final void add(float scalar, Matrix3f m1)
724 this.m00 = m1.m00 + scalar;
725 this.m01 = m1.m01 + scalar;
726 this.m02 = m1.m02 + scalar;
727 this.m10 = m1.m10 + scalar;
728 this.m11 = m1.m11 + scalar;
729 this.m12 = m1.m12 + scalar;
730 this.m20 = m1.m20 + scalar;
731 this.m21 = m1.m21 + scalar;
732 this.m22 = m1.m22 + scalar;
736 * Sets the value of this matrix to the matrix sum of matrices m1 and m2.
737 * @param m1 the first matrix
738 * @param m2 the second matrix
740 public final void add(Matrix3f m1, Matrix3f m2)
742 this.m00 = m1.m00 + m2.m00;
743 this.m01 = m1.m01 + m2.m01;
744 this.m02 = m1.m02 + m2.m02;
746 this.m10 = m1.m10 + m2.m10;
747 this.m11 = m1.m11 + m2.m11;
748 this.m12 = m1.m12 + m2.m12;
750 this.m20 = m1.m20 + m2.m20;
751 this.m21 = m1.m21 + m2.m21;
752 this.m22 = m1.m22 + m2.m22;
756 * Sets the value of this matrix to the matrix sum of itself and
758 * @param m1 the other matrix
760 public final void add(Matrix3f m1)
776 * Sets the value of this matrix to the matrix difference
777 * of matrices m1 and m2.
778 * @param m1 the first matrix
779 * @param m2 the second matrix
781 public final void sub(Matrix3f m1, Matrix3f m2)
783 this.m00 = m1.m00 - m2.m00;
784 this.m01 = m1.m01 - m2.m01;
785 this.m02 = m1.m02 - m2.m02;
787 this.m10 = m1.m10 - m2.m10;
788 this.m11 = m1.m11 - m2.m11;
789 this.m12 = m1.m12 - m2.m12;
791 this.m20 = m1.m20 - m2.m20;
792 this.m21 = m1.m21 - m2.m21;
793 this.m22 = m1.m22 - m2.m22;
797 * Sets the value of this matrix to the matrix difference
798 * of itself and matrix m1 (this = this - m1).
799 * @param m1 the other matrix
801 public final void sub(Matrix3f m1)
817 * Sets the value of this matrix to its transpose.
819 public final void transpose()
837 * Sets the value of this matrix to the transpose of the argument matrix.
838 * @param m1 the matrix to be transposed
840 public final void transpose(Matrix3f m1)
859 * Sets the value of this matrix to the matrix conversion of the
860 * (single precision) quaternion argument.
861 * @param q1 the quaternion to be converted
863 public final void set(Quat4f q1)
865 this.m00 = 1.0f - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z;
866 this.m10 = 2.0f*(q1.x*q1.y + q1.w*q1.z);
867 this.m20 = 2.0f*(q1.x*q1.z - q1.w*q1.y);
869 this.m01 = 2.0f*(q1.x*q1.y - q1.w*q1.z);
870 this.m11 = 1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z;
871 this.m21 = 2.0f*(q1.y*q1.z + q1.w*q1.x);
873 this.m02 = 2.0f*(q1.x*q1.z + q1.w*q1.y);
874 this.m12 = 2.0f*(q1.y*q1.z - q1.w*q1.x);
875 this.m22 = 1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y;
879 * Sets the value of this matrix to the matrix conversion of the
880 * (single precision) axis and angle argument.
881 * @param a1 the axis and angle to be converted
883 public final void set(AxisAngle4f a1)
885 float mag = (float)Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
904 float sinTheta = (float)Math.sin((float)a1.angle);
905 float cosTheta = (float)Math.cos((float)a1.angle);
906 float t = (float)1.0 - cosTheta;
912 m00 = t * ax * ax + cosTheta;
913 m01 = t * xy - sinTheta * az;
914 m02 = t * xz + sinTheta * ay;
916 m10 = t * xy + sinTheta * az;
917 m11 = t * ay * ay + cosTheta;
918 m12 = t * yz - sinTheta * ax;
920 m20 = t * xz - sinTheta * ay;
921 m21 = t * yz + sinTheta * ax;
922 m22 = t * az * az + cosTheta;
928 * Sets the value of this matrix to the matrix conversion of the
929 * (double precision) axis and angle argument.
930 * @param a1 the axis and angle to be converted
932 public final void set(AxisAngle4d a1)
934 double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
949 double ax = a1.x*mag;
950 double ay = a1.y*mag;
951 double az = a1.z*mag;
953 double sinTheta = Math.sin(a1.angle);
954 double cosTheta = Math.cos(a1.angle);
955 double t = 1.0 - cosTheta;
961 m00 = (float)(t * ax * ax + cosTheta);
962 m01 = (float)(t * xy - sinTheta * az);
963 m02 = (float)(t * xz + sinTheta * ay);
965 m10 = (float)(t * xy + sinTheta * az);
966 m11 = (float)(t * ay * ay + cosTheta);
967 m12 = (float)(t * yz - sinTheta * ax);
969 m20 = (float)(t * xz - sinTheta * ay);
970 m21 = (float)(t * yz + sinTheta * ax);
971 m22 = (float)(t * az * az + cosTheta);
977 * Sets the value of this matrix to the matrix conversion of the
978 * (single precision) quaternion argument.
979 * @param q1 the quaternion to be converted
981 public final void set(Quat4d q1)
983 this.m00 = (float) (1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
984 this.m10 = (float) (2.0*(q1.x*q1.y + q1.w*q1.z));
985 this.m20 = (float) (2.0*(q1.x*q1.z - q1.w*q1.y));
987 this.m01 = (float) (2.0*(q1.x*q1.y - q1.w*q1.z));
988 this.m11 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
989 this.m21 = (float) (2.0*(q1.y*q1.z + q1.w*q1.x));
991 this.m02 = (float) (2.0*(q1.x*q1.z + q1.w*q1.y));
992 this.m12 = (float) (2.0*(q1.y*q1.z - q1.w*q1.x));
993 this.m22 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
997 * Sets the values in this Matrix3f equal to the row-major
998 * array parameter (ie, the first three elements of the
999 * array will be copied into the first row of this matrix, etc.).
1000 * @param m the single precision array of length 9
1002 public final void set(float[] m)
1020 * Sets the value of this matrix to the value of the Matrix3f
1022 * @param m1 the source matrix3f
1024 public final void set(Matrix3f m1) {
1042 * Sets the value of this matrix to the float value of the Matrix3d
1044 * @param m1 the source matrix3d
1046 public final void set(Matrix3d m1) {
1048 this.m00 = (float)m1.m00;
1049 this.m01 = (float)m1.m01;
1050 this.m02 = (float)m1.m02;
1052 this.m10 = (float)m1.m10;
1053 this.m11 = (float)m1.m11;
1054 this.m12 = (float)m1.m12;
1056 this.m20 = (float)m1.m20;
1057 this.m21 = (float)m1.m21;
1058 this.m22 = (float)m1.m22;
1064 * Sets the value of this matrix to the matrix inverse
1065 * of the passed matrix m1.
1066 * @param m1 the matrix to be inverted
1068 public final void invert(Matrix3f m1)
1074 * Inverts this matrix in place.
1076 public final void invert()
1078 invertGeneral( this );
1082 * General invert routine. Inverts m1 and places the result in "this".
1083 * Note that this routine handles both the "this" version and the
1084 * non-"this" version.
1086 * Also note that since this routine is slow anyway, we won't worry
1087 * about allocating a little bit of garbage.
1089 private final void invertGeneral(Matrix3f m1) {
1090 double temp[] = new double[9];
1091 double result[] = new double[9];
1092 int row_perm[] = new int[3];
1095 // Use LU decomposition and backsubstitution code specifically
1096 // for floating-point 3x3 matrices.
1098 // Copy source matrix to t1tmp
1099 temp[0] = (double)m1.m00;
1100 temp[1] = (double)m1.m01;
1101 temp[2] = (double)m1.m02;
1103 temp[3] = (double)m1.m10;
1104 temp[4] = (double)m1.m11;
1105 temp[5] = (double)m1.m12;
1107 temp[6] = (double)m1.m20;
1108 temp[7] = (double)m1.m21;
1109 temp[8] = (double)m1.m22;
1112 // Calculate LU decomposition: Is the matrix singular?
1113 if (!luDecomposition(temp, row_perm)) {
1114 // Matrix has no inverse
1115 throw new SingularMatrixException(VecMathI18N.getString("Matrix3f12"));
1118 // Perform back substitution on the identity matrix
1119 for(i=0;i<9;i++) result[i] = 0.0;
1120 result[0] = 1.0; result[4] = 1.0; result[8] = 1.0;
1121 luBacksubstitution(temp, row_perm, result);
1123 this.m00 = (float)result[0];
1124 this.m01 = (float)result[1];
1125 this.m02 = (float)result[2];
1127 this.m10 = (float)result[3];
1128 this.m11 = (float)result[4];
1129 this.m12 = (float)result[5];
1131 this.m20 = (float)result[6];
1132 this.m21 = (float)result[7];
1133 this.m22 = (float)result[8];
1138 * Given a 3x3 array "matrix0", this function replaces it with the
1139 * LU decomposition of a row-wise permutation of itself. The input
1140 * parameters are "matrix0" and "dimen". The array "matrix0" is also
1141 * an output parameter. The vector "row_perm[3]" is an output
1142 * parameter that contains the row permutations resulting from partial
1143 * pivoting. The output parameter "even_row_xchg" is 1 when the
1144 * number of row exchanges is even, or -1 otherwise. Assumes data
1145 * type is always double.
1147 * This function is similar to luDecomposition, except that it
1148 * is tuned specifically for 3x3 matrices.
1150 * @return true if the matrix is nonsingular, or false otherwise.
1153 // Reference: Press, Flannery, Teukolsky, Vetterling,
1154 // _Numerical_Recipes_in_C_, Cambridge University Press,
1157 static boolean luDecomposition(double[] matrix0,
1160 double row_scale[] = new double[3];
1162 // Determine implicit scaling information by looping over rows
1176 // For each column, find the largest element in the row
1179 temp = matrix0[ptr++];
1180 temp = Math.abs(temp);
1186 // Is the matrix singular?
1190 row_scale[rs++] = 1.0 / big;
1200 // For all columns, execute Crout's method
1201 for (j = 0; j < 3; j++) {
1204 double sum, big, temp;
1206 // Determine elements of upper diagonal matrix U
1207 for (i = 0; i < j; i++) {
1208 target = mtx + (3*i) + j;
1209 sum = matrix0[target];
1214 sum -= matrix0[p1] * matrix0[p2];
1218 matrix0[target] = sum;
1221 // Search for largest pivot element and calculate
1222 // intermediate elements of lower diagonal matrix L.
1225 for (i = j; i < 3; i++) {
1226 target = mtx + (3*i) + j;
1227 sum = matrix0[target];
1232 sum -= matrix0[p1] * matrix0[p2];
1236 matrix0[target] = sum;
1238 // Is this the best pivot so far?
1239 if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
1246 throw new RuntimeException(VecMathI18N.getString("Matrix3f13"));
1249 // Is a row exchange necessary?
1251 // Yes: exchange rows
1253 p1 = mtx + (3*imax);
1257 matrix0[p1++] = matrix0[p2];
1258 matrix0[p2++] = temp;
1261 // Record change in scale factor
1262 row_scale[imax] = row_scale[j];
1265 // Record row permutation
1268 // Is the matrix singular
1269 if (matrix0[(mtx + (3*j) + j)] == 0.0) {
1273 // Divide elements of lower diagonal matrix L by pivot
1275 temp = 1.0 / (matrix0[(mtx + (3*j) + j)]);
1276 target = mtx + (3*(j+1)) + j;
1279 matrix0[target] *= temp;
1290 * Solves a set of linear equations. The input parameters "matrix1",
1291 * and "row_perm" come from luDecompostionD3x3 and do not change
1292 * here. The parameter "matrix2" is a set of column vectors assembled
1293 * into a 3x3 matrix of floating-point values. The procedure takes each
1294 * column of "matrix2" in turn and treats it as the right-hand side of the
1295 * matrix equation Ax = LUx = b. The solution vector replaces the
1296 * original column of the matrix.
1298 * If "matrix2" is the identity matrix, the procedure replaces its contents
1299 * with the inverse of the matrix from which "matrix1" was originally
1303 // Reference: Press, Flannery, Teukolsky, Vetterling,
1304 // _Numerical_Recipes_in_C_, Cambridge University Press,
1307 static void luBacksubstitution(double[] matrix1,
1311 int i, ii, ip, j, k;
1318 // For each column vector of matrix2 ...
1319 for (k = 0; k < 3; k++) {
1320 // cv = &(matrix2[0][k]);
1324 // Forward substitution
1325 for (i = 0; i < 3; i++) {
1328 ip = row_perm[rp+i];
1329 sum = matrix2[cv+3*ip];
1330 matrix2[cv+3*ip] = matrix2[cv+3*i];
1332 // rv = &(matrix1[i][0]);
1334 for (j = ii; j <= i-1; j++) {
1335 sum -= matrix1[rv+j] * matrix2[cv+3*j];
1338 else if (sum != 0.0) {
1341 matrix2[cv+3*i] = sum;
1345 // rv = &(matrix1[3][0]);
1347 matrix2[cv+3*2] /= matrix1[rv+2];
1350 matrix2[cv+3*1] = (matrix2[cv+3*1] -
1351 matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+1];
1354 matrix2[cv+4*0] = (matrix2[cv+3*0] -
1355 matrix1[rv+1] * matrix2[cv+3*1] -
1356 matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+0];
1361 * Computes the determinant of this matrix.
1362 * @return the determinant of this matrix
1364 public final float determinant()
1367 total = this.m00*(this.m11*this.m22 - this.m12*this.m21)
1368 + this.m01*(this.m12*this.m20 - this.m10*this.m22)
1369 + this.m02*(this.m10*this.m21 - this.m11*this.m20);
1374 * Sets the value of this matrix to a scale matrix with
1375 * the passed scale amount.
1376 * @param scale the scale factor for the matrix
1378 public final void set(float scale)
1381 this.m01 = (float) 0.0;
1382 this.m02 = (float) 0.0;
1384 this.m10 = (float) 0.0;
1386 this.m12 = (float) 0.0;
1388 this.m20 = (float) 0.0;
1389 this.m21 = (float) 0.0;
1394 * Sets the value of this matrix to a counter clockwise rotation
1396 * @param angle the angle to rotate about the X axis in radians
1398 public final void rotX(float angle)
1400 float sinAngle, cosAngle;
1402 sinAngle = (float) Math.sin((double) angle);
1403 cosAngle = (float) Math.cos((double) angle);
1405 this.m00 = (float) 1.0;
1406 this.m01 = (float) 0.0;
1407 this.m02 = (float) 0.0;
1409 this.m10 = (float) 0.0;
1410 this.m11 = cosAngle;
1411 this.m12 = -sinAngle;
1413 this.m20 = (float) 0.0;
1414 this.m21 = sinAngle;
1415 this.m22 = cosAngle;
1419 * Sets the value of this matrix to a counter clockwise rotation
1421 * @param angle the angle to rotate about the Y axis in radians
1423 public final void rotY(float angle)
1425 float sinAngle, cosAngle;
1427 sinAngle = (float) Math.sin((double) angle);
1428 cosAngle = (float) Math.cos((double) angle);
1430 this.m00 = cosAngle;
1431 this.m01 = (float) 0.0;
1432 this.m02 = sinAngle;
1434 this.m10 = (float) 0.0;
1435 this.m11 = (float) 1.0;
1436 this.m12 = (float) 0.0;
1438 this.m20 = -sinAngle;
1439 this.m21 = (float) 0.0;
1440 this.m22 = cosAngle;
1444 * Sets the value of this matrix to a counter clockwise rotation
1446 * @param angle the angle to rotate about the Z axis in radians
1448 public final void rotZ(float angle)
1450 float sinAngle, cosAngle;
1452 sinAngle = (float) Math.sin((double) angle);
1453 cosAngle = (float) Math.cos((double) angle);
1455 this.m00 = cosAngle;
1456 this.m01 = -sinAngle;
1457 this.m02 = (float) 0.0;
1459 this.m10 = sinAngle;
1460 this.m11 = cosAngle;
1461 this.m12 = (float) 0.0;
1463 this.m20 = (float) 0.0;
1464 this.m21 = (float) 0.0;
1465 this.m22 = (float) 1.0;
1469 * Multiplies each element of this matrix by a scalar.
1470 * @param scalar the scalar multiplier
1472 public final void mul(float scalar)
1488 * Multiplies each element of matrix m1 by a scalar and places
1489 * the result into this. Matrix m1 is not modified.
1490 * @param scalar the scalar multiplier
1491 * @param m1 the original matrix
1493 public final void mul(float scalar, Matrix3f m1)
1495 this.m00 = scalar * m1.m00;
1496 this.m01 = scalar * m1.m01;
1497 this.m02 = scalar * m1.m02;
1499 this.m10 = scalar * m1.m10;
1500 this.m11 = scalar * m1.m11;
1501 this.m12 = scalar * m1.m12;
1503 this.m20 = scalar * m1.m20;
1504 this.m21 = scalar * m1.m21;
1505 this.m22 = scalar * m1.m22;
1510 * Sets the value of this matrix to the result of multiplying itself
1512 * @param m1 the other matrix
1514 public final void mul(Matrix3f m1)
1516 float m00, m01, m02,
1520 m00 = this.m00*m1.m00 + this.m01*m1.m10 + this.m02*m1.m20;
1521 m01 = this.m00*m1.m01 + this.m01*m1.m11 + this.m02*m1.m21;
1522 m02 = this.m00*m1.m02 + this.m01*m1.m12 + this.m02*m1.m22;
1524 m10 = this.m10*m1.m00 + this.m11*m1.m10 + this.m12*m1.m20;
1525 m11 = this.m10*m1.m01 + this.m11*m1.m11 + this.m12*m1.m21;
1526 m12 = this.m10*m1.m02 + this.m11*m1.m12 + this.m12*m1.m22;
1528 m20 = this.m20*m1.m00 + this.m21*m1.m10 + this.m22*m1.m20;
1529 m21 = this.m20*m1.m01 + this.m21*m1.m11 + this.m22*m1.m21;
1530 m22 = this.m20*m1.m02 + this.m21*m1.m12 + this.m22*m1.m22;
1532 this.m00 = m00; this.m01 = m01; this.m02 = m02;
1533 this.m10 = m10; this.m11 = m11; this.m12 = m12;
1534 this.m20 = m20; this.m21 = m21; this.m22 = m22;
1538 * Sets the value of this matrix to the result of multiplying
1539 * the two argument matrices together.
1540 * @param m1 the first matrix
1541 * @param m2 the second matrix
1543 public final void mul(Matrix3f m1, Matrix3f m2)
1545 if (this != m1 && this != m2) {
1546 this.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
1547 this.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
1548 this.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
1550 this.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
1551 this.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
1552 this.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
1554 this.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
1555 this.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
1556 this.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
1558 float m00, m01, m02,
1562 m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
1563 m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
1564 m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
1566 m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
1567 m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
1568 m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
1570 m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
1571 m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
1572 m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
1574 this.m00 = m00; this.m01 = m01; this.m02 = m02;
1575 this.m10 = m10; this.m11 = m11; this.m12 = m12;
1576 this.m20 = m20; this.m21 = m21; this.m22 = m22;
1581 * Multiplies this matrix by matrix m1, does an SVD normalization
1582 * of the result, and places the result back into this matrix.
1583 * this = SVDnorm(this*m1).
1584 * @param m1 the matrix on the right hand side of the multiplication
1586 public final void mulNormalize(Matrix3f m1){
1588 double[] tmp = new double[9]; // scratch matrix
1589 double[] tmp_rot = new double[9]; // scratch matrix
1590 double[] tmp_scale = new double[3]; // scratch matrix
1592 tmp[0] = this.m00*m1.m00 + this.m01*m1.m10 + this.m02*m1.m20;
1593 tmp[1] = this.m00*m1.m01 + this.m01*m1.m11 + this.m02*m1.m21;
1594 tmp[2] = this.m00*m1.m02 + this.m01*m1.m12 + this.m02*m1.m22;
1596 tmp[3] = this.m10*m1.m00 + this.m11*m1.m10 + this.m12*m1.m20;
1597 tmp[4] = this.m10*m1.m01 + this.m11*m1.m11 + this.m12*m1.m21;
1598 tmp[5] = this.m10*m1.m02 + this.m11*m1.m12 + this.m12*m1.m22;
1600 tmp[6] = this.m20*m1.m00 + this.m21*m1.m10 + this.m22*m1.m20;
1601 tmp[7] = this.m20*m1.m01 + this.m21*m1.m11 + this.m22*m1.m21;
1602 tmp[8] = this.m20*m1.m02 + this.m21*m1.m12 + this.m22*m1.m22;
1604 Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot);
1606 this.m00 = (float)(tmp_rot[0]);
1607 this.m01 = (float)(tmp_rot[1]);
1608 this.m02 = (float)(tmp_rot[2]);
1610 this.m10 = (float)(tmp_rot[3]);
1611 this.m11 = (float)(tmp_rot[4]);
1612 this.m12 = (float)(tmp_rot[5]);
1614 this.m20 = (float)(tmp_rot[6]);
1615 this.m21 = (float)(tmp_rot[7]);
1616 this.m22 = (float)(tmp_rot[8]);
1621 * Multiplies matrix m1 by matrix m2, does an SVD normalization
1622 * of the result, and places the result into this matrix.
1623 * this = SVDnorm(m1*m2).
1624 * @param m1 the matrix on the left hand side of the multiplication
1625 * @param m2 the matrix on the right hand side of the multiplication
1627 public final void mulNormalize(Matrix3f m1, Matrix3f m2){
1629 double[] tmp = new double[9]; // scratch matrix
1630 double[] tmp_rot = new double[9]; // scratch matrix
1631 double[] tmp_scale = new double[3]; // scratch matrix
1634 tmp[0] = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
1635 tmp[1] = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
1636 tmp[2] = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
1638 tmp[3] = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
1639 tmp[4] = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
1640 tmp[5] = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
1642 tmp[6] = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
1643 tmp[7] = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
1644 tmp[8] = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
1646 Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot);
1648 this.m00 = (float)(tmp_rot[0]);
1649 this.m01 = (float)(tmp_rot[1]);
1650 this.m02 = (float)(tmp_rot[2]);
1652 this.m10 = (float)(tmp_rot[3]);
1653 this.m11 = (float)(tmp_rot[4]);
1654 this.m12 = (float)(tmp_rot[5]);
1656 this.m20 = (float)(tmp_rot[6]);
1657 this.m21 = (float)(tmp_rot[7]);
1658 this.m22 = (float)(tmp_rot[8]);
1662 * Multiplies the transpose of matrix m1 times the transpose of matrix
1663 * m2, and places the result into this.
1664 * @param m1 the matrix on the left hand side of the multiplication
1665 * @param m2 the matrix on the right hand side of the multiplication
1667 public final void mulTransposeBoth(Matrix3f m1, Matrix3f m2)
1669 if (this != m1 && this != m2) {
1670 this.m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02;
1671 this.m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12;
1672 this.m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22;
1674 this.m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02;
1675 this.m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12;
1676 this.m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22;
1678 this.m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02;
1679 this.m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12;
1680 this.m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22;
1682 float m00, m01, m02,
1684 m20, m21, m22; // vars for temp result matrix
1686 m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02;
1687 m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12;
1688 m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22;
1690 m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02;
1691 m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12;
1692 m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22;
1694 m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02;
1695 m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12;
1696 m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22;
1698 this.m00 = m00; this.m01 = m01; this.m02 = m02;
1699 this.m10 = m10; this.m11 = m11; this.m12 = m12;
1700 this.m20 = m20; this.m21 = m21; this.m22 = m22;
1707 * Multiplies matrix m1 times the transpose of matrix m2, and
1708 * places the result into this.
1709 * @param m1 the matrix on the left hand side of the multiplication
1710 * @param m2 the matrix on the right hand side of the multiplication
1712 public final void mulTransposeRight(Matrix3f m1, Matrix3f m2)
1714 if (this != m1 && this != m2) {
1715 this.m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02;
1716 this.m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12;
1717 this.m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22;
1719 this.m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02;
1720 this.m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12;
1721 this.m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22;
1723 this.m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02;
1724 this.m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12;
1725 this.m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22;
1727 float m00, m01, m02,
1729 m20, m21, m22; // vars for temp result matrix
1731 m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02;
1732 m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12;
1733 m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22;
1735 m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02;
1736 m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12;
1737 m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22;
1739 m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02;
1740 m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12;
1741 m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22;
1743 this.m00 = m00; this.m01 = m01; this.m02 = m02;
1744 this.m10 = m10; this.m11 = m11; this.m12 = m12;
1745 this.m20 = m20; this.m21 = m21; this.m22 = m22;
1750 * Multiplies the transpose of matrix m1 times matrix m2, and
1751 * places the result into this.
1752 * @param m1 the matrix on the left hand side of the multiplication
1753 * @param m2 the matrix on the right hand side of the multiplication
1755 public final void mulTransposeLeft(Matrix3f m1, Matrix3f m2)
1757 if (this != m1 && this != m2) {
1758 this.m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20;
1759 this.m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21;
1760 this.m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22;
1762 this.m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20;
1763 this.m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21;
1764 this.m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22;
1766 this.m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20;
1767 this.m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21;
1768 this.m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22;
1770 float m00, m01, m02,
1772 m20, m21, m22; // vars for temp result matrix
1774 m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20;
1775 m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21;
1776 m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22;
1778 m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20;
1779 m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21;
1780 m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22;
1782 m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20;
1783 m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21;
1784 m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22;
1786 this.m00 = m00; this.m01 = m01; this.m02 = m02;
1787 this.m10 = m10; this.m11 = m11; this.m12 = m12;
1788 this.m20 = m20; this.m21 = m21; this.m22 = m22;
1793 * Performs singular value decomposition normalization of this matrix.
1795 public final void normalize(){
1797 double[] tmp_rot = new double[9]; // scratch matrix
1798 double[] tmp_scale = new double[3]; // scratch matrix
1799 getScaleRotate( tmp_scale, tmp_rot );
1801 this.m00 = (float)tmp_rot[0];
1802 this.m01 = (float)tmp_rot[1];
1803 this.m02 = (float)tmp_rot[2];
1805 this.m10 = (float)tmp_rot[3];
1806 this.m11 = (float)tmp_rot[4];
1807 this.m12 = (float)tmp_rot[5];
1809 this.m20 = (float)tmp_rot[6];
1810 this.m21 = (float)tmp_rot[7];
1811 this.m22 = (float)tmp_rot[8];
1816 * Perform singular value decomposition normalization of matrix m1
1817 * and place the normalized values into this.
1818 * @param m1 the matrix values to be normalized
1820 public final void normalize(Matrix3f m1){
1821 double[] tmp = new double[9]; // scratch matrix
1822 double[] tmp_rot = new double[9]; // scratch matrix
1823 double[] tmp_scale = new double[3]; // scratch matrix
1837 Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot );
1839 this.m00 = (float)(tmp_rot[0]);
1840 this.m01 = (float)(tmp_rot[1]);
1841 this.m02 = (float)(tmp_rot[2]);
1843 this.m10 = (float)(tmp_rot[3]);
1844 this.m11 = (float)(tmp_rot[4]);
1845 this.m12 = (float)(tmp_rot[5]);
1847 this.m20 = (float)(tmp_rot[6]);
1848 this.m21 = (float)(tmp_rot[7]);
1849 this.m22 = (float)(tmp_rot[8]);
1854 * Perform cross product normalization of this matrix.
1856 public final void normalizeCP()
1858 float mag = 1.0f/(float)Math.sqrt(m00*m00 + m10*m10 + m20*m20);
1863 mag = 1.0f/(float)Math.sqrt(m01*m01 + m11*m11 + m21*m21);
1868 m02 = m10*m21 - m11*m20;
1869 m12 = m01*m20 - m00*m21;
1870 m22 = m00*m11 - m01*m10;
1875 * Perform cross product normalization of matrix m1 and place the
1876 * normalized values into this.
1877 * @param m1 Provides the matrix values to be normalized
1879 public final void normalizeCP(Matrix3f m1)
1881 float mag = 1.0f/(float)Math.sqrt(m1.m00*m1.m00 + m1.m10*m1.m10 + m1.m20*m1.m20);
1886 mag = 1.0f/(float)Math.sqrt(m1.m01*m1.m01 + m1.m11*m1.m11 + m1.m21*m1.m21);
1891 m02 = m10*m21 - m11*m20;
1892 m12 = m01*m20 - m00*m21;
1893 m22 = m00*m11 - m01*m10;
1898 * Returns true if all of the data members of Matrix3f m1 are
1899 * equal to the corresponding data members in this Matrix3f.
1900 * @param m1 the matrix with which the comparison is made
1901 * @return true or false
1903 public boolean equals(Matrix3f m1)
1907 return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
1908 && this.m10 == m1.m10 && this.m11 == m1.m11 && this.m12 == m1.m12
1909 && this.m20 == m1.m20 && this.m21 == m1.m21 && this.m22 == m1.m22);
1911 catch (NullPointerException e2) { return false; }
1916 * Returns true if the Object o1 is of type Matrix3f and all of the
1917 * data members of o1 are equal to the corresponding data members in
1919 * @param o1 the object with which the comparison is made
1920 * @return true or false
1922 public boolean equals(Object o1)
1926 Matrix3f m2 = (Matrix3f) o1;
1927 return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
1928 && this.m10 == m2.m10 && this.m11 == m2.m11 && this.m12 == m2.m12
1929 && this.m20 == m2.m20 && this.m21 == m2.m21 && this.m22 == m2.m22);
1931 catch (ClassCastException e1) { return false; }
1932 catch (NullPointerException e2) { return false; }
1936 * Returns true if the L-infinite distance between this matrix
1937 * and matrix m1 is less than or equal to the epsilon parameter,
1938 * otherwise returns false. The L-infinite
1939 * distance is equal to
1940 * MAX[i=0,1,2 ; j=0,1,2 ; abs(this.m(i,j) - m1.m(i,j)]
1941 * @param m1 the matrix to be compared to this matrix
1942 * @param epsilon the threshold value
1944 public boolean epsilonEquals(Matrix3f m1, float epsilon)
1946 boolean status = true;
1948 if( Math.abs( this.m00 - m1.m00) > epsilon) status = false;
1949 if( Math.abs( this.m01 - m1.m01) > epsilon) status = false;
1950 if( Math.abs( this.m02 - m1.m02) > epsilon) status = false;
1952 if( Math.abs( this.m10 - m1.m10) > epsilon) status = false;
1953 if( Math.abs( this.m11 - m1.m11) > epsilon) status = false;
1954 if( Math.abs( this.m12 - m1.m12) > epsilon) status = false;
1956 if( Math.abs( this.m20 - m1.m20) > epsilon) status = false;
1957 if( Math.abs( this.m21 - m1.m21) > epsilon) status = false;
1958 if( Math.abs( this.m22 - m1.m22) > epsilon) status = false;
1966 * Returns a hash code value based on the data values in this
1967 * object. Two different Matrix3f objects with identical data values
1968 * (i.e., Matrix3f.equals returns true) will return the same hash
1969 * code value. Two objects with different data members may return the
1970 * same hash value, although this is not likely.
1971 * @return the integer hash code value
1973 public int hashCode() {
1975 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m00);
1976 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m01);
1977 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m02);
1978 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m10);
1979 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m11);
1980 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m12);
1981 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m20);
1982 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m21);
1983 bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m22);
1984 return (int) (bits ^ (bits >> 32));
1989 * Sets this matrix to all zeros.
1991 public final void setZero()
2008 * Negates the value of this matrix: this = -this.
2010 public final void negate()
2012 this.m00 = -this.m00;
2013 this.m01 = -this.m01;
2014 this.m02 = -this.m02;
2016 this.m10 = -this.m10;
2017 this.m11 = -this.m11;
2018 this.m12 = -this.m12;
2020 this.m20 = -this.m20;
2021 this.m21 = -this.m21;
2022 this.m22 = -this.m22;
2027 * Sets the value of this matrix equal to the negation of
2028 * of the Matrix3f parameter.
2029 * @param m1 the source matrix
2031 public final void negate(Matrix3f m1)
2048 * Multiply this matrix by the tuple t and place the result
2049 * back into the tuple (t = this*t).
2050 * @param t the tuple to be multiplied by this matrix and then replaced
2052 public final void transform(Tuple3f t) {
2054 x = m00* t.x + m01*t.y + m02*t.z;
2055 y = m10* t.x + m11*t.y + m12*t.z;
2056 z = m20* t.x + m21*t.y + m22*t.z;
2061 * Multiply this matrix by the tuple t and and place the result
2062 * into the tuple "result" (result = this*t).
2063 * @param t the tuple to be multiplied by this matrix
2064 * @param result the tuple into which the product is placed
2066 public final void transform(Tuple3f t, Tuple3f result) {
2068 x = m00* t.x + m01*t.y + m02*t.z;
2069 y = m10* t.x + m11*t.y + m12*t.z;
2070 result.z = m20* t.x + m21*t.y + m22*t.z;
2076 * perform SVD (if necessary to get rotational component
2078 void getScaleRotate( double[] scales, double[] rot ) {
2080 double[] tmp = new double[9]; // scratch matrix
2090 Matrix3d.compute_svd(tmp, scales, rot);
2097 * Creates a new object of the same class as this object.
2099 * @return a clone of this instance.
2100 * @exception OutOfMemoryError if there is not enough memory.
2101 * @see java.lang.Cloneable
2102 * @since vecmath 1.3
2104 public Object clone() {
2107 m1 = (Matrix3f)super.clone();
2108 } catch (CloneNotSupportedException e) {
2109 // this shouldn't happen, since we are Cloneable
2110 throw new InternalError();
2117 * Get the first matrix element in the first row.
2119 * @return Returns the m00.
2121 * @since vecmath 1.5
2123 public final float getM00() {
2128 * Set the first matrix element in the first row.
2130 * @param m00 The m00 to set.
2132 * @since vecmath 1.5
2134 public final void setM00(float m00) {
2139 * Get the second matrix element in the first row.
2141 * @return Returns the m01.
2144 * @since vecmath 1.5
2146 public final float getM01() {
2151 * Set the second matrix element in the first row.
2153 * @param m01 The m01 to set.
2155 * @since vecmath 1.5
2157 public final void setM01(float m01) {
2162 * Get the third matrix element in the first row.
2164 * @return Returns the m02.
2166 * @since vecmath 1.5
2168 public final float getM02() {
2173 * Set the third matrix element in the first row.
2175 * @param m02 The m02 to set.
2177 * @since vecmath 1.5
2179 public final void setM02(float m02) {
2184 * Get first matrix element in the second row.
2186 * @return Returns the m10.
2188 * @since vecmath 1.5
2190 public final float getM10() {
2195 * Set first matrix element in the second row.
2197 * @param m10 The m10 to set.
2199 * @since vecmath 1.5
2201 public final void setM10(float m10) {
2206 * Get second matrix element in the second row.
2208 * @return Returns the m11.
2210 * @since vecmath 1.5
2212 public final float getM11() {
2217 * Set the second matrix element in the second row.
2219 * @param m11 The m11 to set.
2221 * @since vecmath 1.5
2223 public final void setM11(float m11) {
2228 * Get the third matrix element in the second row.
2230 * @return Returns the m12.
2232 * @since vecmath 1.5
2234 public final float getM12() {
2239 * Set the third matrix element in the second row.
2240 * @param m12 The m12 to set.
2241 * @since vecmath 1.5
2243 public final void setM12(float m12) {
2248 * Get the first matrix element in the third row.
2250 * @return Returns the m20.
2252 * @since vecmath 1.5
2254 public final float getM20() {
2259 * Set the first matrix element in the third row.
2261 * @param m20 The m20 to set.
2263 * @since vecmath 1.5
2265 public final void setM20(float m20) {
2270 * Get the second matrix element in the third row.
2272 * @return Returns the m21.
2274 * @since vecmath 1.5
2276 public final float getM21() {
2281 * Set the second matrix element in the third row.
2283 * @param m21 The m21 to set.
2285 * @since vecmath 1.5
2287 public final void setM21(float m21) {
2292 * Get the third matrix element in the third row .
2294 * @return Returns the m22.
2296 * @since vecmath 1.5
2298 public final float getM22() {
2303 * Set the third matrix element in the third row.
2305 * @param m22 The m22 to set.
2307 * @since vecmath 1.5
2309 public final void setM22(float m22) {