X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2Fgeom%2FLine.java;h=cafa081ff6e6e236996c4e6dad5f8c8fde0c71dc;hp=7fb9b86fe113ef5ec9dd17bb743f48bb69e9386b;hb=eabe4f7acd947415f183290dc3269b2502a25a1c;hpb=de2400d58116bd995e73baf7a429e22def1e4067 diff --git a/src/edu/berkeley/qfat/geom/Line.java b/src/edu/berkeley/qfat/geom/Line.java index 7fb9b86..cafa081 100644 --- a/src/edu/berkeley/qfat/geom/Line.java +++ b/src/edu/berkeley/qfat/geom/Line.java @@ -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 @@ -10,12 +10,18 @@ public class Line { /** the line passing through two points */ public Line(Point p1, Point p2) { + // FIXME: division by zero? this.m = (p2.y-p1.y)/(p2.x-p1.x); this.n = (p2.z-p1.z)/(p2.x-p1.x); this.c = p1.y - m * p1.x; this.d = p1.z - n * p1.x; } + /** the line passing through p1 with direction v */ + public Line(Point p1, Vec v) { + this(p1, v.plus(p1)); + } + public int hashCode() { return Float.floatToIntBits(m) ^ @@ -33,23 +39,44 @@ 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); Vec w = p.minus(p1); - return getUnit().times(w.dot(getUnit())); - */ + return p1.plus(getUnit().times(w.dot(getUnit()))); + /* 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); + } + + public AffineConstraint multiply(Matrix m) { + // FIXME: ugly + Point p1 = new Point(0, c, d); + Point p2 = new Point(1, this.m+c, n+d); + return new Line(m.times(p1), m.times(p2)); } }