X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2Fgeom%2FPlane.java;h=fe23b83903aba072c46f4aea96f999bef938ec73;hp=5f5d99078d6b4e2b94b37c1eba6076a31fa0be86;hb=00235327934dbc5ffaf5b09cbda538ee0d3686e8;hpb=5dc5f8e70f3e4088f0f787e4c5e94d95c7e4c95f diff --git a/src/edu/berkeley/qfat/geom/Plane.java b/src/edu/berkeley/qfat/geom/Plane.java index 5f5d990..fe23b83 100644 --- a/src/edu/berkeley/qfat/geom/Plane.java +++ b/src/edu/berkeley/qfat/geom/Plane.java @@ -1,39 +1,102 @@ package edu.berkeley.qfat.geom; import javax.media.opengl.*; +// FEATURE: represent a plane by the matrix that projects points onto that plane? public class Plane implements AffineConstraint { - // FIXME: could be given by // ax+by+cz=d + public final float a, b, c, d; + public final Point p; - public final Vec norm; - public final float dvalue; + public Vec norm() { return new Vec(a, b, c).norm(); } 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; + this.p = p; } - /** 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"); + // FIXME, what if c==0? + this(a, b, c, d, new Point(0, 0, d/c)); + } + + /** 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, Point p) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.p = p; } 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)); } - public Point getProjection(Point p) { - throw new RuntimeException("not implemented yet"); + public AffineConstraint intersect(AffineConstraint c, float epsilon) { + if (c instanceof Plane) { + Plane p = (Plane)c; + + // same plane + if (Math.abs(p.a*this.d-this.a*p.d) <= epsilon && + Math.abs(p.b*this.d-this.b*p.d) <= epsilon && + Math.abs(p.c*this.d-this.c*p.d) <= epsilon && + Math.abs(p.d*this.d-this.d*p.d) <= epsilon) + return this; + + // parallel planes + if (Math.abs(p.norm().cross(norm()).mag()) <= epsilon) + return AffineConstraint.NONE; + + 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 intersect(AffineConstraint c, float epsilon) { - throw new RuntimeException("not implemented yet"); + public AffineConstraint multiply(Matrix m) { + return new Plane( m.times(p), m.times(norm()).norm() ); + } + + public Point getProjection(Point p) { + Point ret = norm().times(p.minus(this.p).dot(norm())).times(-1).plus(p); + return ret; + } + public String toString() { + return "[plane "+a+"x+"+b+"y+"+c+"z="+d+"]"; } }