package edu.berkeley.qfat.geom;
+import javax.media.opengl.*;
// FEATURE: precompute/cache determinant?
/** the identity matrix */
public static final Matrix NEGATIVE_ONE = new Matrix(-1,0,0,0,0,-1,0,0,0,0,-1,0,0,0,0,1);
+ public Matrix(double a, double b, double c, double d, double e, double f, double g,
+ double h, double i, double j, double k, double l, double m, double n, double o, double p) {
+ this((float)a, (float)b, (float)c, (float)d,
+ (float)e, (float)f, (float)g, (float)h,
+ (float)i, (float)j, (float)k, (float)l,
+ (float)m, (float)n, (float)o, (float)p);
+ }
+
public Matrix(float a, float b, float c, float d, float e, float f, float g,
float h, float i, float j, float k, float l, float m, float n, float o, float p) {
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;
0, 0, 0, 1);
}
+ public static Matrix reflect(Vec v) {
+ Vec reflectionPlaneNormal = v.norm();
+ float a = reflectionPlaneNormal.x;
+ float b = reflectionPlaneNormal.y;
+ float c = reflectionPlaneNormal.z;
+ return
+ new Matrix( 1-2*a*a, -2*a*b, -2*a*c, 0,
+ -2*a*b, 1-2*b*b, -2*b*c, 0,
+ -2*a*c, -2*b*c, 1-2*c*c, 0,
+ 0, 0, 0, 1);
+ }
+
+ public Vec getTranslationalComponent() {
+ return new Vec(d, h, l);
+ }
+
public Matrix plus(Matrix x) {
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);
}
/** discards bottom row */
public Point times(Point p) {
// discards bottom row
- return new Point(a*p.x + b*p.y + c*p.z + d,
- e*p.x + f*p.y + g*p.z + h,
- i*p.x + j*p.y + k*p.z + l);
+ double x = a*p.x + b*p.y + c*p.z + d;
+ double y = e*p.x + f*p.y + g*p.z + h;
+ double z = i*p.x + j*p.y + k*p.z + l;
+ double q = m*p.x + n*p.y + o*p.z + this.p;
+ return new Point(x/q, y/q, z/q);
}
/** discards bottom row */
i*p.x + j*p.y + k*p.z + l);
}
+ public Matrix preMultiplyTranslationalComponentBy(Matrix mm) {
+ Vec v = mm.times(getTranslationalComponent());
+ return new Matrix(a, b, c, v.x,
+ e, f, g, v.y,
+ i, j, k, v.z,
+ m, n, o, 1);
+ }
+
/** multiply by another matrix */
public Matrix times(Matrix z) {
float t00 = a;
if (!(oo instanceof Matrix)) return false;
Matrix z = (Matrix)oo;
return
- a==z.a &&
- b==z.b &&
- c==z.c &&
- d==z.d &&
- e==z.e &&
- f==z.f &&
- g==z.g &&
- h==z.h &&
- i==z.i &&
- j==z.j &&
- k==z.k &&
- l==z.l &&
- m==z.m &&
- n==z.n &&
- o==z.o &&
- p==z.p;
+ near(a,z.a) &&
+ near(b,z.b) &&
+ near(c,z.c) &&
+ near(d,z.d) &&
+ near(e,z.e) &&
+ near(f,z.f) &&
+ near(g,z.g) &&
+ near(h,z.h) &&
+ near(i,z.i) &&
+ near(j,z.j) &&
+ near(k,z.k) &&
+ near(l,z.l) &&
+ near(m,z.m) &&
+ near(n,z.n) &&
+ near(o,z.o) &&
+ near(p,z.p);
}
+ private static final float EPSILON = 0.001f;
+ private static boolean near(float a, float b) { return Math.abs(a-b)<EPSILON; }
public int hashCode() {
return
Float.floatToIntBits(o) ^
Float.floatToIntBits(p);
}
+
+ public static Matrix getProjectionMatrix(GL gl) {
+ int view[] = new int[4];
+ double mvmatrix[] = new double[16];
+ double projmatrix[] = new double[16];
+ gl.glGetIntegerv(GL.GL_VIEWPORT, view, 0);
+ gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
+ gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);
+ Matrix m = new Matrix(mvmatrix[0],
+ mvmatrix[4],
+ mvmatrix[8],
+ mvmatrix[12],
+ mvmatrix[1],
+ mvmatrix[5],
+ mvmatrix[9],
+ mvmatrix[13],
+ mvmatrix[2],
+ mvmatrix[6],
+ mvmatrix[10],
+ mvmatrix[14],
+ mvmatrix[3],
+ mvmatrix[7],
+ mvmatrix[11],
+ mvmatrix[15]);
+ Matrix p = new Matrix(projmatrix[0],
+ projmatrix[4],
+ projmatrix[8],
+ projmatrix[12],
+ projmatrix[1],
+ projmatrix[5],
+ projmatrix[9],
+ projmatrix[13],
+ projmatrix[2],
+ projmatrix[6],
+ projmatrix[10],
+ projmatrix[14],
+ projmatrix[3],
+ projmatrix[7],
+ projmatrix[11],
+ projmatrix[15]);
+ Matrix z =
+ new Matrix(0.5*view[2], 0, 0, view[0]+view[2]*0.5,
+ 0, 0.5*view[3], 0, view[1]+view[3]*0.5,
+ 0, 0, 0.5, 0.5,
+ 0, 0, 0, 1);
+ return z.times(p).times(m);
+ }
+
}