package matrix; import java.lang.Math; // Matrix2Dh for making transformations // to homogenous 2D Vectors (Vector2Dh) // including translations which can only // be done with the homogenous version // carrying an extra dimension. // These transformation can be applied // on other transformation to make composite // transformations. public class Matrix2Dh extends Matrix { public Matrix2Dh() { super(3); //{{INIT_CONTROLS //}} } public Matrix2Dh(Matrix M) throws MatrixDimensionError { super(3); copy(M); } public Matrix2Dh(Matrix2D M) { super(3); subcopy(M); } // create a transformation matrix which when applied // to a Vector2D(X, Y) yeilds Vector2D(X+x, Y+y). public static Matrix2Dh translate(double x, double y) { Matrix2Dh trans = new Matrix2Dh(); trans.setCell(2, 0, x); trans.setCell(2, 1, y); return trans; } public static Matrix2Dh translate(Vector2D v) { return translate(v.x(), v.y()); } /* scalar multiplication */ public static Matrix2Dh mult(Matrix2Dh M, double a) { Matrix2Dh result = new Matrix2Dh(); result.copy(M); result.selfMult(a); return result; } public Matrix mult(double a) { return mult(this, a); } /* vector multiplication */ public Vector2Dh applyOn(Vector2Dh v2) { // equivalent to Vector2Dh(Vector2D(Matrix.mult(this, v2))) // but optimized for the 2Dh case and no conversion needed. return new Vector2Dh(cell(0, 0) * v2.x() + cell(1, 0) * v2.y() + cell(2, 0) * v2.w, cell(0, 1) * v2.x() + cell(1, 1) * v2.y() + cell(2, 1) * v2.w, cell(0, 2) * v2.x() + cell(1, 2) * v2.y() + cell(2, 2) * v2.w); } public Vector2Dh applyOn(Vector2D v2) { // equivalent to Vector2Dh(Vector2D(Matrix.mult(this, Vector2Dh(v2)))) // but optimized for the 2Dh case and no conversion needed. return new Vector2Dh(cell(0, 0) * v2.x() + cell(1, 0) * v2.y() + cell(2, 0), cell(0, 1) * v2.x() + cell(1, 1) * v2.y() + cell(2, 1), cell(0, 2) * v2.x() + cell(1, 2) * v2.y() + cell(2, 2)); } // Transform by applying the Matrix and // homogenizing the result. public Vector2D transform(Vector2D V) throws PointAtInfinity { return this.applyOn(V).homogenized(); } /* matrix multiplication */ public Matrix2Dh applyOn(Matrix2Dh M2) { // equivalent to Matrix2Dh(Matrix.mult(this, M2)) // but optimized for the 2Dh case and no conversion needed. Matrix2Dh result = new Matrix2Dh(); for (int j = 0; j < rows(); j++) for (int i = 0; i < cols(); 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 Matrix2Dh applyOn(Matrix2D M2) { // equivalent to Matrix2Dh(Matrix.mult(this, Matrix2Dh(M2))) // but optimized for the 2Dh case and no conversion needed. /* Matrix2Dh result = new Matrix2Dh(); for (int j = 0; j < 3; j++) for (int i = 0; i < 2; i++) result.setCell(i, j, cell(0, j) * M2.cell(i, 0) + cell(1, j) * M2.cell(i, 1)); result.setCell(2, 2, cell(2, 2)); return result;*/ return this.applyOn(new Matrix2Dh(M2)); } // Apply a 2Dh matrix on a 3Dh matrix. // This would be used for performing a screen // transformation after a projection. public Matrix3Dh applyOn(Matrix3Dh M2) { return Matrix3Dh.apply(this, M2); } public static Matrix2Dh apply(Matrix2D M1, Matrix2Dh M2) { // equivalent to Matrix2Dh(Matrix.mult(Matrix2Dh(M1), M2)) // but optimized for the 2Dh case and no conversion needed. /* Matrix2Dh result = new Matrix2Dh(); for (int j = 0; j < 2; j++) for (int i = 0; i < 3; i++) result.setCell(i, j, M1.cell(0, j) * M2.cell(i, 0) + M1.cell(1, j) * M2.cell(i, 1)); result.setCell(2, 2, M2.cell(2, 2)); return result;*/ return (new Matrix2Dh(M1)).applyOn(M2); } //{{DECLARE_CONTROLS //}} }