package matrix; import java.lang.Math; // Matrix3D for making transformations // to 3D Vectors (Vector3D) // including rotations and scales. // These transformation can be applied // on other transformation to make composite // transformations. public class Matrix3D extends Matrix { public Matrix3D() { super(3); //{{INIT_CONTROLS //}} } public Matrix3D(Matrix M) throws MatrixDimensionError { super(3); copy(M); } // promote a Matrix2D to a Matrix3D as: // M M 0 // M M 0 // 0 0 1 public Matrix3D(Matrix2D M) { super(3); subcopy(M); } // create a transformation matrix which when applied // to a Vector3D(X, Y, Z) yeilds Vector3D(X*x, Y*y, Z*z). public static Matrix3D scale(double x, double y, double z) { Matrix3D scale = new Matrix3D(); scale.setCell(0, 0, x); scale.setCell(1, 1, y); scale.setCell(2, 2, y); return scale; } public static Matrix3D scale(Vector3D v) { return scale(v.x(), v.y(), v.z()); } // create a transformation matrix which rotates // a Vector3D in a right-handed way about the x-axis public static Matrix3D rotateX(double radians) { Matrix3D rot = new Matrix3D(); double cosine = Math.cos(radians); double sine = Math.sin(radians); rot.setCell(1, 1, cosine); rot.setCell(1, 2, sine); rot.setCell(2, 1, -sine); rot.setCell(2, 2, cosine); return rot; } // create a transformation matrix which rotates // a Vector3D in a right-handed way about the y-axis public static Matrix3D rotateY(double radians) { Matrix3D rot = new Matrix3D(); double cosine = Math.cos(radians); double sine = Math.sin(radians); rot.setCell(2, 2, cosine); rot.setCell(2, 0, sine); rot.setCell(0, 2, -sine); rot.setCell(0, 0, cosine); return rot; } // create a transformation matrix which rotates // a Vector3D in a right-handed way about the z-axis public static Matrix3D rotateZ(double radians) { Matrix3D rot = new Matrix3D(); double cosine = Math.cos(radians); double sine = Math.sin(radians); rot.setCell(0, 0, cosine); rot.setCell(0, 1, sine); rot.setCell(1, 0, -sine); rot.setCell(1, 1, cosine); return rot; } // create a rotation transformation matrix // rotates v to the positive z-direction. public static Matrix3D rotateToZ(Vector3D v) { double xang = Math.atan2(v.x(), v.z()); double yang = Math.atan2(v.y(), Math.pow(v.z() * v.z() + v.x() * v.x(), .5)); return rotateX(yang).applyOn(rotateY(-xang)); } public static Matrix3D rotate(Vector3D v, double radians) { Matrix3D rotToZ; Matrix3D rotToZInv; double xang = Math.atan2(v.x(), v.z()); double yang = Math.atan2(v.y(), Math.pow(v.z() * v.z() + v.x() * v.x(), .5)); rotToZ = rotateX(yang).applyOn(rotateY(-xang)); rotToZInv = rotateY(xang).applyOn(rotateX(-yang)); return rotToZInv.applyOn(rotateZ(radians)).applyOn(rotToZ); } /* scalar multiplication */ public static Matrix3D mult(Matrix3D M, double a) { Matrix3D result = new Matrix3D(); result.copy(M); result.selfMult(a); return result; } public Matrix mult(double a) { return mult(this, a); } /* vector multiplication */ public Vector3D applyOn(Vector3D v2) { // equivalent to Vector3D(Matrix.mult(this, v2) // but optimized for the 2D case and no conversion needed. return new Vector3D(cell(0, 0) * v2.x() + cell(1, 0) * v2.y() + cell(2, 0) * v2.z(), cell(0, 1) * v2.x() + cell(1, 1) * v2.y() + cell(2, 1) * v2.z(), cell(0, 2) * v2.x() + cell(1, 2) * v2.y() + cell(2, 2) * v2.z()); } /* matrix multiplication */ public Matrix3D applyOn(Matrix3D M2) { // equivalent to Matrix3D(Matrix.mult(this, N2)) // but optimized for the 3D case and no conversion needed. Matrix3D result = new Matrix3D(); for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) result.setCell(i, j, cell(0, j) * M2.cell(i, 0) + cell(1, j) * M2.cell(i, 1) + cell(2, j) * M2.cell(i, 2)); return result; } public Matrix3Dh applyOn(Matrix3Dh M2) { // equivalent to Matrix3Dh(Matrix.mult(Matrix3Dh(this), M2)) // but optimized for the 3Dh case and no conversion needed. return Matrix3Dh.apply(this, M2); } //{{DECLARE_CONTROLS //}} }