checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / Matrix.java
index 346f53e..514f7d7 100644 (file)
@@ -1,44 +1,44 @@
 package edu.berkeley.qfat.geom;
 
-/** affine matrix; immutable */
+/** an affine matrix; immutable */
 public class Matrix {
 
+    /**
+     *  <pre>
+     *  [ a b c d ]   [ x ]
+     *  [ e f g h ]   [ y ]
+     *  [ i j k l ]   [ z ]
+     *  [ m n o p ]   [ 1 ]
+     *  </pre>
+     */
+    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);
 
-    //
-    //  [ a b c d ]   [ x ]
-    //  [ e f g h ]   [ y ]
-    //  [ i j k l ]   [ z ]
-    //  [ m n o p ]   [ 1 ]
-    //
-    public final float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
-    public Matrix() { this(1); }
-    public Matrix(float scale) {
-        a = f = k = scale;
-        l = h = d = e = b = i = c = j = g = 0;            
-        m = n = o = 0;
-        p = 1;
-    }
-    public Matrix(float scalex, float scaley, float scalez) {
-        a = scalex;
-        f = scaley;
-        k = scalez;
-        l = h = d = e = b = i = c = j = g = 0;            
-        m = n = o = 0;
-        p = 1;
-    }
-    public Matrix(Vec translate) {
-        d = translate.x; h = translate.y; l = translate.z;
-        a = f = k = 1;
-        b = c = e = g = i = j = 0;
-        m = n = o = 0;
-        p = 1;
-    }
+    /** 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);
+
+    /** a scaling matrix (uniform in all dimensions) */
+    public static Matrix scale(float scale) { return scale(scale, scale, scale); }
+
+    /** a scaling matrix */
+    public static Matrix scale(float scalex, float scaley, float scalez) {
+        return new Matrix(scalex, 0, 0, 0, 0, scaley, 0, 0, 0, 0, scalez, 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) {
         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;
         this.j = j; this.k = k; this.l = l; this.m = m; this.n = n; this.o = o; this.p = p;
     }
+
+    public static Matrix translate(Vec translate) {
+        return new Matrix(1, 0, 0, translate.x,
+                          0, 1, 0, translate.y,
+                          0, 0, 1, translate.z,
+                          0, 0, 0, 1);
+    }
+
     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);
     }
@@ -59,28 +59,29 @@ public class Matrix {
         return ret;
     }
 
-    public Matrix(Vec axis, float angle) {
-        double q = Math.cos(angle);
-        double s = Math.sin(angle);
-        double t = 1.0 - q;
-        a = (float)(q + axis.x*axis.x*t);
-        f = (float)(q + axis.y*axis.y*t);
-        k = (float)(q + axis.z*axis.z*t);
-        double tmp1 = axis.x*axis.y*t;
-        double tmp2 = axis.z*s;
-        e = (float)(tmp1 + tmp2);
-        b = (float)(tmp1 - tmp2);
+    public static Matrix rotate(Vec axis, float angle) {
+        float q = (float)Math.cos(angle);
+        float s = (float)Math.sin(angle);
+        float t = 1 - q;
+        float a = (float)(q + axis.x*axis.x*t);
+        float f = (float)(q + axis.y*axis.y*t);
+        float k = (float)(q + axis.z*axis.z*t);
+        float tmp1 = axis.x*axis.y*t;
+        float tmp2 = axis.z*s;
+        float e = (float)(tmp1 + tmp2);
+        float b = (float)(tmp1 - tmp2);
         tmp1 = axis.x*axis.z*t;
         tmp2 = axis.y*s;
-        i = (float)(tmp1 - tmp2);
-        c = (float)(tmp1 + tmp2);
+        float i = (float)(tmp1 - tmp2);
+        float c = (float)(tmp1 + tmp2);
         tmp1 = axis.y*axis.z*t;
         tmp2 = axis.x*s;
-        j = (float)(tmp1 + tmp2);
-        g = (float)(tmp1 - tmp2);
-        d = h = l = 0;
-        m = n = o = 0;
-        p = 1;
+        float j = (float)(tmp1 + tmp2);
+        float g = (float)(tmp1 - tmp2);
+        return new Matrix(a, b, c, 0,
+                          e, f, g, 0,
+                          i, j, k, 0,
+                          0, 0, 0, 1);
     }
     public Point times(Point p) {
         // discards bottom row