2 * $RCSfile: Matrix4d.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 double precision floating point 4 by 4 matrix.
38 * Primarily to support 3D rotations.
41 public class Matrix4d implements java.io.Serializable, Cloneable {
43 // Compatible with 1.1
44 static final long serialVersionUID = 8223903484171633710L;
47 * The first element of the first row.
52 * The second element of the first row.
57 * The third element of the first row.
62 * The fourth element of the first row.
67 * The first element of the second row.
72 * The second element of the second row.
77 * The third element of the second row.
82 * The fourth element of the second row.
87 * The first element of the third row.
92 * The second element of the third row.
97 * The third element of the third row.
102 * The fourth element of the third row.
107 * The first element of the fourth row.
112 * The second element of the fourth row.
117 * The third element of the fourth row.
122 * The fourth element of the fourth row.
126 double[] tmp = new double[16];
127 double[] tmp_rot = new double[9]; // scratch matrix
128 double[] tmp_scale = new double[3]; // scratch matrix
130 private static final double EPS = 1.0E-10;
134 * Constructs and initializes a Matrix4d from the specified 16 values.
135 * @param m00 the [0][0] element
136 * @param m01 the [0][1] element
137 * @param m02 the [0][2] element
138 * @param m03 the [0][3] element
139 * @param m10 the [1][0] element
140 * @param m11 the [1][1] element
141 * @param m12 the [1][2] element
142 * @param m13 the [1][3] element
143 * @param m20 the [2][0] element
144 * @param m21 the [2][1] element
145 * @param m22 the [2][2] element
146 * @param m23 the [2][3] element
147 * @param m30 the [3][0] element
148 * @param m31 the [3][1] element
149 * @param m32 the [3][2] element
150 * @param m33 the [3][3] element
152 public Matrix4d(double m00, double m01, double m02, double m03,
153 double m10, double m11, double m12, double m13,
154 double m20, double m21, double m22, double m23,
155 double m30, double m31, double m32, double m33)
180 * Constructs and initializes a Matrix4d from the specified 16
181 * element array. this.m00 =v[0], this.m01=v[1], etc.
182 * @param v the array of length 16 containing in order
184 public Matrix4d(double[] v)
209 * Constructs and initializes a Matrix4d from the quaternion,
210 * translation, and scale values; the scale is applied only to the
211 * rotational components of the matrix (upper 3x3) and not to the
212 * translational components.
213 * @param q1 the quaternion value representing the rotational component
214 * @param t1 the translational component of the matrix
215 * @param s the scale value applied to the rotational components
217 public Matrix4d(Quat4d q1, Vector3d t1, double s)
219 m00 = s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
220 m10 = s*(2.0*(q1.x*q1.y + q1.w*q1.z));
221 m20 = s*(2.0*(q1.x*q1.z - q1.w*q1.y));
223 m01 = s*(2.0*(q1.x*q1.y - q1.w*q1.z));
224 m11 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
225 m21 = s*(2.0*(q1.y*q1.z + q1.w*q1.x));
227 m02 = s*(2.0*(q1.x*q1.z + q1.w*q1.y));
228 m12 = s*(2.0*(q1.y*q1.z - q1.w*q1.x));
229 m22 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
243 * Constructs and initializes a Matrix4d from the quaternion,
244 * translation, and scale values; the scale is applied only to the
245 * rotational components of the matrix (upper 3x3) and not to the
246 * translational components.
247 * @param q1 the quaternion value representing the rotational component
248 * @param t1 the translational component of the matrix
249 * @param s the scale value applied to the rotational components
251 public Matrix4d(Quat4f q1, Vector3d t1, double s)
253 m00 = s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
254 m10 = s*(2.0*(q1.x*q1.y + q1.w*q1.z));
255 m20 = s*(2.0*(q1.x*q1.z - q1.w*q1.y));
257 m01 = s*(2.0*(q1.x*q1.y - q1.w*q1.z));
258 m11 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
259 m21 = s*(2.0*(q1.y*q1.z + q1.w*q1.x));
261 m02 = s*(2.0*(q1.x*q1.z + q1.w*q1.y));
262 m12 = s*(2.0*(q1.y*q1.z - q1.w*q1.x));
263 m22 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
277 * Constructs a new matrix with the same values as the
278 * Matrix4d parameter.
279 * @param m1 the source matrix
281 public Matrix4d(Matrix4d m1)
306 * Constructs a new matrix with the same values as the
307 * Matrix4f parameter.
308 * @param m1 the source matrix
310 public Matrix4d(Matrix4f m1)
335 * Constructs and initializes a Matrix4d from the rotation matrix,
336 * translation, and scale values; the scale is applied only to the
337 * rotational components of the matrix (upper 3x3) and not to the
338 * translational components of the matrix.
339 * @param m1 the rotation matrix representing the rotational components
340 * @param t1 the translational components of the matrix
341 * @param s the scale value applied to the rotational components
343 public Matrix4d(Matrix3f m1, Vector3d t1, double s)
368 * Constructs and initializes a Matrix4f from the rotation matrix,
369 * translation, and scale values; the scale is applied only to the
370 * rotational components of the matrix (upper 3x3) and not to the
371 * translational components of the matrix.
372 * @param m1 the rotation matrix representing the rotational components
373 * @param t1 the translational components of the matrix
374 * @param s the scale value applied to the rotational components
376 public Matrix4d(Matrix3d m1, Vector3d t1, double s)
401 * Constructs and initializes a Matrix4d to all zeros.
428 * Returns a string that contains the values of this Matrix4d.
429 * @return the String representation
431 public String toString() {
433 this.m00 + ", " + this.m01 + ", " + this.m02 + ", " + this.m03 + "\n" +
434 this.m10 + ", " + this.m11 + ", " + this.m12 + ", " + this.m13 + "\n" +
435 this.m20 + ", " + this.m21 + ", " + this.m22 + ", " + this.m23 + "\n" +
436 this.m30 + ", " + this.m31 + ", " + this.m32 + ", " + this.m33 + "\n";
440 * Sets this Matrix4d to identity.
442 public final void setIdentity()
466 * Sets the specified element of this matrix4f to the value provided.
467 * @param row the row number to be modified (zero indexed)
468 * @param column the column number to be modified (zero indexed)
469 * @param value the new value
471 public final void setElement(int row, int column, double value)
491 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
511 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
531 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
551 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
556 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
561 * Retrieves the value at the specified row and column of this matrix.
562 * @param row the row number to be retrieved (zero indexed)
563 * @param column the column number to be retrieved (zero indexed)
564 * @return the value at the indexed element
566 public final double getElement(int row, int column)
636 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d1"));
640 * Copies the matrix values in the specified row into the vector parameter.
641 * @param row the matrix row
642 * @param v the vector into which the matrix row values will be copied
644 public final void getRow(int row, Vector4d v) {
650 } else if(row == 1) {
655 } else if(row == 2) {
660 } else if(row == 3) {
666 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d2"));
672 * Copies the matrix values in the specified row into the array parameter.
673 * @param row the matrix row
674 * @param v the array into which the matrix row values will be copied
676 public final void getRow(int row, double v[]) {
682 } else if(row == 1) {
687 } else if(row == 2) {
692 } else if(row == 3) {
699 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d2"));
706 * Copies the matrix values in the specified column into the vector
708 * @param column the matrix column
709 * @param v the vector into which the matrix column values will be copied
711 public final void getColumn(int column, Vector4d v) {
717 } else if(column == 1) {
722 } else if(column == 2) {
727 } else if(column == 3) {
733 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d3"));
742 * Copies the matrix values in the specified column into the array
744 * @param column the matrix column
745 * @param v the array into which the matrix column values will be copied
747 public final void getColumn(int column, double v[]) {
753 } else if(column == 1) {
758 } else if(column == 2) {
763 } else if(column == 3) {
769 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d3"));
777 * Performs an SVD normalization of this matrix in order to acquire
778 * the normalized rotational component; the values are placed into
779 * the Matrix3d parameter.
780 * @param m1 the matrix into which the rotational component is placed
782 public final void get(Matrix3d m1)
785 double[] tmp_rot = new double[9]; // scratch matrix
786 double[] tmp_scale = new double[3]; // scratch matrix
787 getScaleRotate( tmp_scale, tmp_rot );
805 * Performs an SVD normalization of this matrix in order to acquire
806 * the normalized rotational component; the values are placed into
807 * the Matrix3f parameter.
808 * @param m1 the matrix into which the rotational component is placed
810 public final void get(Matrix3f m1)
812 double[] tmp_rot = new double[9]; // scratch matrix
813 double[] tmp_scale = new double[3]; // scratch matrix
815 getScaleRotate( tmp_scale, tmp_rot );
817 m1.m00 = (float)tmp_rot[0];
818 m1.m01 = (float)tmp_rot[1];
819 m1.m02 = (float)tmp_rot[2];
821 m1.m10 = (float)tmp_rot[3];
822 m1.m11 = (float)tmp_rot[4];
823 m1.m12 = (float)tmp_rot[5];
825 m1.m20 = (float)tmp_rot[6];
826 m1.m21 = (float)tmp_rot[7];
827 m1.m22 = (float)tmp_rot[8];
831 * Performs an SVD normalization of this matrix to calculate
832 * the rotation as a 3x3 matrix, the translation, and the scale.
833 * None of the matrix values are modified.
834 * @param m1 the normalized matrix representing the rotation
835 * @param t1 the translation component
836 * @return the scale component of this transform
838 public final double get(Matrix3d m1, Vector3d t1)
841 double[] tmp_rot = new double[9]; // scratch matrix
842 double[] tmp_scale = new double[3]; // scratch matrix
843 getScaleRotate( tmp_scale, tmp_rot );
861 return( Matrix3d.max3( tmp_scale ));
866 * Performs an SVD normalization of this matrix to calculate
867 * the rotation as a 3x3 matrix, the translation, and the scale.
868 * None of the matrix values are modified.
869 * @param m1 the normalized matrix representing the rotation
870 * @param t1 the translation component
871 * @return the scale component of this transform
873 public final double get(Matrix3f m1, Vector3d t1){
875 double[] tmp_rot = new double[9]; // scratch matrix
876 double[] tmp_scale = new double[3]; // scratch matrix
877 getScaleRotate( tmp_scale, tmp_rot );
879 m1.m00 = (float)tmp_rot[0];
880 m1.m01 = (float)tmp_rot[1];
881 m1.m02 = (float)tmp_rot[2];
883 m1.m10 = (float)tmp_rot[3];
884 m1.m11 = (float)tmp_rot[4];
885 m1.m12 = (float)tmp_rot[5];
887 m1.m20 = (float)tmp_rot[6];
888 m1.m21 = (float)tmp_rot[7];
889 m1.m22 = (float)tmp_rot[8];
895 return( Matrix3d.max3( tmp_scale ));
900 * Performs an SVD normalization of this matrix in order to acquire
901 * the normalized rotational component; the values are placed into
902 * the Quat4f parameter.
903 * @param q1 quaternion into which the rotation component is placed
905 public final void get(Quat4f q1)
908 double[] tmp_rot = new double[9]; // scratch matrix
909 double[] tmp_scale = new double[3]; // scratch matrix
910 getScaleRotate( tmp_scale, tmp_rot );
914 ww = 0.25*(1.0 + tmp_rot[0] + tmp_rot[4] + tmp_rot[8]);
915 if(!((ww<0?-ww:ww) < 1.0e-30)) {
916 q1.w = (float)Math.sqrt(ww);
918 q1.x = (float)((tmp_rot[7] - tmp_rot[5])*ww);
919 q1.y = (float)((tmp_rot[2] - tmp_rot[6])*ww);
920 q1.z = (float)((tmp_rot[3] - tmp_rot[1])*ww);
925 ww = -0.5*(tmp_rot[4] + tmp_rot[8]);
926 if(!((ww<0?-ww:ww) < 1.0e-30)) {
927 q1.x = (float)Math.sqrt(ww);
929 q1.y = (float)(tmp_rot[3]*ww);
930 q1.z = (float)(tmp_rot[6]*ww);
935 ww = 0.5*(1.0 - tmp_rot[8]);
936 if(!((ww<0?-ww:ww) < 1.0e-30)) {
937 q1.y = (float)(Math.sqrt(ww));
938 q1.z = (float)(tmp_rot[7]/(2.0*q1.y));
948 * Performs an SVD normalization of q1 matrix in order to acquire
949 * the normalized rotational component; the values are placed into
950 * the Quat4d parameter.
951 * @param q1 the quaternion into which the rotation component is placed
953 public final void get(Quat4d q1)
955 double[] tmp_rot = new double[9]; // scratch matrix
956 double[] tmp_scale = new double[3]; // scratch matrix
958 getScaleRotate( tmp_scale, tmp_rot );
962 ww = 0.25*(1.0 + tmp_rot[0] + tmp_rot[4] + tmp_rot[8]);
963 if(!((ww<0?-ww:ww) < 1.0e-30)) {
964 q1.w = Math.sqrt(ww);
966 q1.x = (tmp_rot[7] - tmp_rot[5])*ww;
967 q1.y = (tmp_rot[2] - tmp_rot[6])*ww;
968 q1.z = (tmp_rot[3] - tmp_rot[1])*ww;
973 ww = -0.5*(tmp_rot[4] + tmp_rot[8]);
974 if(!((ww<0?-ww:ww) < 1.0e-30)) {
975 q1.x = Math.sqrt(ww);
977 q1.y = tmp_rot[3]*ww;
978 q1.z = tmp_rot[6]*ww;
983 ww = 0.5*(1.0 - tmp_rot[8]);
984 if(!((ww<0?-ww:ww) < 1.0e-30)) {
985 q1.y = Math.sqrt(ww);
986 q1.z = tmp_rot[7]/(2.0*q1.y);
995 * Retrieves the translational components of this matrix.
996 * @param trans the vector that will receive the translational component
998 public final void get(Vector3d trans)
1006 * Gets the upper 3x3 values of this matrix and places them into
1008 * @param m1 the matrix that will hold the values
1010 public final void getRotationScale(Matrix3f m1)
1012 m1.m00 = (float)m00; m1.m01 = (float)m01; m1.m02 = (float)m02;
1013 m1.m10 = (float)m10; m1.m11 = (float)m11; m1.m12 = (float)m12;
1014 m1.m20 = (float)m20; m1.m21 = (float)m21; m1.m22 = (float)m22;
1018 * Gets the upper 3x3 values of this matrix and places them into
1020 * @param m1 the matrix that will hold the values
1022 public final void getRotationScale(Matrix3d m1)
1024 m1.m00 = m00; m1.m01 = m01; m1.m02 = m02;
1025 m1.m10 = m10; m1.m11 = m11; m1.m12 = m12;
1026 m1.m20 = m20; m1.m21 = m21; m1.m22 = m22;
1030 * Performs an SVD normalization of this matrix to calculate
1031 * and return the uniform scale factor. If the matrix has non-uniform
1032 * scale factors, the largest of the x, y, and z scale factors will
1033 * be returned. This matrix is not modified.
1034 * @return the scale factor of this matrix
1036 public final double getScale()
1039 double[] tmp_rot = new double[9]; // scratch matrix
1040 double[] tmp_scale = new double[3]; // scratch matrix
1041 getScaleRotate( tmp_scale, tmp_rot );
1043 return( Matrix3d.max3( tmp_scale ));
1048 * Replaces the upper 3x3 matrix values of this matrix with the
1049 * values in the matrix m1.
1050 * @param m1 the matrix that will be the new upper 3x3
1052 public final void setRotationScale(Matrix3d m1)
1054 m00 = m1.m00; m01 = m1.m01; m02 = m1.m02;
1055 m10 = m1.m10; m11 = m1.m11; m12 = m1.m12;
1056 m20 = m1.m20; m21 = m1.m21; m22 = m1.m22;
1060 * Replaces the upper 3x3 matrix values of this matrix with the
1061 * values in the matrix m1.
1062 * @param m1 the matrix that will be the new upper 3x3
1064 public final void setRotationScale(Matrix3f m1)
1066 m00 = m1.m00; m01 = m1.m01; m02 = m1.m02;
1067 m10 = m1.m10; m11 = m1.m11; m12 = m1.m12;
1068 m20 = m1.m20; m21 = m1.m21; m22 = m1.m22;
1072 * Sets the scale component of the current matrix by factoring
1073 * out the current scale (by doing an SVD) from the rotational
1074 * component and multiplying by the new scale.
1075 * @param scale the new scale amount
1077 public final void setScale(double scale)
1079 double[] tmp_rot = new double[9]; // scratch matrix
1080 double[] tmp_scale = new double[3]; // scratch matrix
1082 getScaleRotate( tmp_scale, tmp_rot );
1084 m00 = tmp_rot[0]*scale;
1085 m01 = tmp_rot[1]*scale;
1086 m02 = tmp_rot[2]*scale;
1088 m10 = tmp_rot[3]*scale;
1089 m11 = tmp_rot[4]*scale;
1090 m12 = tmp_rot[5]*scale;
1092 m20 = tmp_rot[6]*scale;
1093 m21 = tmp_rot[7]*scale;
1094 m22 = tmp_rot[8]*scale;
1099 * Sets the specified row of this matrix4d to the four values provided.
1100 * @param row the row number to be modified (zero indexed)
1101 * @param x the first column element
1102 * @param y the second column element
1103 * @param z the third column element
1104 * @param w the fourth column element
1106 public final void setRow(int row, double x, double y, double z, double w)
1138 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d4"));
1144 * Sets the specified row of this matrix4d to the Vector provided.
1145 * @param row the row number to be modified (zero indexed)
1146 * @param v the replacement row
1148 public final void setRow(int row, Vector4d v)
1180 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d4"));
1185 * Sets the specified row of this matrix4d to the four values provided.
1186 * @param row the row number to be modified (zero indexed)
1187 * @param v the replacement row
1189 public final void setRow(int row, double v[])
1221 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d4"));
1226 * Sets the specified column of this matrix4d to the four values provided.
1227 * @param column the column number to be modified (zero indexed)
1228 * @param x the first row element
1229 * @param y the second row element
1230 * @param z the third row element
1231 * @param w the fourth row element
1233 public final void setColumn(int column, double x, double y, double z, double w)
1265 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d7"));
1270 * Sets the specified column of this matrix4d to the vector provided.
1271 * @param column the column number to be modified (zero indexed)
1272 * @param v the replacement column
1274 public final void setColumn(int column, Vector4d v)
1306 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d7"));
1311 * Sets the specified column of this matrix4d to the four values provided.
1312 * @param column the column number to be modified (zero indexed)
1313 * @param v the replacement column
1315 public final void setColumn(int column, double v[])
1347 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d7"));
1352 * Adds a scalar to each component of this matrix.
1353 * @param scalar the scalar adder
1355 public final void add(double scalar)
1376 * Adds a scalar to each component of the matrix m1 and places
1377 * the result into this. Matrix m1 is not modified.
1378 * @param scalar the scalar adder
1379 * @param m1 the original matrix values
1381 public final void add(double scalar, Matrix4d m1)
1383 this.m00 = m1.m00 + scalar;
1384 this.m01 = m1.m01 + scalar;
1385 this.m02 = m1.m02 + scalar;
1386 this.m03 = m1.m03 + scalar;
1387 this.m10 = m1.m10 + scalar;
1388 this.m11 = m1.m11 + scalar;
1389 this.m12 = m1.m12 + scalar;
1390 this.m13 = m1.m13 + scalar;
1391 this.m20 = m1.m20 + scalar;
1392 this.m21 = m1.m21 + scalar;
1393 this.m22 = m1.m22 + scalar;
1394 this.m23 = m1.m23 + scalar;
1395 this.m30 = m1.m30 + scalar;
1396 this.m31 = m1.m31 + scalar;
1397 this.m32 = m1.m32 + scalar;
1398 this.m33 = m1.m33 + scalar;
1402 * Sets the value of this matrix to the matrix sum of matrices m1 and m2.
1403 * @param m1 the first matrix
1404 * @param m2 the second matrix
1406 public final void add(Matrix4d m1, Matrix4d m2)
1408 this.m00 = m1.m00 + m2.m00;
1409 this.m01 = m1.m01 + m2.m01;
1410 this.m02 = m1.m02 + m2.m02;
1411 this.m03 = m1.m03 + m2.m03;
1413 this.m10 = m1.m10 + m2.m10;
1414 this.m11 = m1.m11 + m2.m11;
1415 this.m12 = m1.m12 + m2.m12;
1416 this.m13 = m1.m13 + m2.m13;
1418 this.m20 = m1.m20 + m2.m20;
1419 this.m21 = m1.m21 + m2.m21;
1420 this.m22 = m1.m22 + m2.m22;
1421 this.m23 = m1.m23 + m2.m23;
1423 this.m30 = m1.m30 + m2.m30;
1424 this.m31 = m1.m31 + m2.m31;
1425 this.m32 = m1.m32 + m2.m32;
1426 this.m33 = m1.m33 + m2.m33;
1430 * Sets the value of this matrix to sum of itself and matrix m1.
1431 * @param m1 the other matrix
1433 public final void add(Matrix4d m1)
1457 * Sets the value of this matrix to the matrix difference
1458 * of matrices m1 and m2.
1459 * @param m1 the first matrix
1460 * @param m2 the second matrix
1462 public final void sub(Matrix4d m1, Matrix4d m2)
1464 this.m00 = m1.m00 - m2.m00;
1465 this.m01 = m1.m01 - m2.m01;
1466 this.m02 = m1.m02 - m2.m02;
1467 this.m03 = m1.m03 - m2.m03;
1469 this.m10 = m1.m10 - m2.m10;
1470 this.m11 = m1.m11 - m2.m11;
1471 this.m12 = m1.m12 - m2.m12;
1472 this.m13 = m1.m13 - m2.m13;
1474 this.m20 = m1.m20 - m2.m20;
1475 this.m21 = m1.m21 - m2.m21;
1476 this.m22 = m1.m22 - m2.m22;
1477 this.m23 = m1.m23 - m2.m23;
1479 this.m30 = m1.m30 - m2.m30;
1480 this.m31 = m1.m31 - m2.m31;
1481 this.m32 = m1.m32 - m2.m32;
1482 this.m33 = m1.m33 - m2.m33;
1487 * Sets the value of this matrix to the matrix difference of itself
1488 * and matrix m1 (this = this - m1).
1489 * @param m1 the other matrix
1491 public final void sub(Matrix4d m1)
1515 * Sets the value of this matrix to its transpose.
1517 public final void transpose()
1522 this.m10 = this.m01;
1526 this.m20 = this.m02;
1530 this.m30 = this.m03;
1534 this.m21 = this.m12;
1538 this.m31 = this.m13;
1542 this.m32 = this.m23;
1547 * Sets the value of this matrix to the transpose of the argument matrix
1548 * @param m1 the matrix to be transposed
1550 public final void transpose(Matrix4d m1)
1577 * Sets the values in this Matrix4d equal to the row-major
1578 * array parameter (ie, the first four elements of the
1579 * array will be copied into the first row of this matrix, etc.).
1580 * @param m the double precision array of length 16
1582 public final void set(double[] m)
1603 * Sets the rotational component (upper 3x3) of this matrix to the
1604 * matrix values in the single precision Matrix3f argument; the other
1605 * elements of this matrix are initialized as if this were an identity
1606 * matrix (i.e., affine matrix with no translational component).
1607 * @param m1 the double precision 3x3 matrix
1609 public final void set(Matrix3f m1)
1611 m00 = m1.m00; m01 = m1.m01; m02 = m1.m02; m03 = 0.0;
1612 m10 = m1.m10; m11 = m1.m11; m12 = m1.m12; m13 = 0.0;
1613 m20 = m1.m20; m21 = m1.m21; m22 = m1.m22; m23 = 0.0;
1614 m30 = 0.0; m31 = 0.0 ; m32 = 0.0 ; m33 = 1.0;
1618 * Sets the rotational component (upper 3x3) of this matrix to the
1619 * matrix values in the double precision Matrix3d argument; the other
1620 * elements of this matrix are initialized as if this were an identity
1621 * matrix (i.e., affine matrix with no translational component).
1622 * @param m1 the double precision 3x3 matrix
1624 public final void set(Matrix3d m1)
1626 m00 = m1.m00; m01 = m1.m01; m02 = m1.m02; m03 = 0.0;
1627 m10 = m1.m10; m11 = m1.m11; m12 = m1.m12; m13 = 0.0;
1628 m20 = m1.m20; m21 = m1.m21; m22 = m1.m22; m23 = 0.0;
1629 m30 = 0.0; m31 = 0.0 ; m32 = 0.0 ; m33 = 1.0;
1633 * Sets the value of this matrix to the matrix conversion of the
1634 * (double precision) quaternion argument.
1635 * @param q1 the quaternion to be converted
1637 public final void set(Quat4d q1)
1639 this.m00 = (1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
1640 this.m10 = (2.0*(q1.x*q1.y + q1.w*q1.z));
1641 this.m20 = (2.0*(q1.x*q1.z - q1.w*q1.y));
1643 this.m01 = (2.0*(q1.x*q1.y - q1.w*q1.z));
1644 this.m11 = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
1645 this.m21 = (2.0*(q1.y*q1.z + q1.w*q1.x));
1647 this.m02 = (2.0*(q1.x*q1.z + q1.w*q1.y));
1648 this.m12 = (2.0*(q1.y*q1.z - q1.w*q1.x));
1649 this.m22 = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
1662 * Sets the value of this matrix to the matrix conversion of the
1663 * double precision axis and angle argument.
1664 * @param a1 the axis and angle to be converted
1666 public final void set(AxisAngle4d a1)
1668 double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
1684 double ax = a1.x*mag;
1685 double ay = a1.y*mag;
1686 double az = a1.z*mag;
1688 double sinTheta = Math.sin(a1.angle);
1689 double cosTheta = Math.cos(a1.angle);
1690 double t = 1.0 - cosTheta;
1692 double xz = ax * az;
1693 double xy = ax * ay;
1694 double yz = ay * az;
1696 m00 = t * ax * ax + cosTheta;
1697 m01 = t * xy - sinTheta * az;
1698 m02 = t * xz + sinTheta * ay;
1700 m10 = t * xy + sinTheta * az;
1701 m11 = t * ay * ay + cosTheta;
1702 m12 = t * yz - sinTheta * ax;
1704 m20 = t * xz - sinTheta * ay;
1705 m21 = t * yz + sinTheta * ax;
1706 m22 = t * az * az + cosTheta;
1720 * Sets the value of this matrix to the matrix conversion of the
1721 * single precision quaternion argument.
1722 * @param q1 the quaternion to be converted
1724 public final void set(Quat4f q1)
1726 this.m00 = (1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
1727 this.m10 = (2.0*(q1.x*q1.y + q1.w*q1.z));
1728 this.m20 = (2.0*(q1.x*q1.z - q1.w*q1.y));
1730 this.m01 = (2.0*(q1.x*q1.y - q1.w*q1.z));
1731 this.m11 = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
1732 this.m21 = (2.0*(q1.y*q1.z + q1.w*q1.x));
1734 this.m02 = (2.0*(q1.x*q1.z + q1.w*q1.y));
1735 this.m12 = (2.0*(q1.y*q1.z - q1.w*q1.x));
1736 this.m22 = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
1749 * Sets the value of this matrix to the matrix conversion of the
1750 * single precision axis and angle argument.
1751 * @param a1 the axis and angle to be converted
1753 public final void set(AxisAngle4f a1)
1755 double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
1771 double ax = a1.x*mag;
1772 double ay = a1.y*mag;
1773 double az = a1.z*mag;
1775 double sinTheta = Math.sin((double)a1.angle);
1776 double cosTheta = Math.cos((double)a1.angle);
1777 double t = 1.0 - cosTheta;
1779 double xz = ax * az;
1780 double xy = ax * ay;
1781 double yz = ay * az;
1783 m00 = t * ax * ax + cosTheta;
1784 m01 = t * xy - sinTheta * az;
1785 m02 = t * xz + sinTheta * ay;
1787 m10 = t * xy + sinTheta * az;
1788 m11 = t * ay * ay + cosTheta;
1789 m12 = t * yz - sinTheta * ax;
1791 m20 = t * xz - sinTheta * ay;
1792 m21 = t * yz + sinTheta * ax;
1793 m22 = t * az * az + cosTheta;
1806 * Sets the value of this matrix from the rotation expressed
1807 * by the quaternion q1, the translation t1, and the scale s.
1808 * @param q1 the rotation expressed as a quaternion
1809 * @param t1 the translation
1810 * @param s the scale value
1812 public final void set(Quat4d q1, Vector3d t1, double s)
1814 this.m00 = s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
1815 this.m10 = s*(2.0*(q1.x*q1.y + q1.w*q1.z));
1816 this.m20 = s*(2.0*(q1.x*q1.z - q1.w*q1.y));
1818 this.m01 = s*(2.0*(q1.x*q1.y - q1.w*q1.z));
1819 this.m11 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
1820 this.m21 = s*(2.0*(q1.y*q1.z + q1.w*q1.x));
1822 this.m02 = s*(2.0*(q1.x*q1.z + q1.w*q1.y));
1823 this.m12 = s*(2.0*(q1.y*q1.z - q1.w*q1.x));
1824 this.m22 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
1837 * Sets the value of this matrix from the rotation expressed
1838 * by the quaternion q1, the translation t1, and the scale s.
1839 * @param q1 the rotation expressed as a quaternion
1840 * @param t1 the translation
1841 * @param s the scale value
1843 public final void set(Quat4f q1, Vector3d t1, double s)
1845 this.m00 = s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
1846 this.m10 = s*(2.0*(q1.x*q1.y + q1.w*q1.z));
1847 this.m20 = s*(2.0*(q1.x*q1.z - q1.w*q1.y));
1849 this.m01 = s*(2.0*(q1.x*q1.y - q1.w*q1.z));
1850 this.m11 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
1851 this.m21 = s*(2.0*(q1.y*q1.z + q1.w*q1.x));
1853 this.m02 = s*(2.0*(q1.x*q1.z + q1.w*q1.y));
1854 this.m12 = s*(2.0*(q1.y*q1.z - q1.w*q1.x));
1855 this.m22 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
1868 * Sets the value of this matrix from the rotation expressed
1869 * by the quaternion q1, the translation t1, and the scale s.
1870 * @param q1 the rotation expressed as a quaternion
1871 * @param t1 the translation
1872 * @param s the scale value
1874 public final void set(Quat4f q1, Vector3f t1, float s)
1876 this.m00 = s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
1877 this.m10 = s*(2.0*(q1.x*q1.y + q1.w*q1.z));
1878 this.m20 = s*(2.0*(q1.x*q1.z - q1.w*q1.y));
1880 this.m01 = s*(2.0*(q1.x*q1.y - q1.w*q1.z));
1881 this.m11 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
1882 this.m21 = s*(2.0*(q1.y*q1.z + q1.w*q1.x));
1884 this.m02 = s*(2.0*(q1.x*q1.z + q1.w*q1.y));
1885 this.m12 = s*(2.0*(q1.y*q1.z - q1.w*q1.x));
1886 this.m22 = s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
1899 * Sets the value of this matrix to a copy of the
1901 * @param m1 the matrix4f
1903 public final void set(Matrix4f m1)
1927 * Sets the value of this matrix to a copy of the
1929 * @param m1 the matrix to be copied
1931 public final void set(Matrix4d m1)
1955 * Sets the value of this matrix to the matrix inverse
1956 * of the passed (user declared) matrix m1.
1957 * @param m1 the matrix to be inverted
1959 public final void invert(Matrix4d m1)
1966 * Inverts this matrix in place.
1968 public final void invert()
1970 invertGeneral( this );
1974 * General invert routine. Inverts m1 and places the result in "this".
1975 * Note that this routine handles both the "this" version and the
1976 * non-"this" version.
1978 * Also note that since this routine is slow anyway, we won't worry
1979 * about allocating a little bit of garbage.
1981 final void invertGeneral(Matrix4d m1) {
1982 double result[] = new double[16];
1983 int row_perm[] = new int[4];
1986 // Use LU decomposition and backsubstitution code specifically
1987 // for floating-point 4x4 matrices.
1988 double[] tmp = new double[16]; // scratch matrix
1989 // Copy source matrix to t1tmp
2010 // Calculate LU decomposition: Is the matrix singular?
2011 if (!luDecomposition(tmp, row_perm)) {
2012 // Matrix has no inverse
2013 throw new SingularMatrixException(VecMathI18N.getString("Matrix4d10"));
2016 // Perform back substitution on the identity matrix
2017 for(i=0;i<16;i++) result[i] = 0.0;
2018 result[0] = 1.0; result[5] = 1.0; result[10] = 1.0; result[15] = 1.0;
2019 luBacksubstitution(tmp, row_perm, result);
2021 this.m00 = result[0];
2022 this.m01 = result[1];
2023 this.m02 = result[2];
2024 this.m03 = result[3];
2026 this.m10 = result[4];
2027 this.m11 = result[5];
2028 this.m12 = result[6];
2029 this.m13 = result[7];
2031 this.m20 = result[8];
2032 this.m21 = result[9];
2033 this.m22 = result[10];
2034 this.m23 = result[11];
2036 this.m30 = result[12];
2037 this.m31 = result[13];
2038 this.m32 = result[14];
2039 this.m33 = result[15];
2044 * Given a 4x4 array "matrix0", this function replaces it with the
2045 * LU decomposition of a row-wise permutation of itself. The input
2046 * parameters are "matrix0" and "dimen". The array "matrix0" is also
2047 * an output parameter. The vector "row_perm[4]" is an output
2048 * parameter that contains the row permutations resulting from partial
2049 * pivoting. The output parameter "even_row_xchg" is 1 when the
2050 * number of row exchanges is even, or -1 otherwise. Assumes data
2051 * type is always double.
2053 * This function is similar to luDecomposition, except that it
2054 * is tuned specifically for 4x4 matrices.
2056 * @return true if the matrix is nonsingular, or false otherwise.
2059 // Reference: Press, Flannery, Teukolsky, Vetterling,
2060 // _Numerical_Recipes_in_C_, Cambridge University Press,
2063 static boolean luDecomposition(double[] matrix0,
2066 double row_scale[] = new double[4];
2068 // Determine implicit scaling information by looping over rows
2082 // For each column, find the largest element in the row
2085 temp = matrix0[ptr++];
2086 temp = Math.abs(temp);
2092 // Is the matrix singular?
2096 row_scale[rs++] = 1.0 / big;
2106 // For all columns, execute Crout's method
2107 for (j = 0; j < 4; j++) {
2110 double sum, big, temp;
2112 // Determine elements of upper diagonal matrix U
2113 for (i = 0; i < j; i++) {
2114 target = mtx + (4*i) + j;
2115 sum = matrix0[target];
2120 sum -= matrix0[p1] * matrix0[p2];
2124 matrix0[target] = sum;
2127 // Search for largest pivot element and calculate
2128 // intermediate elements of lower diagonal matrix L.
2131 for (i = j; i < 4; i++) {
2132 target = mtx + (4*i) + j;
2133 sum = matrix0[target];
2138 sum -= matrix0[p1] * matrix0[p2];
2142 matrix0[target] = sum;
2144 // Is this the best pivot so far?
2145 if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
2152 throw new RuntimeException(VecMathI18N.getString("Matrix4d11"));
2155 // Is a row exchange necessary?
2157 // Yes: exchange rows
2159 p1 = mtx + (4*imax);
2163 matrix0[p1++] = matrix0[p2];
2164 matrix0[p2++] = temp;
2167 // Record change in scale factor
2168 row_scale[imax] = row_scale[j];
2171 // Record row permutation
2174 // Is the matrix singular
2175 if (matrix0[(mtx + (4*j) + j)] == 0.0) {
2179 // Divide elements of lower diagonal matrix L by pivot
2181 temp = 1.0 / (matrix0[(mtx + (4*j) + j)]);
2182 target = mtx + (4*(j+1)) + j;
2185 matrix0[target] *= temp;
2196 * Solves a set of linear equations. The input parameters "matrix1",
2197 * and "row_perm" come from luDecompostionD4x4 and do not change
2198 * here. The parameter "matrix2" is a set of column vectors assembled
2199 * into a 4x4 matrix of floating-point values. The procedure takes each
2200 * column of "matrix2" in turn and treats it as the right-hand side of the
2201 * matrix equation Ax = LUx = b. The solution vector replaces the
2202 * original column of the matrix.
2204 * If "matrix2" is the identity matrix, the procedure replaces its contents
2205 * with the inverse of the matrix from which "matrix1" was originally
2209 // Reference: Press, Flannery, Teukolsky, Vetterling,
2210 // _Numerical_Recipes_in_C_, Cambridge University Press,
2213 static void luBacksubstitution(double[] matrix1,
2217 int i, ii, ip, j, k;
2224 // For each column vector of matrix2 ...
2225 for (k = 0; k < 4; k++) {
2226 // cv = &(matrix2[0][k]);
2230 // Forward substitution
2231 for (i = 0; i < 4; i++) {
2234 ip = row_perm[rp+i];
2235 sum = matrix2[cv+4*ip];
2236 matrix2[cv+4*ip] = matrix2[cv+4*i];
2238 // rv = &(matrix1[i][0]);
2240 for (j = ii; j <= i-1; j++) {
2241 sum -= matrix1[rv+j] * matrix2[cv+4*j];
2244 else if (sum != 0.0) {
2247 matrix2[cv+4*i] = sum;
2251 // rv = &(matrix1[3][0]);
2253 matrix2[cv+4*3] /= matrix1[rv+3];
2256 matrix2[cv+4*2] = (matrix2[cv+4*2] -
2257 matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+2];
2260 matrix2[cv+4*1] = (matrix2[cv+4*1] -
2261 matrix1[rv+2] * matrix2[cv+4*2] -
2262 matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+1];
2265 matrix2[cv+4*0] = (matrix2[cv+4*0] -
2266 matrix1[rv+1] * matrix2[cv+4*1] -
2267 matrix1[rv+2] * matrix2[cv+4*2] -
2268 matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+0];
2273 * Computes the determinant of this matrix.
2274 * @return the determinant of the matrix
2276 public final double determinant()
2280 // cofactor exapainsion along first row
2282 det = m00*(m11*m22*m33+ m12*m23*m31 + m13*m21*m32
2283 - m13*m22*m31 -m11*m23*m32 - m12*m21*m33);
2284 det -= m01*(m10*m22*m33+ m12*m23*m30 + m13*m20*m32
2285 - m13*m22*m30 -m10*m23*m32 - m12*m20*m33);
2286 det += m02*(m10*m21*m33+ m11*m23*m30 + m13*m20*m31
2287 - m13*m21*m30 -m10*m23*m31 - m11*m20*m33);
2288 det -= m03*(m10*m21*m32+ m11*m22*m30 + m12*m20*m31
2289 - m12*m21*m30 -m10*m22*m31 - m11*m20*m32);
2295 * Sets the value of this matrix to a scale matrix with the
2296 * passed scale amount.
2297 * @param scale the scale factor for the matrix
2299 public final void set(double scale)
2323 * Sets the value of this matrix to a translate matrix by the
2324 * passed translation value.
2325 * @param v1 the translation amount
2327 public final void set(Vector3d v1)
2351 * Sets the value of this transform to a scale and translation matrix;
2352 * the scale is not applied to the translation and all of the matrix
2353 * values are modified.
2354 * @param scale the scale factor for the matrix
2355 * @param v1 the translation amount
2357 public final void set(double scale, Vector3d v1)
2381 * Sets the value of this transform to a scale and translation matrix;
2382 * the translation is scaled by the scale factor and all of the matrix
2383 * values are modified.
2384 * @param v1 the translation amount
2385 * @param scale the scale factor for the matrix
2387 public final void set(Vector3d v1, double scale)
2392 this.m03 = scale*v1.x;
2397 this.m13 = scale*v1.y;
2402 this.m23 = scale*v1.z;
2411 * Sets the value of this matrix from the rotation expressed by
2412 * the rotation matrix m1, the translation t1, and the scale factor.
2413 * The translation is not modified by the scale.
2414 * @param m1 the rotation component
2415 * @param t1 the translation component
2416 * @param scale the scale component
2418 public final void set(Matrix3f m1, Vector3f t1, float scale)
2420 this.m00 = m1.m00*scale;
2421 this.m01 = m1.m01*scale;
2422 this.m02 = m1.m02*scale;
2425 this.m10 = m1.m10*scale;
2426 this.m11 = m1.m11*scale;
2427 this.m12 = m1.m12*scale;
2430 this.m20 = m1.m20*scale;
2431 this.m21 = m1.m21*scale;
2432 this.m22 = m1.m22*scale;
2443 * Sets the value of this matrix from the rotation expressed by
2444 * the rotation matrix m1, the translation t1, and the scale factor.
2445 * The translation is not modified by the scale.
2446 * @param m1 the rotation component
2447 * @param t1 the translation component
2448 * @param scale the scale component
2450 public final void set(Matrix3d m1, Vector3d t1, double scale)
2452 this.m00 = m1.m00*scale;
2453 this.m01 = m1.m01*scale;
2454 this.m02 = m1.m02*scale;
2457 this.m10 = m1.m10*scale;
2458 this.m11 = m1.m11*scale;
2459 this.m12 = m1.m12*scale;
2462 this.m20 = m1.m20*scale;
2463 this.m21 = m1.m21*scale;
2464 this.m22 = m1.m22*scale;
2474 * Modifies the translational components of this matrix to the values
2475 * of the Vector3d argument; the other values of this matrix are not
2477 * @param trans the translational component
2479 public final void setTranslation(Vector3d trans)
2487 * Sets the value of this matrix to a counter-clockwise rotation
2489 * @param angle the angle to rotate about the X axis in radians
2491 public final void rotX(double angle)
2493 double sinAngle, cosAngle;
2495 sinAngle = Math.sin(angle);
2496 cosAngle = Math.cos(angle);
2504 this.m11 = cosAngle;
2505 this.m12 = -sinAngle;
2509 this.m21 = sinAngle;
2510 this.m22 = cosAngle;
2520 * Sets the value of this matrix to a counter-clockwise rotation
2522 * @param angle the angle to rotate about the Y axis in radians
2524 public final void rotY(double angle)
2526 double sinAngle, cosAngle;
2528 sinAngle = Math.sin(angle);
2529 cosAngle = Math.cos(angle);
2531 this.m00 = cosAngle;
2533 this.m02 = sinAngle;
2541 this.m20 = -sinAngle;
2543 this.m22 = cosAngle;
2553 * Sets the value of this matrix to a counter-clockwise rotation
2555 * @param angle the angle to rotate about the Z axis in radians
2557 public final void rotZ(double angle)
2559 double sinAngle, cosAngle;
2561 sinAngle = Math.sin(angle);
2562 cosAngle = Math.cos(angle);
2564 this.m00 = cosAngle;
2565 this.m01 = -sinAngle;
2569 this.m10 = sinAngle;
2570 this.m11 = cosAngle;
2586 * Multiplies each element of this matrix by a scalar.
2587 * @param scalar the scalar multiplier.
2589 public final void mul(double scalar)
2610 * Multiplies each element of matrix m1 by a scalar and places
2611 * the result into this. Matrix m1 is not modified.
2612 * @param scalar the scalar multiplier
2613 * @param m1 the original matrix
2615 public final void mul(double scalar, Matrix4d m1)
2617 this.m00 = m1.m00 * scalar;
2618 this.m01 = m1.m01 * scalar;
2619 this.m02 = m1.m02 * scalar;
2620 this.m03 = m1.m03 * scalar;
2621 this.m10 = m1.m10 * scalar;
2622 this.m11 = m1.m11 * scalar;
2623 this.m12 = m1.m12 * scalar;
2624 this.m13 = m1.m13 * scalar;
2625 this.m20 = m1.m20 * scalar;
2626 this.m21 = m1.m21 * scalar;
2627 this.m22 = m1.m22 * scalar;
2628 this.m23 = m1.m23 * scalar;
2629 this.m30 = m1.m30 * scalar;
2630 this.m31 = m1.m31 * scalar;
2631 this.m32 = m1.m32 * scalar;
2632 this.m33 = m1.m33 * scalar;
2636 * Sets the value of this matrix to the result of multiplying itself
2638 * @param m1 the other matrix
2640 public final void mul(Matrix4d m1)
2642 double m00, m01, m02, m03,
2645 m30, m31, m32, m33; // vars for temp result matrix
2647 m00 = this.m00*m1.m00 + this.m01*m1.m10 +
2648 this.m02*m1.m20 + this.m03*m1.m30;
2649 m01 = this.m00*m1.m01 + this.m01*m1.m11 +
2650 this.m02*m1.m21 + this.m03*m1.m31;
2651 m02 = this.m00*m1.m02 + this.m01*m1.m12 +
2652 this.m02*m1.m22 + this.m03*m1.m32;
2653 m03 = this.m00*m1.m03 + this.m01*m1.m13 +
2654 this.m02*m1.m23 + this.m03*m1.m33;
2656 m10 = this.m10*m1.m00 + this.m11*m1.m10 +
2657 this.m12*m1.m20 + this.m13*m1.m30;
2658 m11 = this.m10*m1.m01 + this.m11*m1.m11 +
2659 this.m12*m1.m21 + this.m13*m1.m31;
2660 m12 = this.m10*m1.m02 + this.m11*m1.m12 +
2661 this.m12*m1.m22 + this.m13*m1.m32;
2662 m13 = this.m10*m1.m03 + this.m11*m1.m13 +
2663 this.m12*m1.m23 + this.m13*m1.m33;
2665 m20 = this.m20*m1.m00 + this.m21*m1.m10 +
2666 this.m22*m1.m20 + this.m23*m1.m30;
2667 m21 = this.m20*m1.m01 + this.m21*m1.m11 +
2668 this.m22*m1.m21 + this.m23*m1.m31;
2669 m22 = this.m20*m1.m02 + this.m21*m1.m12 +
2670 this.m22*m1.m22 + this.m23*m1.m32;
2671 m23 = this.m20*m1.m03 + this.m21*m1.m13 +
2672 this.m22*m1.m23 + this.m23*m1.m33;
2674 m30 = this.m30*m1.m00 + this.m31*m1.m10 +
2675 this.m32*m1.m20 + this.m33*m1.m30;
2676 m31 = this.m30*m1.m01 + this.m31*m1.m11 +
2677 this.m32*m1.m21 + this.m33*m1.m31;
2678 m32 = this.m30*m1.m02 + this.m31*m1.m12 +
2679 this.m32*m1.m22 + this.m33*m1.m32;
2680 m33 = this.m30*m1.m03 + this.m31*m1.m13 +
2681 this.m32*m1.m23 + this.m33*m1.m33;
2683 this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
2684 this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
2685 this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
2686 this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
2690 * Sets the value of this matrix to the result of multiplying
2691 * the two argument matrices together.
2692 * @param m1 the first matrix
2693 * @param m2 the second matrix
2695 public final void mul(Matrix4d m1, Matrix4d m2)
2697 if (this != m1 && this != m2) {
2699 this.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 +
2700 m1.m02*m2.m20 + m1.m03*m2.m30;
2701 this.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 +
2702 m1.m02*m2.m21 + m1.m03*m2.m31;
2703 this.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 +
2704 m1.m02*m2.m22 + m1.m03*m2.m32;
2705 this.m03 = m1.m00*m2.m03 + m1.m01*m2.m13 +
2706 m1.m02*m2.m23 + m1.m03*m2.m33;
2708 this.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 +
2709 m1.m12*m2.m20 + m1.m13*m2.m30;
2710 this.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 +
2711 m1.m12*m2.m21 + m1.m13*m2.m31;
2712 this.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 +
2713 m1.m12*m2.m22 + m1.m13*m2.m32;
2714 this.m13 = m1.m10*m2.m03 + m1.m11*m2.m13 +
2715 m1.m12*m2.m23 + m1.m13*m2.m33;
2717 this.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 +
2718 m1.m22*m2.m20 + m1.m23*m2.m30;
2719 this.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 +
2720 m1.m22*m2.m21 + m1.m23*m2.m31;
2721 this.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 +
2722 m1.m22*m2.m22 + m1.m23*m2.m32;
2723 this.m23 = m1.m20*m2.m03 + m1.m21*m2.m13 +
2724 m1.m22*m2.m23 + m1.m23*m2.m33;
2726 this.m30 = m1.m30*m2.m00 + m1.m31*m2.m10 +
2727 m1.m32*m2.m20 + m1.m33*m2.m30;
2728 this.m31 = m1.m30*m2.m01 + m1.m31*m2.m11 +
2729 m1.m32*m2.m21 + m1.m33*m2.m31;
2730 this.m32 = m1.m30*m2.m02 + m1.m31*m2.m12 +
2731 m1.m32*m2.m22 + m1.m33*m2.m32;
2732 this.m33 = m1.m30*m2.m03 + m1.m31*m2.m13 +
2733 m1.m32*m2.m23 + m1.m33*m2.m33;
2735 double m00, m01, m02, m03,
2738 m30, m31, m32, m33; // vars for temp result matrix
2741 m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20 + m1.m03*m2.m30;
2742 m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21 + m1.m03*m2.m31;
2743 m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22 + m1.m03*m2.m32;
2744 m03 = m1.m00*m2.m03 + m1.m01*m2.m13 + m1.m02*m2.m23 + m1.m03*m2.m33;
2746 m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20 + m1.m13*m2.m30;
2747 m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21 + m1.m13*m2.m31;
2748 m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22 + m1.m13*m2.m32;
2749 m13 = m1.m10*m2.m03 + m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13*m2.m33;
2751 m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20 + m1.m23*m2.m30;
2752 m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21 + m1.m23*m2.m31;
2753 m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22 + m1.m23*m2.m32;
2754 m23 = m1.m20*m2.m03 + m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23*m2.m33;
2756 m30 = m1.m30*m2.m00 + m1.m31*m2.m10 + m1.m32*m2.m20 + m1.m33*m2.m30;
2757 m31 = m1.m30*m2.m01 + m1.m31*m2.m11 + m1.m32*m2.m21 + m1.m33*m2.m31;
2758 m32 = m1.m30*m2.m02 + m1.m31*m2.m12 + m1.m32*m2.m22 + m1.m33*m2.m32;
2759 m33 = m1.m30*m2.m03 + m1.m31*m2.m13 + m1.m32*m2.m23 + m1.m33*m2.m33;
2761 this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
2762 this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
2763 this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
2764 this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
2770 * Multiplies the transpose of matrix m1 times the transpose of matrix
2771 * m2, and places the result into this.
2772 * @param m1 the matrix on the left hand side of the multiplication
2773 * @param m2 the matrix on the right hand side of the multiplication
2775 public final void mulTransposeBoth(Matrix4d m1, Matrix4d m2)
2777 if (this != m1 && this != m2) {
2778 this.m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02 + m1.m30*m2.m03;
2779 this.m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12 + m1.m30*m2.m13;
2780 this.m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22 + m1.m30*m2.m23;
2781 this.m03 = m1.m00*m2.m30 + m1.m10*m2.m31 + m1.m20*m2.m32 + m1.m30*m2.m33;
2783 this.m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02 + m1.m31*m2.m03;
2784 this.m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12 + m1.m31*m2.m13;
2785 this.m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22 + m1.m31*m2.m23;
2786 this.m13 = m1.m01*m2.m30 + m1.m11*m2.m31 + m1.m21*m2.m32 + m1.m31*m2.m33;
2788 this.m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02 + m1.m32*m2.m03;
2789 this.m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12 + m1.m32*m2.m13;
2790 this.m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22 + m1.m32*m2.m23;
2791 this.m23 = m1.m02*m2.m30 + m1.m12*m2.m31 + m1.m22*m2.m32 + m1.m32*m2.m33;
2793 this.m30 = m1.m03*m2.m00 + m1.m13*m2.m01 + m1.m23*m2.m02 + m1.m33*m2.m03;
2794 this.m31 = m1.m03*m2.m10 + m1.m13*m2.m11 + m1.m23*m2.m12 + m1.m33*m2.m13;
2795 this.m32 = m1.m03*m2.m20 + m1.m13*m2.m21 + m1.m23*m2.m22 + m1.m33*m2.m23;
2796 this.m33 = m1.m03*m2.m30 + m1.m13*m2.m31 + m1.m23*m2.m32 + m1.m33*m2.m33;
2798 double m00, m01, m02, m03,
2800 m20, m21, m22, m23, // vars for temp result matrix
2803 m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02 + m1.m30*m2.m03;
2804 m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12 + m1.m30*m2.m13;
2805 m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22 + m1.m30*m2.m23;
2806 m03 = m1.m00*m2.m30 + m1.m10*m2.m31 + m1.m20*m2.m32 + m1.m30*m2.m33;
2808 m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02 + m1.m31*m2.m03;
2809 m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12 + m1.m31*m2.m13;
2810 m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22 + m1.m31*m2.m23;
2811 m13 = m1.m01*m2.m30 + m1.m11*m2.m31 + m1.m21*m2.m32 + m1.m31*m2.m33;
2813 m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02 + m1.m32*m2.m03;
2814 m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12 + m1.m32*m2.m13;
2815 m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22 + m1.m32*m2.m23;
2816 m23 = m1.m02*m2.m30 + m1.m12*m2.m31 + m1.m22*m2.m32 + m1.m32*m2.m33;
2818 m30 = m1.m03*m2.m00 + m1.m13*m2.m01 + m1.m23*m2.m02 + m1.m33*m2.m03;
2819 m31 = m1.m03*m2.m10 + m1.m13*m2.m11 + m1.m23*m2.m12 + m1.m33*m2.m13;
2820 m32 = m1.m03*m2.m20 + m1.m13*m2.m21 + m1.m23*m2.m22 + m1.m33*m2.m23;
2821 m33 = m1.m03*m2.m30 + m1.m13*m2.m31 + m1.m23*m2.m32 + m1.m33*m2.m33;
2823 this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
2824 this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
2825 this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
2826 this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
2834 * Multiplies matrix m1 times the transpose of matrix m2, and
2835 * places the result into this.
2836 * @param m1 the matrix on the left hand side of the multiplication
2837 * @param m2 the matrix on the right hand side of the multiplication
2839 public final void mulTransposeRight(Matrix4d m1, Matrix4d m2)
2841 if (this != m1 && this != m2) {
2842 this.m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02 + m1.m03*m2.m03;
2843 this.m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12 + m1.m03*m2.m13;
2844 this.m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22 + m1.m03*m2.m23;
2845 this.m03 = m1.m00*m2.m30 + m1.m01*m2.m31 + m1.m02*m2.m32 + m1.m03*m2.m33;
2847 this.m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02 + m1.m13*m2.m03;
2848 this.m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12 + m1.m13*m2.m13;
2849 this.m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22 + m1.m13*m2.m23;
2850 this.m13 = m1.m10*m2.m30 + m1.m11*m2.m31 + m1.m12*m2.m32 + m1.m13*m2.m33;
2852 this.m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02 + m1.m23*m2.m03;
2853 this.m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12 + m1.m23*m2.m13;
2854 this.m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22 + m1.m23*m2.m23;
2855 this.m23 = m1.m20*m2.m30 + m1.m21*m2.m31 + m1.m22*m2.m32 + m1.m23*m2.m33;
2857 this.m30 = m1.m30*m2.m00 + m1.m31*m2.m01 + m1.m32*m2.m02 + m1.m33*m2.m03;
2858 this.m31 = m1.m30*m2.m10 + m1.m31*m2.m11 + m1.m32*m2.m12 + m1.m33*m2.m13;
2859 this.m32 = m1.m30*m2.m20 + m1.m31*m2.m21 + m1.m32*m2.m22 + m1.m33*m2.m23;
2860 this.m33 = m1.m30*m2.m30 + m1.m31*m2.m31 + m1.m32*m2.m32 + m1.m33*m2.m33;
2862 double m00, m01, m02, m03,
2864 m20, m21, m22, m23, // vars for temp result matrix
2867 m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02 + m1.m03*m2.m03;
2868 m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12 + m1.m03*m2.m13;
2869 m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22 + m1.m03*m2.m23;
2870 m03 = m1.m00*m2.m30 + m1.m01*m2.m31 + m1.m02*m2.m32 + m1.m03*m2.m33;
2872 m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02 + m1.m13*m2.m03;
2873 m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12 + m1.m13*m2.m13;
2874 m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22 + m1.m13*m2.m23;
2875 m13 = m1.m10*m2.m30 + m1.m11*m2.m31 + m1.m12*m2.m32 + m1.m13*m2.m33;
2877 m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02 + m1.m23*m2.m03;
2878 m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12 + m1.m23*m2.m13;
2879 m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22 + m1.m23*m2.m23;
2880 m23 = m1.m20*m2.m30 + m1.m21*m2.m31 + m1.m22*m2.m32 + m1.m23*m2.m33;
2882 m30 = m1.m30*m2.m00 + m1.m31*m2.m01 + m1.m32*m2.m02 + m1.m33*m2.m03;
2883 m31 = m1.m30*m2.m10 + m1.m31*m2.m11 + m1.m32*m2.m12 + m1.m33*m2.m13;
2884 m32 = m1.m30*m2.m20 + m1.m31*m2.m21 + m1.m32*m2.m22 + m1.m33*m2.m23;
2885 m33 = m1.m30*m2.m30 + m1.m31*m2.m31 + m1.m32*m2.m32 + m1.m33*m2.m33;
2887 this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
2888 this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
2889 this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
2890 this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
2896 * Multiplies the transpose of matrix m1 times matrix m2, and
2897 * places the result into this.
2898 * @param m1 the matrix on the left hand side of the multiplication
2899 * @param m2 the matrix on the right hand side of the multiplication
2901 public final void mulTransposeLeft(Matrix4d m1, Matrix4d m2)
2903 if (this != m1 && this != m2) {
2904 this.m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20 + m1.m30*m2.m30;
2905 this.m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21 + m1.m30*m2.m31;
2906 this.m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22 + m1.m30*m2.m32;
2907 this.m03 = m1.m00*m2.m03 + m1.m10*m2.m13 + m1.m20*m2.m23 + m1.m30*m2.m33;
2909 this.m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20 + m1.m31*m2.m30;
2910 this.m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21 + m1.m31*m2.m31;
2911 this.m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22 + m1.m31*m2.m32;
2912 this.m13 = m1.m01*m2.m03 + m1.m11*m2.m13 + m1.m21*m2.m23 + m1.m31*m2.m33;
2914 this.m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20 + m1.m32*m2.m30;
2915 this.m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21 + m1.m32*m2.m31;
2916 this.m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22 + m1.m32*m2.m32;
2917 this.m23 = m1.m02*m2.m03 + m1.m12*m2.m13 + m1.m22*m2.m23 + m1.m32*m2.m33;
2919 this.m30 = m1.m03*m2.m00 + m1.m13*m2.m10 + m1.m23*m2.m20 + m1.m33*m2.m30;
2920 this.m31 = m1.m03*m2.m01 + m1.m13*m2.m11 + m1.m23*m2.m21 + m1.m33*m2.m31;
2921 this.m32 = m1.m03*m2.m02 + m1.m13*m2.m12 + m1.m23*m2.m22 + m1.m33*m2.m32;
2922 this.m33 = m1.m03*m2.m03 + m1.m13*m2.m13 + m1.m23*m2.m23 + m1.m33*m2.m33;
2924 double m00, m01, m02, m03,
2926 m20, m21, m22, m23, // vars for temp result matrix
2931 m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20 + m1.m30*m2.m30;
2932 m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21 + m1.m30*m2.m31;
2933 m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22 + m1.m30*m2.m32;
2934 m03 = m1.m00*m2.m03 + m1.m10*m2.m13 + m1.m20*m2.m23 + m1.m30*m2.m33;
2936 m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20 + m1.m31*m2.m30;
2937 m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21 + m1.m31*m2.m31;
2938 m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22 + m1.m31*m2.m32;
2939 m13 = m1.m01*m2.m03 + m1.m11*m2.m13 + m1.m21*m2.m23 + m1.m31*m2.m33;
2941 m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20 + m1.m32*m2.m30;
2942 m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21 + m1.m32*m2.m31;
2943 m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22 + m1.m32*m2.m32;
2944 m23 = m1.m02*m2.m03 + m1.m12*m2.m13 + m1.m22*m2.m23 + m1.m32*m2.m33;
2946 m30 = m1.m03*m2.m00 + m1.m13*m2.m10 + m1.m23*m2.m20 + m1.m33*m2.m30;
2947 m31 = m1.m03*m2.m01 + m1.m13*m2.m11 + m1.m23*m2.m21 + m1.m33*m2.m31;
2948 m32 = m1.m03*m2.m02 + m1.m13*m2.m12 + m1.m23*m2.m22 + m1.m33*m2.m32;
2949 m33 = m1.m03*m2.m03 + m1.m13*m2.m13 + m1.m23*m2.m23 + m1.m33*m2.m33;
2951 this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
2952 this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
2953 this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
2954 this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
2961 * Returns true if all of the data members of Matrix4d m1 are
2962 * equal to the corresponding data members in this Matrix4d.
2963 * @param m1 the matrix with which the comparison is made
2964 * @return true or false
2966 public boolean equals(Matrix4d m1)
2969 return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
2970 && this.m03 == m1.m03 && this.m10 == m1.m10 && this.m11 == m1.m11
2971 && this.m12 == m1.m12 && this.m13 == m1.m13 && this.m20 == m1.m20
2972 && this.m21 == m1.m21 && this.m22 == m1.m22 && this.m23 == m1.m23
2973 && this.m30 == m1.m30 && this.m31 == m1.m31 && this.m32 == m1.m32
2974 && this.m33 == m1.m33);
2976 catch (NullPointerException e2) { return false; }
2981 * Returns true if the Object t1 is of type Matrix4d and all of the
2982 * data members of t1 are equal to the corresponding data members in
2984 * @param t1 the matrix with which the comparison is made
2985 * @return true or false
2987 public boolean equals(Object t1)
2990 Matrix4d m2 = (Matrix4d) t1;
2991 return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
2992 && this.m03 == m2.m03 && this.m10 == m2.m10 && this.m11 == m2.m11
2993 && this.m12 == m2.m12 && this.m13 == m2.m13 && this.m20 == m2.m20
2994 && this.m21 == m2.m21 && this.m22 == m2.m22 && this.m23 == m2.m23
2995 && this.m30 == m2.m30 && this.m31 == m2.m31 && this.m32 == m2.m32
2996 && this.m33 == m2.m33);
2998 catch (ClassCastException e1) { return false; }
2999 catch (NullPointerException e2) { return false; }
3003 * @deprecated Use epsilonEquals(Matrix4d,double) instead
3005 public boolean epsilonEquals(Matrix4d m1, float epsilon) {
3006 return epsilonEquals(m1, (double)epsilon);
3010 * Returns true if the L-infinite distance between this matrix
3011 * and matrix m1 is less than or equal to the epsilon parameter,
3012 * otherwise returns false. The L-infinite
3013 * distance is equal to
3014 * MAX[i=0,1,2,3 ; j=0,1,2,3 ; abs(this.m(i,j) - m1.m(i,j)]
3015 * @param m1 the matrix to be compared to this matrix
3016 * @param epsilon the threshold value
3018 public boolean epsilonEquals(Matrix4d m1, double epsilon) {
3021 diff = m00 - m1.m00;
3022 if((diff<0?-diff:diff) > epsilon) return false;
3024 diff = m01 - m1.m01;
3025 if((diff<0?-diff:diff) > epsilon) return false;
3027 diff = m02 - m1.m02;
3028 if((diff<0?-diff:diff) > epsilon) return false;
3030 diff = m03 - m1.m03;
3031 if((diff<0?-diff:diff) > epsilon) return false;
3033 diff = m10 - m1.m10;
3034 if((diff<0?-diff:diff) > epsilon) return false;
3036 diff = m11 - m1.m11;
3037 if((diff<0?-diff:diff) > epsilon) return false;
3039 diff = m12 - m1.m12;
3040 if((diff<0?-diff:diff) > epsilon) return false;
3042 diff = m13 - m1.m13;
3043 if((diff<0?-diff:diff) > epsilon) return false;
3045 diff = m20 - m1.m20;
3046 if((diff<0?-diff:diff) > epsilon) return false;
3048 diff = m21 - m1.m21;
3049 if((diff<0?-diff:diff) > epsilon) return false;
3051 diff = m22 - m1.m22;
3052 if((diff<0?-diff:diff) > epsilon) return false;
3054 diff = m23 - m1.m23;
3055 if((diff<0?-diff:diff) > epsilon) return false;
3057 diff = m30 - m1.m30;
3058 if((diff<0?-diff:diff) > epsilon) return false;
3060 diff = m31 - m1.m31;
3061 if((diff<0?-diff:diff) > epsilon) return false;
3063 diff = m32 - m1.m32;
3064 if((diff<0?-diff:diff) > epsilon) return false;
3066 diff = m33 - m1.m33;
3067 if((diff<0?-diff:diff) > epsilon) return false;
3073 * Returns a hash code value based on the data values in this
3074 * object. Two different Matrix4d objects with identical data values
3075 * (i.e., Matrix4d.equals returns true) will return the same hash
3076 * code value. Two objects with different data members may return the
3077 * same hash value, although this is not likely.
3078 * @return the integer hash code value
3080 public int hashCode() {
3082 bits = 31L * bits + VecMathUtil.doubleToLongBits(m00);
3083 bits = 31L * bits + VecMathUtil.doubleToLongBits(m01);
3084 bits = 31L * bits + VecMathUtil.doubleToLongBits(m02);
3085 bits = 31L * bits + VecMathUtil.doubleToLongBits(m03);
3086 bits = 31L * bits + VecMathUtil.doubleToLongBits(m10);
3087 bits = 31L * bits + VecMathUtil.doubleToLongBits(m11);
3088 bits = 31L * bits + VecMathUtil.doubleToLongBits(m12);
3089 bits = 31L * bits + VecMathUtil.doubleToLongBits(m13);
3090 bits = 31L * bits + VecMathUtil.doubleToLongBits(m20);
3091 bits = 31L * bits + VecMathUtil.doubleToLongBits(m21);
3092 bits = 31L * bits + VecMathUtil.doubleToLongBits(m22);
3093 bits = 31L * bits + VecMathUtil.doubleToLongBits(m23);
3094 bits = 31L * bits + VecMathUtil.doubleToLongBits(m30);
3095 bits = 31L * bits + VecMathUtil.doubleToLongBits(m31);
3096 bits = 31L * bits + VecMathUtil.doubleToLongBits(m32);
3097 bits = 31L * bits + VecMathUtil.doubleToLongBits(m33);
3098 return (int) (bits ^ (bits >> 32));
3103 * Transform the vector vec using this Matrix4d and place the
3104 * result into vecOut.
3105 * @param vec the double precision vector to be transformed
3106 * @param vecOut the vector into which the transformed values are placed
3108 public final void transform(Tuple4d vec, Tuple4d vecOut)
3111 x = (m00*vec.x + m01*vec.y
3112 + m02*vec.z + m03*vec.w);
3113 y = (m10*vec.x + m11*vec.y
3114 + m12*vec.z + m13*vec.w);
3115 z = (m20*vec.x + m21*vec.y
3116 + m22*vec.z + m23*vec.w);
3117 vecOut.w = (m30*vec.x + m31*vec.y
3118 + m32*vec.z + m33*vec.w);
3125 * Transform the vector vec using this Matrix4d and place the
3126 * result back into vec.
3127 * @param vec the double precision vector to be transformed
3129 public final void transform(Tuple4d vec)
3133 x = (m00*vec.x + m01*vec.y
3134 + m02*vec.z + m03*vec.w);
3135 y = (m10*vec.x + m11*vec.y
3136 + m12*vec.z + m13*vec.w);
3137 z = (m20*vec.x + m21*vec.y
3138 + m22*vec.z + m23*vec.w);
3139 vec.w = (m30*vec.x + m31*vec.y
3140 + m32*vec.z + m33*vec.w);
3147 * Transform the vector vec using this Matrix4d and place the
3148 * result into vecOut.
3149 * @param vec the single precision vector to be transformed
3150 * @param vecOut the vector into which the transformed values are placed
3152 public final void transform(Tuple4f vec, Tuple4f vecOut)
3155 x = (float) (m00*vec.x + m01*vec.y
3156 + m02*vec.z + m03*vec.w);
3157 y = (float) (m10*vec.x + m11*vec.y
3158 + m12*vec.z + m13*vec.w);
3159 z = (float) (m20*vec.x + m21*vec.y
3160 + m22*vec.z + m23*vec.w);
3161 vecOut.w = (float) (m30*vec.x + m31*vec.y
3162 + m32*vec.z + m33*vec.w);
3169 * Transform the vector vec using this Transform and place the
3170 * result back into vec.
3171 * @param vec the single precision vector to be transformed
3173 public final void transform(Tuple4f vec)
3177 x = (float) (m00*vec.x + m01*vec.y
3178 + m02*vec.z + m03*vec.w);
3179 y = (float) (m10*vec.x + m11*vec.y
3180 + m12*vec.z + m13*vec.w);
3181 z = (float) (m20*vec.x + m21*vec.y
3182 + m22*vec.z + m23*vec.w);
3183 vec.w = (float) (m30*vec.x + m31*vec.y
3184 + m32*vec.z + m33*vec.w);
3192 * Transforms the point parameter with this Matrix4d and
3193 * places the result into pointOut. The fourth element of the
3194 * point input parameter is assumed to be one.
3195 * @param point the input point to be transformed.
3196 * @param pointOut the transformed point
3198 public final void transform(Point3d point, Point3d pointOut)
3201 x = m00*point.x + m01*point.y + m02*point.z + m03;
3202 y = m10*point.x + m11*point.y + m12*point.z + m13;
3203 pointOut.z = m20*point.x + m21*point.y + m22*point.z + m23;
3211 * Transforms the point parameter with this Matrix4d and
3212 * places the result back into point. The fourth element of the
3213 * point input parameter is assumed to be one.
3214 * @param point the input point to be transformed.
3216 public final void transform(Point3d point)
3219 x = m00*point.x + m01*point.y + m02*point.z + m03;
3220 y = m10*point.x + m11*point.y + m12*point.z + m13;
3221 point.z = m20*point.x + m21*point.y + m22*point.z + m23;
3228 * Transforms the point parameter with this Matrix4d and
3229 * places the result into pointOut. The fourth element of the
3230 * point input parameter is assumed to be one.
3231 * @param point the input point to be transformed.
3232 * @param pointOut the transformed point
3234 public final void transform(Point3f point, Point3f pointOut)
3238 x = (float) (m00*point.x + m01*point.y + m02*point.z + m03);
3239 y = (float) (m10*point.x + m11*point.y + m12*point.z + m13);
3240 pointOut.z = (float) (m20*point.x + m21*point.y + m22*point.z + m23);
3247 * Transforms the point parameter with this Matrix4d and
3248 * places the result back into point. The fourth element of the
3249 * point input parameter is assumed to be one.
3250 * @param point the input point to be transformed.
3252 public final void transform(Point3f point)
3255 x = (float) (m00*point.x + m01*point.y + m02*point.z + m03);
3256 y = (float) (m10*point.x + m11*point.y + m12*point.z + m13);
3257 point.z = (float) (m20*point.x + m21*point.y + m22*point.z + m23);
3264 * Transforms the normal parameter by this Matrix4d and places the value
3265 * into normalOut. The fourth element of the normal is assumed to be zero.
3266 * @param normal the input normal to be transformed.
3267 * @param normalOut the transformed normal
3269 public final void transform(Vector3d normal, Vector3d normalOut)
3272 x = m00*normal.x + m01*normal.y + m02*normal.z;
3273 y = m10*normal.x + m11*normal.y + m12*normal.z;
3274 normalOut.z = m20*normal.x + m21*normal.y + m22*normal.z;
3281 * Transforms the normal parameter by this transform and places the value
3282 * back into normal. The fourth element of the normal is assumed to be zero.
3283 * @param normal the input normal to be transformed.
3285 public final void transform(Vector3d normal)
3289 x = m00*normal.x + m01*normal.y + m02*normal.z;
3290 y = m10*normal.x + m11*normal.y + m12*normal.z;
3291 normal.z = m20*normal.x + m21*normal.y + m22*normal.z;
3298 * Transforms the normal parameter by this Matrix4d and places the value
3299 * into normalOut. The fourth element of the normal is assumed to be zero.
3300 * @param normal the input normal to be transformed.
3301 * @param normalOut the transformed normal
3303 public final void transform(Vector3f normal, Vector3f normalOut)
3306 x = (float) (m00*normal.x + m01*normal.y + m02*normal.z);
3307 y = (float) (m10*normal.x + m11*normal.y + m12*normal.z);
3308 normalOut.z = (float) (m20*normal.x + m21*normal.y + m22*normal.z);
3315 * Transforms the normal parameter by this transform and places the value
3316 * back into normal. The fourth element of the normal is assumed to be zero.
3317 * @param normal the input normal to be transformed.
3319 public final void transform(Vector3f normal)
3323 x = (float) (m00*normal.x + m01*normal.y + m02*normal.z);
3324 y = (float) (m10*normal.x + m11*normal.y + m12*normal.z);
3325 normal.z = (float) (m20*normal.x + m21*normal.y + m22*normal.z);
3331 * Sets the rotational component (upper 3x3) of this matrix to the
3332 * matrix values in the double precision Matrix3d argument; the other
3333 * elements of this matrix are unchanged; a singular value
3334 * decomposition is performed on this object's upper 3x3 matrix to
3335 * factor out the scale, then this object's upper 3x3 matrix components
3336 * are replaced by the passed rotation components,
3337 * and then the scale is reapplied to the rotational components.
3338 * @param m1 double precision 3x3 matrix
3340 public final void setRotation( Matrix3d m1){
3341 double[] tmp_rot = new double[9]; // scratch matrix
3342 double[] tmp_scale = new double[3]; // scratch matrix
3344 getScaleRotate( tmp_scale, tmp_rot );
3346 m00 = m1.m00*tmp_scale[0];
3347 m01 = m1.m01*tmp_scale[1];
3348 m02 = m1.m02*tmp_scale[2];
3350 m10 = m1.m10*tmp_scale[0];
3351 m11 = m1.m11*tmp_scale[1];
3352 m12 = m1.m12*tmp_scale[2];
3354 m20 = m1.m20*tmp_scale[0];
3355 m21 = m1.m21*tmp_scale[1];
3356 m22 = m1.m22*tmp_scale[2];
3362 * Sets the rotational component (upper 3x3) of this matrix to the
3363 * matrix values in the single precision Matrix3f argument; the other
3364 * elements of this matrix are unchanged; a singular value
3365 * decomposition is performed on this object's upper 3x3 matrix to
3366 * factor out the scale, then this object's upper 3x3 matrix components
3367 * are replaced by the passed rotation components,
3368 * and then the scale is reapplied to the rotational components.
3369 * @param m1 single precision 3x3 matrix
3371 public final void setRotation( Matrix3f m1)
3374 double[] tmp_rot = new double[9]; // scratch matrix
3375 double[] tmp_scale = new double[3]; // scratch matrix
3376 getScaleRotate( tmp_scale, tmp_rot );
3378 m00 = m1.m00*tmp_scale[0];
3379 m01 = m1.m01*tmp_scale[1];
3380 m02 = m1.m02*tmp_scale[2];
3382 m10 = m1.m10*tmp_scale[0];
3383 m11 = m1.m11*tmp_scale[1];
3384 m12 = m1.m12*tmp_scale[2];
3386 m20 = m1.m20*tmp_scale[0];
3387 m21 = m1.m21*tmp_scale[1];
3388 m22 = m1.m22*tmp_scale[2];
3392 * Sets the rotational component (upper 3x3) of this matrix to the
3393 * matrix equivalent values of the quaternion argument; the other
3394 * elements of this matrix are unchanged; a singular value
3395 * decomposition is performed on this object's upper 3x3 matrix to
3396 * factor out the scale, then this object's upper 3x3 matrix components
3397 * are replaced by the matrix equivalent of the quaternion,
3398 * and then the scale is reapplied to the rotational components.
3399 * @param q1 the quaternion that specifies the rotation
3401 public final void setRotation(Quat4f q1){
3402 double[] tmp_rot = new double[9]; // scratch matrix
3403 double[] tmp_scale = new double[3]; // scratch matrix
3404 getScaleRotate( tmp_scale, tmp_rot );
3406 m00 = (1.0 - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z)*tmp_scale[0];
3407 m10 = (2.0*(q1.x*q1.y + q1.w*q1.z))*tmp_scale[0];
3408 m20 = (2.0*(q1.x*q1.z - q1.w*q1.y))*tmp_scale[0];
3410 m01 = (2.0*(q1.x*q1.y - q1.w*q1.z))*tmp_scale[1];
3411 m11 = (1.0 - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z)*tmp_scale[1];
3412 m21 = (2.0*(q1.y*q1.z + q1.w*q1.x))*tmp_scale[1];
3414 m02 = (2.0*(q1.x*q1.z + q1.w*q1.y))*tmp_scale[2];
3415 m12 = (2.0*(q1.y*q1.z - q1.w*q1.x))*tmp_scale[2];
3416 m22 = (1.0 - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y)*tmp_scale[2];
3422 * Sets the rotational component (upper 3x3) of this matrix to the
3423 * matrix equivalent values of the quaternion argument; the other
3424 * elements of this matrix are unchanged; a singular value
3425 * decomposition is performed on this object's upper 3x3 matrix to
3426 * factor out the scale, then this object's upper 3x3 matrix components
3427 * are replaced by the matrix equivalent of the quaternion,
3428 * and then the scale is reapplied to the rotational components.
3429 * @param q1 the quaternion that specifies the rotation
3431 public final void setRotation(Quat4d q1){
3433 double[] tmp_rot = new double[9]; // scratch matrix
3434 double[] tmp_scale = new double[3]; // scratch matrix
3435 getScaleRotate( tmp_scale, tmp_rot );
3437 m00 = (1.0 - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z)*tmp_scale[0];
3438 m10 = (2.0*(q1.x*q1.y + q1.w*q1.z))*tmp_scale[0];
3439 m20 = (2.0*(q1.x*q1.z - q1.w*q1.y))*tmp_scale[0];
3441 m01 = (2.0*(q1.x*q1.y - q1.w*q1.z))*tmp_scale[1];
3442 m11 = (1.0 - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z)*tmp_scale[1];
3443 m21 = (2.0*(q1.y*q1.z + q1.w*q1.x))*tmp_scale[1];
3445 m02 = (2.0*(q1.x*q1.z + q1.w*q1.y))*tmp_scale[2];
3446 m12 = (2.0*(q1.y*q1.z - q1.w*q1.x))*tmp_scale[2];
3447 m22 = (1.0 - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y)*tmp_scale[2];
3452 * Sets the rotational component (upper 3x3) of this matrix to the
3453 * matrix equivalent values of the axis-angle argument; the other
3454 * elements of this matrix are unchanged; a singular value
3455 * decomposition is performed on this object's upper 3x3 matrix to
3456 * factor out the scale, then this object's upper 3x3 matrix components
3457 * are replaced by the matrix equivalent of the axis-angle,
3458 * and then the scale is reapplied to the rotational components.
3459 * @param a1 the axis-angle to be converted (x, y, z, angle)
3461 public final void setRotation(AxisAngle4d a1)
3463 double[] tmp_rot = new double[9]; // scratch matrix
3464 double[] tmp_scale = new double[3]; // scratch matrix
3466 getScaleRotate( tmp_scale, tmp_rot );
3468 double mag = 1.0/Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
3469 double ax = a1.x*mag;
3470 double ay = a1.y*mag;
3471 double az = a1.z*mag;
3473 double sinTheta = Math.sin(a1.angle);
3474 double cosTheta = Math.cos(a1.angle);
3475 double t = 1.0 - cosTheta;
3477 double xz = a1.x * a1.z;
3478 double xy = a1.x * a1.y;
3479 double yz = a1.y * a1.z;
3481 m00 = (t * ax * ax + cosTheta)*tmp_scale[0];
3482 m01 = (t * xy - sinTheta * az)*tmp_scale[1];
3483 m02 = (t * xz + sinTheta * ay)*tmp_scale[2];
3485 m10 = (t * xy + sinTheta * az)*tmp_scale[0];
3486 m11 = (t * ay * ay + cosTheta)*tmp_scale[1];
3487 m12 = (t * yz - sinTheta * ax)*tmp_scale[2];
3489 m20 = (t * xz - sinTheta * ay)*tmp_scale[0];
3490 m21 = (t * yz + sinTheta * ax)*tmp_scale[1];
3491 m22 = (t * az * az + cosTheta)*tmp_scale[2];
3496 * Sets this matrix to all zeros.
3498 public final void setZero()
3519 * Negates the value of this matrix: this = -this.
3521 public final void negate()
3542 * Sets the value of this matrix equal to the negation of
3543 * of the Matrix4d parameter.
3544 * @param m1 the source matrix
3546 public final void negate(Matrix4d m1)
3565 private final void getScaleRotate(double scales[], double rots[]) {
3566 double[] tmp = new double[9]; // scratch matrix
3579 Matrix3d.compute_svd( tmp, scales, rots);
3585 * Creates a new object of the same class as this object.
3587 * @return a clone of this instance.
3588 * @exception OutOfMemoryError if there is not enough memory.
3589 * @see java.lang.Cloneable
3590 * @since vecmath 1.3
3592 public Object clone() {
3595 m1 = (Matrix4d)super.clone();
3596 } catch (CloneNotSupportedException e) {
3597 // this shouldn't happen, since we are Cloneable
3598 throw new InternalError();
3605 * Get the first matrix element in the first row.
3607 * @return Returns the m00.
3609 * @since vecmath 1.5
3611 public final double getM00() {
3616 * Set the first matrix element in the first row.
3618 * @param m00 The m00 to set.
3621 * @since vecmath 1.5
3623 public final void setM00(double m00) {
3628 * Get the second matrix element in the first row.
3630 * @return Returns the m01.
3632 * @since vecmath 1.5
3634 public final double getM01() {
3639 * Set the second matrix element in the first row.
3641 * @param m01 The m01 to set.
3643 * @since vecmath 1.5
3645 public final void setM01(double m01) {
3650 * Get the third matrix element in the first row.
3652 * @return Returns the m02.
3654 * @since vecmath 1.5
3656 public final double getM02() {
3661 * Set the third matrix element in the first row.
3663 * @param m02 The m02 to set.
3665 * @since vecmath 1.5
3667 public final void setM02(double m02) {
3672 * Get first matrix element in the second row.
3674 * @return Returns the m10.
3676 * @since vecmath 1.5
3678 public final double getM10() {
3683 * Set first matrix element in the second row.
3685 * @param m10 The m10 to set.
3687 * @since vecmath 1.5
3689 public final void setM10(double m10) {
3694 * Get second matrix element in the second row.
3696 * @return Returns the m11.
3698 * @since vecmath 1.5
3700 public final double getM11() {
3705 * Set the second matrix element in the second row.
3707 * @param m11 The m11 to set.
3709 * @since vecmath 1.5
3711 public final void setM11(double m11) {
3716 * Get the third matrix element in the second row.
3718 * @return Returns the m12.
3720 * @since vecmath 1.5
3722 public final double getM12() {
3727 * Set the third matrix element in the second row.
3729 * @param m12 The m12 to set.
3732 * @since vecmath 1.5
3734 public final void setM12(double m12) {
3739 * Get the first matrix element in the third row.
3741 * @return Returns the m20.
3743 * @since vecmath 1.5
3745 public final double getM20() {
3750 * Set the first matrix element in the third row.
3752 * @param m20 The m20 to set.
3754 * @since vecmath 1.5
3756 public final void setM20(double m20) {
3761 * Get the second matrix element in the third row.
3763 * @return Returns the m21.
3765 * @since vecmath 1.5
3767 public final double getM21() {
3772 * Set the second matrix element in the third row.
3774 * @param m21 The m21 to set.
3776 * @since vecmath 1.5
3778 public final void setM21(double m21) {
3783 * Get the third matrix element in the third row.
3785 * @return Returns the m22.
3787 * @since vecmath 1.5
3789 public final double getM22() {
3794 * Set the third matrix element in the third row.
3796 * @param m22 The m22 to set.
3798 * @since vecmath 1.5
3800 public final void setM22(double m22) {
3805 * Get the fourth element of the first row.
3807 * @return Returns the m03.
3809 * @since vecmath 1.5
3811 public final double getM03() {
3816 * Set the fourth element of the first row.
3818 * @param m03 The m03 to set.
3820 * @since vecmath 1.5
3822 public final void setM03(double m03) {
3827 * Get the fourth element of the second row.
3829 * @return Returns the m13.
3831 * @since vecmath 1.5
3833 public final double getM13() {
3838 * Set the fourth element of the second row.
3840 * @param m13 The m13 to set.
3842 * @since vecmath 1.5
3844 public final void setM13(double m13) {
3849 * Get the fourth element of the third row.
3851 * @return Returns the m23.
3853 * @since vecmath 1.5
3855 public final double getM23() {
3860 * Set the fourth element of the third row.
3862 * @param m23 The m23 to set.
3864 * @since vecmath 1.5
3866 public final void setM23(double m23) {
3871 * Get the first element of the fourth row.
3873 * @return Returns the m30.
3875 * @since vecmath 1.5
3877 public final double getM30() {
3882 * Set the first element of the fourth row.
3884 * @param m30 The m30 to set.
3886 * @since vecmath 1.5
3888 public final void setM30(double m30) {
3893 * Get the second element of the fourth row.
3895 * @return Returns the m31.
3897 * @since vecmath 1.5
3899 public final double getM31() {
3904 * Set the second element of the fourth row.
3906 * @param m31 The m31 to set.
3908 * @since vecmath 1.5
3910 public final void setM31(double m31) {
3915 * Get the third element of the fourth row.
3917 * @return Returns the m32.
3920 * @since vecmath 1.5
3922 public final double getM32() {
3927 * Set the third element of the fourth row.
3929 * @param m32 The m32 to set.
3931 * @since vecmath 1.5
3933 public final void setM32(double m32) {
3938 * Get the fourth element of the fourth row.
3940 * @return Returns the m33.
3942 * @since vecmath 1.5
3944 public final double getM33() {
3949 * Set the fourth element of the fourth row.
3951 * @param m33 The m33 to set.
3953 * @since vecmath 1.5
3955 public final void setM33(double m33) {