From bdc3edb985da7519a73ac31c5ff9f738b5745dee Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 9 Jun 2011 16:36:09 -0700 Subject: [PATCH] More Line methods. --- src/main/java/pythagoras/f/AbstractLine.java | 40 ++++++++++++++ src/main/java/pythagoras/f/Geometry.java | 58 ++++++++++++++++++++ src/main/java/pythagoras/f/ILine.java | 42 ++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/src/main/java/pythagoras/f/AbstractLine.java b/src/main/java/pythagoras/f/AbstractLine.java index 89128e5..4ea8b42 100644 --- a/src/main/java/pythagoras/f/AbstractLine.java +++ b/src/main/java/pythagoras/f/AbstractLine.java @@ -43,6 +43,46 @@ public abstract class AbstractLine implements ILine return new Point(getX2(), getY2()); } + @Override // from interface ILine + public float pointLineDistSq (float px, float py) { + return Geometry.pointLineDistSq(px, py, getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointLineDistSq (IPoint p) { + return Geometry.pointLineDistSq(p.getX(), p.getY(), getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointLineDist (float px, float py) { + return Geometry.pointLineDist(px, py, getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointLineDist (IPoint p) { + return Geometry.pointLineDist(p.getX(), p.getY(), getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointSegDistSq (float px, float py) { + return Geometry.pointSegDistSq(px, py, getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointSegDistSq (IPoint p) { + return Geometry.pointSegDistSq(p.getX(), p.getY(), getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointSegDist (float px, float py) { + return Geometry.pointSegDist(px, py, getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public float pointSegDist (IPoint p) { + return Geometry.pointSegDist(p.getX(), p.getY(), getX1(), getY1(), getX2(), getY2()); + } + @Override // from interface ILine public Line clone () { return new Line(getX1(), getY1(), getX2(), getY2()); diff --git a/src/main/java/pythagoras/f/Geometry.java b/src/main/java/pythagoras/f/Geometry.java index 8e054cf..61dd4ec 100644 --- a/src/main/java/pythagoras/f/Geometry.java +++ b/src/main/java/pythagoras/f/Geometry.java @@ -80,6 +80,64 @@ public class Geometry || linesIntersect(rr, ry, rx, rb, x1, y1, x2, y2); } + /** + * Returns the square of the distance from the specified point to the specified line. + */ + public static float pointLineDistSq (float px, float py, + float x1, float y1, float x2, float y2) { + x2 -= x1; + y2 -= y1; + px -= x1; + py -= y1; + float s = px * y2 - py * x2; + return (s * s) / (x2 * x2 + y2 * y2); + } + + /** + * Returns the distance from the specified point to the specified line. + */ + public static float pointLineDist (float px, float py, float x1, float y1, float x2, float y2) { + return (float)Math.sqrt(pointLineDistSq(px, py, x1, y1, x2, y2)); + } + + /** + * Returns the square of the distance between the specified point and the specified line + * segment. + */ + public static float pointSegDistSq (float px, float py, + float x1, float y1, float x2, float y2) { + // A = (x2 - x1, y2 - y1) + // P = (px - x1, py - y1) + x2 -= x1; // A = (x2, y2) + y2 -= y1; + px -= x1; // P = (px, py) + py -= y1; + float dist; + if (px * x2 + py * y2 <= 0.0) { // P*A + dist = px * px + py * py; + } else { + px = x2 - px; // P = A - P = (x2 - px, y2 - py) + py = y2 - py; + if (px * x2 + py * y2 <= 0.0) { // P*A + dist = px * px + py * py; + } else { + dist = px * y2 - py * x2; + dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A| + } + } + if (dist < 0) { + dist = 0; + } + return dist; + } + + /** + * Returns the distance between the specified point and the specified line segment. + */ + public static float pointSegDist (float px, float py, float x1, float y1, float x2, float y2) { + return (float)Math.sqrt(pointSegDistSq(px, py, x1, y1, x2, y2)); + } + /** * Returns a string describing the supplied point, of the form +x+y, * +x-y, -x-y, etc. diff --git a/src/main/java/pythagoras/f/ILine.java b/src/main/java/pythagoras/f/ILine.java index f5a772c..edd09ad 100644 --- a/src/main/java/pythagoras/f/ILine.java +++ b/src/main/java/pythagoras/f/ILine.java @@ -52,6 +52,48 @@ public interface ILine extends IShape, Cloneable */ Point getP2 (); + /** + * Returns the square of the distance from the specified point to the line defined by this line + * segment. + */ + float pointLineDistSq (float px, float py); + + /** + * Returns the square of the distance from the supplied point to the line defined by this line + * segment. + */ + float pointLineDistSq (IPoint p); + + /** + * Returns the distance from the specified point to the line defined by this line segment. + */ + float pointLineDist (float px, float py); + + /** + * Returns the distance from the supplied point to the line defined by this line segment. + */ + float pointLineDist (IPoint p); + + /** + * Returns the square of the distance from the specified point this line segment. + */ + float pointSegDistSq (float px, float py); + + /** + * Returns the square of the distance from the supplied point this line segment. + */ + float pointSegDistSq (IPoint p); + + /** + * Returns the distance from the specified point this line segment. + */ + float pointSegDist (float px, float py); + + /** + * Returns the distance from the supplied point this line segment. + */ + float pointSegDist (IPoint p); + /** * Returns a mutable copy of this line. */