checkpoint
authoradam <adam@megacz.com>
Sun, 6 Jul 2008 23:55:14 +0000 (16:55 -0700)
committeradam <adam@megacz.com>
Sun, 6 Jul 2008 23:55:14 +0000 (16:55 -0700)
darcs-hash:20080706235514-5007d-ac23fa54fbd026c226b88549ed135cad515b7c77.gz

src/edu/berkeley/qfat/geom/AffineConstraint.java [new file with mode: 0644]
src/edu/berkeley/qfat/geom/Line.java
src/edu/berkeley/qfat/geom/Matrix.java
src/edu/berkeley/qfat/geom/Plane.java
src/edu/berkeley/qfat/geom/Point.java
src/edu/berkeley/qfat/geom/Segment.java

diff --git a/src/edu/berkeley/qfat/geom/AffineConstraint.java b/src/edu/berkeley/qfat/geom/AffineConstraint.java
new file mode 100644 (file)
index 0000000..a6fb01c
--- /dev/null
@@ -0,0 +1,20 @@
+package edu.berkeley.qfat.geom;
+import javax.media.opengl.*;
+
+/** a constraint arising from the conjunction of linear equalities */
+public interface AffineConstraint {
+
+    public Point getProjection(Point p);
+    public AffineConstraint intersect(AffineConstraint c, float epsilon);
+
+    public static class All implements AffineConstraint {
+        public Point getProjection(Point p) { return p; }
+        public AffineConstraint intersect(AffineConstraint c, float epsilon) { return c; }
+    }
+
+    public static class Nothing implements AffineConstraint {
+        public Point getProjection(Point p) { return null; }
+        public AffineConstraint intersect(AffineConstraint c, float epsilon) { return this; }
+    }
+
+}
index 7fb9b86..5997130 100644 (file)
@@ -2,7 +2,7 @@ package edu.berkeley.qfat.geom;
 import javax.media.opengl.*;
 
 /** an infinitely long line in 3-space */
