diff --git a/src/main/java/pythagoras/f/AbstractLine.java b/src/main/java/pythagoras/f/AbstractLine.java index 1878ff2..a8fa468 100644 --- a/src/main/java/pythagoras/f/AbstractLine.java +++ b/src/main/java/pythagoras/f/AbstractLine.java @@ -73,6 +73,16 @@ public abstract class AbstractLine implements ILine return Lines.pointSegDist(p.getX(), p.getY(), getX1(), getY1(), getX2(), getY2()); } + @Override // from interface ILine + public int relativeCCW (float px, float py) { + return Lines.relativeCCW(px, py, getX1(), getY1(), getX2(), getY2()); + } + + @Override // from interface ILine + public int relativeCCW (IPoint p) { + return Lines.relativeCCW(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/ILine.java b/src/main/java/pythagoras/f/ILine.java index 354e803..c0a4481 100644 --- a/src/main/java/pythagoras/f/ILine.java +++ b/src/main/java/pythagoras/f/ILine.java @@ -60,6 +60,10 @@ public interface ILine extends IShape, Cloneable /** Returns the distance from the supplied point this line segment. */ float pointSegDist (IPoint p); + int relativeCCW (float px, float py); + + int relativeCCW (IPoint p); + /** Returns a mutable copy of this line. */ Line clone (); } diff --git a/src/main/java/pythagoras/f/Lines.java b/src/main/java/pythagoras/f/Lines.java index 2d7662b..fcd6a92 100644 --- a/src/main/java/pythagoras/f/Lines.java +++ b/src/main/java/pythagoras/f/Lines.java @@ -120,4 +120,32 @@ public class Lines 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 an indicator of where the specified point (px,py) lies with respect to the line + * segment from (x1,y1) to (x2,y2). + * + * @see http://download.oracle.com/javase/6/docs/api/java/awt/geom/Line2D.html + */ + public static int relativeCCW (float px, float py, float x1, float y1, float x2, float y2) { + // A = (x2-x1, y2-y1) + // P = (px-x1, py-y1) + x2 -= x1; + y2 -= y1; + px -= x1; + py -= y1; + float t = px * y2 - py * x2; // PxA + if (t == 0f) { + t = px * x2 + py * y2; // P*A + if (t > 0f) { + px -= x2; // B-A + py -= y2; + t = px * x2 + py * y2; // (P-A)*A + if (t < 0f) { + t = 0f; + } + } + } + return (t < 0f) ? -1 : (t > 0f ? 1 : 0); + } }