This is an automated email from the ASF dual-hosted git repository. erans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-geometry.git
commit 65d0228f1dab8c4f37a06f96270ab0f01a440b79 Author: Gilles Sadowski <[email protected]> AuthorDate: Fri Sep 27 13:29:18 2019 +0200 GEOMETRY-61: Improvement of "normalize" functionality for class "Vector2D". "Unit" class defines factory methods "from" to create a normalized instance. --- .../euclidean/twod/AffineTransformMatrix2D.java | 2 +- .../commons/geometry/euclidean/twod/Line.java | 2 +- .../commons/geometry/euclidean/twod/Vector2D.java | 77 +++++++++++++--------- .../geometry/euclidean/twod/Vector2DTest.java | 12 ++-- 4 files changed, 55 insertions(+), 38 deletions(-) diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java index 2192f43..ae80335 100644 --- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java +++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java @@ -164,7 +164,7 @@ public final class AffineTransformMatrix2D implements AffineTransformMatrix<Vect */ @Override public Vector2D applyDirection(final Vector2D vec) { - return applyVector(vec, Vector2D::normalize); + return applyVector(vec, Vector2D.Unit::from); } /** Apply a translation to the current instance, returning the result as a new transform. diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java index 2fc9446..3ac9d9d 100644 --- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java +++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java @@ -420,7 +420,7 @@ public final class Line implements Hyperplane<Vector2D>, Embedding<Vector2D, Vec * abscissa (x) axis. */ public static Line fromPointAndAngle(final Vector2D pt, final double angle, final DoublePrecisionContext precision) { - final Vector2D dir = Vector2D.normalize(Math.cos(angle), Math.sin(angle)); + final Vector2D.Unit dir = Vector2D.Unit.from(Math.cos(angle), Math.sin(angle)); return fromPointAndDirection(pt, dir, precision); } diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java index 1b7c797..85dac32 100644 --- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java +++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java @@ -33,16 +33,16 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { public static final Vector2D ZERO = new Vector2D(0, 0); /** Unit vector pointing in the direction of the positive x-axis. */ - public static final Vector2D PLUS_X = new UnitVector(1, 0); + public static final Vector2D PLUS_X = Unit.PLUS_X; /** Unit vector pointing in the direction of the negative x-axis. */ - public static final Vector2D MINUS_X = new UnitVector(-1, 0); + public static final Vector2D MINUS_X = Unit.MINUS_X; /** Unit vector pointing in the direction of the positive y-axis. */ - public static final Vector2D PLUS_Y = new UnitVector(0, 1); + public static final Vector2D PLUS_Y = Unit.PLUS_Y; /** Unit vector pointing in the direction of the negative y-axis. */ - public static final Vector2D MINUS_Y = new UnitVector(0, -1); + public static final Vector2D MINUS_Y = Unit.MINUS_Y; // CHECKSTYLE: stop ConstantName /** A vector with all coordinates set to NaN. */ @@ -123,10 +123,7 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { /** {@inheritDoc} */ @Override public Vector2D directionTo(Vector2D v) { - return normalize( - v.x - x, - v.y - y - ); + return vectorTo(v).normalize(); } /** {@inheritDoc} */ @@ -197,7 +194,7 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { /** {@inheritDoc} */ @Override public Vector2D normalize() { - return normalize(x, y); + return Unit.from(x, y); } /** {@inheritDoc} */ @@ -273,13 +270,13 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { */ @Override public Vector2D orthogonal() { - return normalize(-y, x); + return Unit.from(-y, x); } /** {@inheritDoc} */ @Override public Vector2D orthogonal(Vector2D dir) { - return dir.getComponent(this, true, Vector2D::normalize); + return dir.getComponent(this, true, Vector2D.Unit::from); } /** Compute the signed area of the parallelogram with sides formed by this instance @@ -432,19 +429,6 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { return new Vector2D(v[0], v[1]); } - /** Returns a normalized vector derived from the given values. - * @param x abscissa (first coordinate value) - * @param y ordinate (second coordinate value) - * @return normalized vector instance - * @throws IllegalNormException if the norm of the given values is zero, NaN, or infinite - */ - public static Vector2D normalize(final double x, final double y) { - final double norm = Vectors.checkedNorm(Vectors.norm(x, y)); - final double invNorm = 1.0 / norm; - - return new UnitVector(x * invNorm, y * invNorm); - } - /** Parses the given string and returns a new vector instance. The expected string * format is the same as that returned by {@link #toString()}. * @param str the string to parse @@ -531,10 +515,19 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { LinearCombination.value(a1, v1.y, a2, v2.y, a3, v3.y, a4, v4.y)); } - /** Private class used to represent unit vectors. This allows optimizations to be performed for certain - * operations. + /** + * Represents unit vectors. + * This allows optimizations to be performed for certain operations. */ - private static final class UnitVector extends Vector2D { + public static final class Unit extends Vector2D { + /** Unit vector (coordinates: 1, 0). */ + static final Unit PLUS_X = new Unit(1d, 0d); + /** Negation of unit vector (coordinates: -1, 0). */ + static final Unit MINUS_X = new Unit(-1d, 0d); + /** Unit vector (coordinates: 0, 1). */ + static final Unit PLUS_Y = new Unit(0d, 1d); + /** Negation of unit vector (coordinates: 0, -1). */ + static final Unit MINUS_Y = new Unit(0d, -1d); /** Serializable version identifier */ private static final long serialVersionUID = 20180903L; @@ -544,10 +537,34 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { * @param x abscissa (first coordinate value) * @param y abscissa (second coordinate value) */ - private UnitVector(final double x, final double y) { + private Unit(final double x, final double y) { super(x, y); } + /** + * Creates a normalized vector. + * + * @param x Vector coordinate. + * @param y Vector coordinate. + * @return a vector whose norm is 1. + * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite + */ + public static Unit from(double x, double y) { + final double invNorm = 1 / Vectors.checkedNorm(Vectors.norm(x, y)); + return new Unit(x * invNorm, y * invNorm); + } + + /** + * Creates a normalized vector. + * + * @param v Vector. + * @return a vector whose norm is 1. + * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite + */ + public static Unit from(Vector2D v) { + return from(v.getX(), v.getY()); + } + /** {@inheritDoc} */ @Override public double norm() { @@ -574,8 +591,8 @@ public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> { /** {@inheritDoc} */ @Override - public UnitVector negate() { - return new UnitVector(-getX(), -getY()); + public Unit negate() { + return new Unit(-getX(), -getY()); } } } diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java index d619342..70adf0b 100644 --- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java +++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java @@ -956,19 +956,19 @@ public class Vector2DTest { double invSqrt2 = 1.0 / Math.sqrt(2.0); // act/assert - checkVector(Vector2D.normalize(2.0, -2.0), invSqrt2, -invSqrt2); - checkVector(Vector2D.normalize(-4.0, 4.0), -invSqrt2, invSqrt2); + checkVector(Vector2D.Unit.from(2.0, -2.0), invSqrt2, -invSqrt2); + checkVector(Vector2D.Unit.from(-4.0, 4.0), -invSqrt2, invSqrt2); } @Test public void testNormalize_static_illegalNorm() { - GeometryTestUtils.assertThrows(() -> Vector2D.normalize(0.0, 0.0), + GeometryTestUtils.assertThrows(() -> Vector2D.Unit.from(0.0, 0.0), IllegalNormException.class); - GeometryTestUtils.assertThrows(() -> Vector2D.normalize(Double.NaN, 1.0), + GeometryTestUtils.assertThrows(() -> Vector2D.Unit.from(Double.NaN, 1.0), IllegalNormException.class); - GeometryTestUtils.assertThrows(() -> Vector2D.normalize(1.0, Double.NEGATIVE_INFINITY), + GeometryTestUtils.assertThrows(() -> Vector2D.Unit.from(1.0, Double.NEGATIVE_INFINITY), IllegalNormException.class); - GeometryTestUtils.assertThrows(() -> Vector2D.normalize(1.0, Double.POSITIVE_INFINITY), + GeometryTestUtils.assertThrows(() -> Vector2D.Unit.from(1.0, Double.POSITIVE_INFINITY), IllegalNormException.class); }
