You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2019/09/27 14:35:13 UTC

[commons-geometry] 03/06: GEOMETRY-61: Improvement of "normalize" functionality for class "Vector2D".

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 <gi...@harfang.homelinux.org>
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);
     }