--- /dev/null
+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; }
+ }
+
+}
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
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);
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);
}
}
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();
+ }
}
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
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));
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");
+ }
}
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);
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;
+ }
}
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));