1 package edu.berkeley.qfat.geom;
3 /** an affine matrix; immutable */
14 public final float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
16 /** the zero matrix */
17 public static final Matrix ZERO = new Matrix(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
19 /** the identity matrix */
20 public static final Matrix ONE = new Matrix(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
22 /** a scaling matrix (uniform in all dimensions) */
23 public static Matrix scale(float scale) { return scale(scale, scale, scale); }
25 /** a scaling matrix */
26 public static Matrix scale(float scalex, float scaley, float scalez) {
27 return new Matrix(scalex, 0, 0, 0, 0, scaley, 0, 0, 0, 0, scalez, 0, 0, 0, 0, 1); }
29 public Matrix(float a, float b, float c, float d, float e, float f, float g,
30 float h, float i, float j, float k, float l, float m, float n, float o, float p) {
31 this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h; this.i = i;
32 this.j = j; this.k = k; this.l = l; this.m = m; this.n = n; this.o = o; this.p = p;
35 public static Matrix translate(Vec translate) {
36 return new Matrix(1, 0, 0, translate.x,
42 public Matrix plus(Matrix x) {
43 return new Matrix(a+x.a, b+x.b, c+x.c, d+x.d, e+x.e, f+x.f, g+x.g, h+x.h, i+x.i, j+x.j, k+x.k, l+x.l, m+x.m, n+x.n, o+x.o, p+x.p);
45 public Matrix minus(Matrix x) {
46 return new Matrix(a-x.a, b-x.b, c-x.c, d-x.d, e-x.e, f-x.f, g-x.g, h-x.h, i-x.i, j-x.j, k-x.k, l-x.l, m-x.m, n-x.n, o-x.o, p-x.p);
48 public Matrix times(float x) {
49 return new Matrix(a*x, b*x, c*x, d*x, e*x, f*x, g*x, h*x, i*x, j*x, k*x, l*x, m*x, n*x, o*x, p*x);
52 /** computes (v^T)(this)(v) */
53 public float preAndPostMultiply(Point point) {
55 ((a*point.x + b*point.y + c*point.z + d) * point.x) +
56 ((e*point.x + f*point.y + g*point.z + h) * point.y) +
57 ((i*point.x + j*point.y + k*point.z + l) * point.z) +
58 ((m*point.x + n*point.y + o*point.z + p) * 1);
62 public static Matrix rotate(Vec axis, float angle) {
63 float q = (float)Math.cos(angle);
64 float s = (float)Math.sin(angle);
66 float a = (float)(q + axis.x*axis.x*t);
67 float f = (float)(q + axis.y*axis.y*t);
68 float k = (float)(q + axis.z*axis.z*t);
69 float tmp1 = axis.x*axis.y*t;
70 float tmp2 = axis.z*s;
71 float e = (float)(tmp1 + tmp2);
72 float b = (float)(tmp1 - tmp2);
73 tmp1 = axis.x*axis.z*t;
75 float i = (float)(tmp1 - tmp2);
76 float c = (float)(tmp1 + tmp2);
77 tmp1 = axis.y*axis.z*t;
79 float j = (float)(tmp1 + tmp2);
80 float g = (float)(tmp1 - tmp2);
81 return new Matrix(a, b, c, 0,
86 public Point times(Point p) {
87 // discards bottom row
88 return new Point(a*p.x + b*p.y + c*p.z + d,
89 e*p.x + f*p.y + g*p.z + h,
90 i*p.x + j*p.y + k*p.z + l);
92 public Vec times(Vec p) {
93 // discards bottom row
94 return new Vec(a*p.x + b*p.y + c*p.z + d,
95 e*p.x + f*p.y + g*p.z + h,
96 i*p.x + j*p.y + k*p.z + l);
98 public Point apply(Point p) { return p; }
99 public Vec apply(Vec v) { return v; }
100 public Matrix invert() { return this; }
101 public Matrix times(Matrix m) { return this; }
104 public float determinant() {
122 m03 * m12 * m21 * m30-m02 * m13 * m21 * m30-m03 * m11 * m22 * m30+m01 * m13 * m22 * m30+
123 m02 * m11 * m23 * m30-m01 * m12 * m23 * m30-m03 * m12 * m20 * m31+m02 * m13 * m20 * m31+
124 m03 * m10 * m22 * m31-m00 * m13 * m22 * m31-m02 * m10 * m23 * m31+m00 * m12 * m23 * m31+
125 m03 * m11 * m20 * m32-m01 * m13 * m20 * m32-m03 * m10 * m21 * m32+m00 * m13 * m21 * m32+
126 m01 * m10 * m23 * m32-m00 * m11 * m23 * m32-m02 * m11 * m20 * m33+m01 * m12 * m20 * m33+
127 m02 * m10 * m21 * m33-m00 * m12 * m21 * m33-m01 * m10 * m22 * m33+m00 * m11 * m22 * m33;
130 public Matrix inverse() {
148 new Matrix(m12*m23*m31 - m13*m22*m31 + m13*m21*m32 - m11*m23*m32 - m12*m21*m33 + m11*m22*m33,
149 m03*m22*m31 - m02*m23*m31 - m03*m21*m32 + m01*m23*m32 + m02*m21*m33 - m01*m22*m33,
150 m02*m13*m31 - m03*m12*m31 + m03*m11*m32 - m01*m13*m32 - m02*m11*m33 + m01*m12*m33,
151 m03*m12*m21 - m02*m13*m21 - m03*m11*m22 + m01*m13*m22 + m02*m11*m23 - m01*m12*m23,
152 m13*m22*m30 - m12*m23*m30 - m13*m20*m32 + m10*m23*m32 + m12*m20*m33 - m10*m22*m33,
153 m02*m23*m30 - m03*m22*m30 + m03*m20*m32 - m00*m23*m32 - m02*m20*m33 + m00*m22*m33,
154 m03*m12*m30 - m02*m13*m30 - m03*m10*m32 + m00*m13*m32 + m02*m10*m33 - m00*m12*m33,
155 m02*m13*m20 - m03*m12*m20 + m03*m10*m22 - m00*m13*m22 - m02*m10*m23 + m00*m12*m23,
156 m11*m23*m30 - m13*m21*m30 + m13*m20*m31 - m10*m23*m31 - m11*m20*m33 + m10*m21*m33,
157 m03*m21*m30 - m01*m23*m30 - m03*m20*m31 + m00*m23*m31 + m01*m20*m33 - m00*m21*m33,
158 m01*m13*m30 - m03*m11*m30 + m03*m10*m31 - m00*m13*m31 - m01*m10*m33 + m00*m11*m33,
159 m03*m11*m20 - m01*m13*m20 - m03*m10*m21 + m00*m13*m21 + m01*m10*m23 - m00*m11*m23,
160 m12*m21*m30 - m11*m22*m30 - m12*m20*m31 + m10*m22*m31 + m11*m20*m32 - m10*m21*m32,
161 m01*m22*m30 - m02*m21*m30 + m02*m20*m31 - m00*m22*m31 - m01*m20*m32 + m00*m21*m32,
162 m02*m11*m30 - m01*m12*m30 - m02*m10*m31 + m00*m12*m31 + m01*m10*m32 - m00*m11*m32,
163 m01*m12*m20 - m02*m11*m20 + m02*m10*m21 - m00*m12*m21 - m01*m10*m22 + m00*m11*m22)
164 .times(1/determinant());