checkpoint autogen tile
[anneal.git] / src / edu / berkeley / qfat / geom / Matrix.java
index 19e1a9a..eeeb68f 100644 (file)
@@ -16,10 +16,13 @@ public class Matrix {
     public final float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
 
     /** the zero matrix */
-    public static final Matrix ZERO = new Matrix(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+    public static final Matrix ZERO          = new Matrix(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
 
     /** the identity matrix */
-    public static final Matrix ONE  = new Matrix(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
+    public static final Matrix ONE           = new Matrix(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
+
+    /** 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(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) {
@@ -68,6 +71,22 @@ public class Matrix {
                           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);
     }
@@ -235,23 +254,25 @@ public class Matrix {
         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