diff --git a/src/main/java/pythagoras/d/AbstractVector.java b/src/main/java/pythagoras/d/AbstractVector.java index 9d595e8..9712cc2 100644 --- a/src/main/java/pythagoras/d/AbstractVector.java +++ b/src/main/java/pythagoras/d/AbstractVector.java @@ -48,6 +48,11 @@ public abstract class AbstractVector implements IVector return (x*x + y*y); } + @Override // from interface IVector + public boolean isZero () { + return Vectors.isZero(x(), y()); + } + @Override // from interface IVector public double distance (IVector other) { return Math.sqrt(distanceSq(other)); diff --git a/src/main/java/pythagoras/d/IVector.java b/src/main/java/pythagoras/d/IVector.java index 2b7d40c..afecbd7 100644 --- a/src/main/java/pythagoras/d/IVector.java +++ b/src/main/java/pythagoras/d/IVector.java @@ -40,6 +40,9 @@ public interface IVector /** Returns the squared length of this vector. */ double lengthSq (); + /** Returns true if this vector has zero magnitude. */ + boolean isZero (); + /** Returns the distance from this vector to the specified other vector. */ double distance (IVector other); diff --git a/src/main/java/pythagoras/d/Points.java b/src/main/java/pythagoras/d/Points.java index 1604f07..1b7f43c 100644 --- a/src/main/java/pythagoras/d/Points.java +++ b/src/main/java/pythagoras/d/Points.java @@ -28,6 +28,22 @@ public class Points return Math.sqrt(distanceSq(x1, y1, x2, y2)); } + /** + * Returns true if the supplied points' x and y components are equal to one another within + * {@link MathUtil#EPSILON}. + */ + public static boolean epsilonEquals (IPoint p1, IPoint p2) { + return epsilonEquals(p1, p2, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied points' x and y components are equal to one another within + * {@code epsilon}. + */ + public static boolean epsilonEquals (IPoint p1, IPoint p2, double epsilon) { + return Math.abs(p1.x() - p2.x()) < epsilon && Math.abs(p1.y() - p2.y()) < epsilon; + } + /** Transforms a point as specified, storing the result in the point provided. * @return a reference to the result point, for chaining. */ public static Point transform (double x, double y, double sx, double sy, double rotation, diff --git a/src/main/java/pythagoras/d/Vectors.java b/src/main/java/pythagoras/d/Vectors.java index b414314..72cd9c7 100644 --- a/src/main/java/pythagoras/d/Vectors.java +++ b/src/main/java/pythagoras/d/Vectors.java @@ -28,24 +28,63 @@ public class Vectors /** * Creates a new vector from polar coordinates. */ - public static final Vector fromPolar (double magnitude, double angle) { + public static Vector fromPolar (double magnitude, double angle) { return new Vector(magnitude * Math.cos(angle), magnitude * Math.sin(angle)); } /** * Returns the magnitude of the specified vector. */ - public static final double length (double x, double y) { + public static double length (double x, double y) { return Math.sqrt(lengthSq(x, y)); } /** * Returns the square of the magnitude of the specified vector. */ - public static final double lengthSq (double x, double y) { + public static double lengthSq (double x, double y) { return (x*x + y*y); } + /** + * Returns true if the supplied vector has zero magnitude. + */ + public static boolean isZero (double x, double y) { + return x == 0 && y == 0; + } + + /** + * Returns true if the supplied vector's x and y components are {@link MathUtil#EPSILON} close + * to zero magnitude. + */ + public static boolean isEpsilonZero (double x, double y) { + return isEpsilonZero(x, y, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied vector's x and y components are {@code epsilon} close to zero + * magnitude. + */ + public static boolean isEpsilonZero (double x, double y, double epsilon) { + return Math.abs(x) < epsilon && Math.abs(y) < epsilon; + } + + /** + * Returns true if the supplied vectors' x and y components are equal to one another within + * {@link MathUtil#EPSILON}. + */ + public static boolean epsilonEquals (IVector v1, IVector v2) { + return epsilonEquals(v1, v2, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied vectors' x and y components are equal to one another within + * {@code epsilon}. + */ + public static boolean epsilonEquals (IVector v1, IVector v2, double epsilon) { + return Math.abs(v1.x() - v2.x()) < epsilon && Math.abs(v1.y() - v2.y()) < epsilon; + } + /** * Transforms a point as specified, storing the result in the point provided. * @return a reference to the result vector, for chaining. diff --git a/src/main/java/pythagoras/f/AbstractVector.java b/src/main/java/pythagoras/f/AbstractVector.java index 8dfa8a4..0d048bb 100644 --- a/src/main/java/pythagoras/f/AbstractVector.java +++ b/src/main/java/pythagoras/f/AbstractVector.java @@ -48,6 +48,11 @@ public abstract class AbstractVector implements IVector return (x*x + y*y); } + @Override // from interface IVector + public boolean isZero () { + return Vectors.isZero(x(), y()); + } + @Override // from interface IVector public float distance (IVector other) { return FloatMath.sqrt(distanceSq(other)); diff --git a/src/main/java/pythagoras/f/IVector.java b/src/main/java/pythagoras/f/IVector.java index 454bb6e..0dd4fac 100644 --- a/src/main/java/pythagoras/f/IVector.java +++ b/src/main/java/pythagoras/f/IVector.java @@ -40,6 +40,9 @@ public interface IVector /** Returns the squared length of this vector. */ float lengthSq (); + /** Returns true if this vector has zero magnitude. */ + boolean isZero (); + /** Returns the distance from this vector to the specified other vector. */ float distance (IVector other); diff --git a/src/main/java/pythagoras/f/Points.java b/src/main/java/pythagoras/f/Points.java index 7ffe273..0cdefa7 100644 --- a/src/main/java/pythagoras/f/Points.java +++ b/src/main/java/pythagoras/f/Points.java @@ -28,6 +28,22 @@ public class Points return FloatMath.sqrt(distanceSq(x1, y1, x2, y2)); } + /** + * Returns true if the supplied points' x and y components are equal to one another within + * {@link MathUtil#EPSILON}. + */ + public static boolean epsilonEquals (IPoint p1, IPoint p2) { + return epsilonEquals(p1, p2, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied points' x and y components are equal to one another within + * {@code epsilon}. + */ + public static boolean epsilonEquals (IPoint p1, IPoint p2, float epsilon) { + return Math.abs(p1.x() - p2.x()) < epsilon && Math.abs(p1.y() - p2.y()) < epsilon; + } + /** Transforms a point as specified, storing the result in the point provided. * @return a reference to the result point, for chaining. */ public static Point transform (float x, float y, float sx, float sy, float rotation, diff --git a/src/main/java/pythagoras/f/Vectors.java b/src/main/java/pythagoras/f/Vectors.java index 550d1a2..1cb2fbb 100644 --- a/src/main/java/pythagoras/f/Vectors.java +++ b/src/main/java/pythagoras/f/Vectors.java @@ -28,24 +28,63 @@ public class Vectors /** * Creates a new vector from polar coordinates. */ - public static final Vector fromPolar (float magnitude, float angle) { + public static Vector fromPolar (float magnitude, float angle) { return new Vector(magnitude * FloatMath.cos(angle), magnitude * FloatMath.sin(angle)); } /** * Returns the magnitude of the specified vector. */ - public static final float length (float x, float y) { + public static float length (float x, float y) { return FloatMath.sqrt(lengthSq(x, y)); } /** * Returns the square of the magnitude of the specified vector. */ - public static final float lengthSq (float x, float y) { + public static float lengthSq (float x, float y) { return (x*x + y*y); } + /** + * Returns true if the supplied vector has zero magnitude. + */ + public static boolean isZero (float x, float y) { + return x == 0 && y == 0; + } + + /** + * Returns true if the supplied vector's x and y components are {@link MathUtil#EPSILON} close + * to zero magnitude. + */ + public static boolean isEpsilonZero (float x, float y) { + return isEpsilonZero(x, y, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied vector's x and y components are {@code epsilon} close to zero + * magnitude. + */ + public static boolean isEpsilonZero (float x, float y, float epsilon) { + return Math.abs(x) < epsilon && Math.abs(y) < epsilon; + } + + /** + * Returns true if the supplied vectors' x and y components are equal to one another within + * {@link MathUtil#EPSILON}. + */ + public static boolean epsilonEquals (IVector v1, IVector v2) { + return epsilonEquals(v1, v2, MathUtil.EPSILON); + } + + /** + * Returns true if the supplied vectors' x and y components are equal to one another within + * {@code epsilon}. + */ + public static boolean epsilonEquals (IVector v1, IVector v2, float epsilon) { + return Math.abs(v1.x() - v2.x()) < epsilon && Math.abs(v1.y() - v2.y()) < epsilon; + } + /** * Transforms a point as specified, storing the result in the point provided. * @return a reference to the result vector, for chaining.