checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / Plane.java
index 5f5d990..36f18a3 100644 (file)
@@ -3,29 +3,35 @@ import javax.media.opengl.*;
 
 public class Plane implements AffineConstraint {
 
-    // FIXME: could be given by
     // ax+by+cz=d
+    public final float a, b, c, d;
 
-    public final Vec norm;
-    public final float dvalue;
+    public Vec norm() { return new Vec(a, b, c); }
 
     public Plane(Point p, Vec norm) {
-        this.norm = norm.norm();
-        this.dvalue = p.x*this.norm.x+p.y*this.norm.y+p.z*this.norm.z;
+        norm = norm.norm();
+        this.a = norm.x;
+        this.b = norm.y;
+        this.c = norm.z;
+        this.d = p.x*norm.x+p.y*norm.y+p.z*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");
+        this.a = a;
+        this.b = b;
+        this.c = c;
+        this.d = d;
     }
 
     public Point intersect(Plane p1, Plane p2) {
+        Vec norm = norm();
         Plane p3 = this;
-        float z = p1.norm.dot(p2.norm.cross(p3.norm));
+        float z = p1.norm().dot(p2.norm().cross(p3.norm()));
         if (Math.abs(z) < 0.0001) return null;  // planes do not intersect at a point
-        Vec v1 = p2.norm.cross(p3.norm).times(-1 * p1.dvalue);
-        Vec v2 = p3.norm.cross(p1.norm).times(-1 * p2.dvalue);
-        Vec v3 = p1.norm.cross(p2.norm).times(-1 * p3.dvalue);
+        Vec v1 = p2.norm().cross(p3.norm()).times(-1 * p1.d);
+        Vec v2 = p3.norm().cross(p1.norm()).times(-1 * p2.d);
+        Vec v3 = p1.norm().cross(p2.norm()).times(-1 * p3.d);
         return Point.ZERO.plus(v1.plus(v2).plus(v3).times(1/z));
     }
 
@@ -34,6 +40,50 @@ public class Plane implements AffineConstraint {
     }
 
     public AffineConstraint intersect(AffineConstraint c, float epsilon) {
-        throw new RuntimeException("not implemented yet");
+        if (c instanceof Plane) {
+            Plane p = (Plane)c;
+
+            // same plane
+            if (Math.abs(p.a-this.a) <= epsilon &&
+                Math.abs(p.b-this.b) <= epsilon &&
+                Math.abs(p.c-this.c) <= epsilon &&
+                Math.abs(p.d-this.d) <= epsilon)
+                return this;
+
+            // parallel planes
+            if (Math.abs(p.norm().cross(norm()).mag()) <= epsilon)
+                return new AffineConstraint.Nothing();
+
+            Vec u = norm().cross(p.norm());
+            Point point = null;
+            if (Math.abs(u.z) >= Math.abs(u.y) && Math.abs(u.z) >= Math.abs(u.y)) {
+                point = new Point( (this.b*p.d - p.b*this.d)/(this.a*p.b - p.a*this.b),
+                                   (this.d*p.a - p.d*this.a)/(this.a*p.b - p.a*this.b),
+                                   0);
+            } else if (Math.abs(u.y) >= Math.abs(u.z) && Math.abs(u.y) >= Math.abs(u.x)) {
+                point = new Point( (this.c*p.d - p.c*this.d)/(this.a*p.c - p.a*this.c),
+                                   0,
+                                   (this.d*p.a - p.d*this.a)/(this.a*p.c - p.a*this.c));
+            } else {
+                point = new Point( 0,
+                                   (this.c*p.d - p.c*this.d)/(this.b*p.c - p.b*this.c),
+                                   (this.d*p.b - p.d*this.b)/(this.b*p.c - p.b*this.c));
+            }
+
+            return new Line(point, u);
+
+        } else if (c instanceof Line) {
+            Line l = (Line)c;
+            if ( Math.abs(a + b*l.m + this.c*l.n) <= epsilon &&
+                 Math.abs(b * l.c + this.c * l.d + d) <= epsilon)
+                return l;
+            throw new RuntimeException("not yet implemented");
+
+        } else
+            return c.intersect(this, epsilon);
+    }
+
+    public AffineConstraint multiply(Matrix m) {
+        throw new RuntimeException("not yet implemented");
     }
 }