-public class Line {
+public class Line implements AffineConstraint {
 
     // y=mx+c
     // z=nx+d
@@ -33,10 +33,16 @@ public class Line {
         return "[line: y="+m+"x+"+c+" z="+n+"x+"+d+"]";
     }
 
-    public double distance(Point p) { return projection(p).distance(p); }
+    public double distance(Point p) { return getProjection(p).distance(p); }
+
+    public Vec getUnit() {
+        Point p1 = new Point(0, c,   d);
+        Point p2 = new Point(1, m+c, n+d);
+        return p2.minus(p1).norm();
+    }
 
     /** returns the point on this line which is closest to p */
-    public Point projection(Point p) {
+    public Point getProjection(Point p) {
         /*
         Point p1 = new Point(0, c,   d);
         Point p2 = new Point(1, m+c, n+d);
@@ -46,10 +52,18 @@ public class Line {
         throw new RuntimeException("test this before using; may not be correct");
     }
 
-    public Vec getUnit() {
-        Point p1 = new Point(0, c,   d);
-        Point p2 = new Point(1, m+c, n+d);
-        return p2.minus(p1).norm();
+    public AffineConstraint intersect(AffineConstraint con, float epsilon) {
+        if (!(con instanceof Line)) return con.intersect(this, epsilon);
+        Line line = (Line)con;
+        if (Math.abs(this.m-line.m) <= epsilon &&
+            Math.abs(this.n-line.n) <= epsilon &&
+            Math.abs(this.c-line.c) <= epsilon &&
+            Math.abs(this.d-line.d) <= epsilon)
+            return this;
+        float x = (line.c-this.c)/(this.m-line.m);
+        if (Math.abs( (m*x+c)-(line.m*x+line.c) ) > epsilon ) return null;
+        if (Math.abs( (n*x+d)-(line.n*x+line.d) ) > epsilon ) return null;
+        return new Point(x, m*x+c, n*x+d);
     }
 
 }
index dda8285..372e6c2 100644 (file)
@@ -366,4 +366,23 @@ public class Matrix {
         return z.times(p).times(m);
     }
 
+    /** returns the constraint-conjunction "(forall v)Mv=v" */
+    public AffineConstraint getConstraint(float epsilon) {
+        AffineConstraint c1 = getConstraint(a-1, b,   c,   d  , epsilon);
+        AffineConstraint c2 = getConstraint(e,   f-1, g,   h  , epsilon);
+        AffineConstraint c3 = getConstraint(i,   j,   k-1, l  , epsilon);
+        // FIXME: bottom row constraint?
+        return c1.intersect(c2.intersect(c3, epsilon), epsilon);
+    }
+
+    /** the AffineConstraint representing ax+by+cz+d=0 */
+    private static AffineConstraint getConstraint(float a, float b, float c, float d, float epsilon) {
+        a = Math.abs(a) <= epsilon ? 0 : a;
+        b = Math.abs(b) <= epsilon ? 0 : b;
+        c = Math.abs(c) <= epsilon ? 0 : c;
+        d = Math.abs(d) <= epsilon ? 0 : d;
+        if (a!=0 || b!=0 || c!=0) return new Plane(a, b, c, d);
+        if (d==0) return new AffineConstraint.All();
+        return new AffineConstraint.Nothing();
+    }
 }
index 1789e55..5f5d990 100644 (file)
@@ -1,7 +1,7 @@
 package edu.berkeley.qfat.geom;
 import javax.media.opengl.*;
 
-public class Plane {
+public class Plane implements AffineConstraint {
 
     // FIXME: could be given by
     // ax+by+cz=d
@@ -14,6 +14,11 @@ public class Plane {
         this.dvalue = p.x*this.norm.x+p.y*this.norm.y+p.z*this.norm.z;
     }
 
+    /** provided at least one of a,b,c is nonzero, return the Plane representing ax+by+cz=d */
+    public Plane(float a, float b, float c, float d) {
+        throw new RuntimeException("not implemented yet");
+    }
+
     public Point intersect(Plane p1, Plane p2) {
         Plane p3 = this;
         float z = p1.norm.dot(p2.norm.cross(p3.norm));
@@ -24,4 +29,11 @@ public class Plane {
         return Point.ZERO.plus(v1.plus(v2).plus(v3).times(1/z));
     }
 
+    public Point getProjection(Point p) {
+        throw new RuntimeException("not implemented yet");
+    }
+
+    public AffineConstraint intersect(AffineConstraint c, float epsilon) {
+        throw new RuntimeException("not implemented yet");
+    }
 }
index cf44573..57c8667 100644 (file)
@@ -3,7 +3,7 @@ import javax.media.opengl.*;
 import javax.media.opengl.glu.*;
 
 /** point in 3-space; immutable */
-public final class Point extends HasPoint implements HasBoundingBox {
+public final class Point extends HasPoint implements HasBoundingBox, AffineConstraint {
 
     public static final Point ZERO = new Point(0,0,0);
 
@@ -33,5 +33,11 @@ public final class Point extends HasPoint implements HasBoundingBox {
     public float getMinY() { return y; }
     public float getMaxZ() { return z; }
     public float getMinZ() { return z; }
+
+    public Point getProjection(Point p) { return this; }
+    public AffineConstraint intersect(AffineConstraint c, float epsilon) {
+        if (c.getProjection(this).distance(this) <= epsilon) return this;
+        return null;
+    }
 }
 
index fa303d1..db41142 100644 (file)
@@ -32,7 +32,7 @@ public class Segment implements HasBoundingBox {
 
     public double distance(Point p) {
         Line line = getLine();
-        Point proj = line.projection(p);
+        Point proj = line.getProjection(p);
         if (proj.distance(p1)+proj.distance(p2) > length())
             return Math.min(p1.distance(p),
                             p2.distance(p));