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 a009c78f19acf0b6feb9473a2de3ec8513710bf7
Author: Gilles Sadowski <[email protected]>
AuthorDate: Fri Sep 27 13:58:31 2019 +0200

    GEOMETRY-61: Improvement of "normalize" functionality for class "Vector3D".
    
    "Unit" class defines factory methods "from" to create a normalized instance.
---
 .../euclidean/threed/AffineTransformMatrix3D.java  |  2 +-
 .../geometry/euclidean/threed/Vector3D.java        | 85 ++++++++++++++--------
 .../threed/rotation/QuaternionRotation.java        |  2 +-
 .../geometry/euclidean/threed/PlaneTest.java       | 14 ++--
 .../geometry/euclidean/threed/Vector3DTest.java    | 12 +--
 5 files changed, 68 insertions(+), 47 deletions(-)

diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
index cd25f7b..92d2b2a 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
@@ -199,7 +199,7 @@ public final class AffineTransformMatrix3D implements 
AffineTransformMatrix<Vect
      */
     @Override
     public Vector3D applyDirection(final Vector3D vec) {
-        return applyVector(vec, Vector3D::normalize);
+        return applyVector(vec, Vector3D.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/threed/Vector3D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
index e0f86f3..5aa4610 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
@@ -34,22 +34,22 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
     public static final Vector3D ZERO   = new Vector3D(0, 0, 0);
 
     /** First canonical vector (coordinates: 1, 0, 0). */
-    public static final Vector3D PLUS_X = new UnitVector(1, 0, 0);
+    public static final Vector3D PLUS_X = Unit.PLUS_X;
 
     /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */
-    public static final Vector3D MINUS_X = new UnitVector(-1, 0, 0);
+    public static final Vector3D MINUS_X = Unit.MINUS_X;
 
     /** Second canonical vector (coordinates: 0, 1, 0). */
-    public static final Vector3D PLUS_Y = new UnitVector(0, 1, 0);
+    public static final Vector3D PLUS_Y = Unit.PLUS_Y;
 
     /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */
-    public static final Vector3D MINUS_Y = new UnitVector(0, -1, 0);
+    public static final Vector3D MINUS_Y = Unit.MINUS_Y;
 
     /** Third canonical vector (coordinates: 0, 0, 1). */
-    public static final Vector3D PLUS_Z = new UnitVector(0, 0, 1);
+    public static final Vector3D PLUS_Z = Unit.PLUS_Z;
 
     /** Opposite of the third canonical vector (coordinates: 0, 0, -1).  */
-    public static final Vector3D MINUS_Z = new UnitVector(0, 0, -1);
+    public static final Vector3D MINUS_Z = Unit.MINUS_Z;
 
     // CHECKSTYLE: stop ConstantName
     /** A vector with all coordinates set to NaN. */
@@ -149,10 +149,7 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
     /** {@inheritDoc} */
     @Override
     public Vector3D directionTo(Vector3D v) {
-        return normalize(
-                v.x - x,
-                v.y - y,
-                v.z - z);
+        return vectorTo(v).normalize();
     }
 
     /** {@inheritDoc} */
@@ -234,7 +231,7 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
     /** {@inheritDoc} */
     @Override
     public Vector3D normalize() {
-        return normalize(x, y, z);
+        return Unit.from(x, y, z);
     }
 
     /** {@inheritDoc} */
@@ -348,7 +345,7 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
     /** {@inheritDoc} */
     @Override
     public Vector3D orthogonal(Vector3D dir) {
-        return dir.getComponent(this, true, Vector3D::normalize);
+        return dir.getComponent(this, true, Vector3D.Unit::from);
     }
 
     /** Compute the cross-product of the instance with another vector.
@@ -493,20 +490,6 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
         return new Vector3D(v[0], v[1], v[2]);
     }
 
-    /** Returns a normalized vector derived from the given values.
-     * @param x abscissa (first coordinate value)
-     * @param y ordinate (second coordinate value)
-     * @param z height (third coordinate value)
-     * @return normalized vector instance
-     * @throws IllegalNormException if the norm of the given values is zero, 
NaN, or infinite
-     */
-    public static Vector3D normalize(final double x, final double y, final 
double z) {
-        final double norm = Vectors.checkedNorm(Vectors.norm(x, y, z));
-        final double invNorm = 1.0 / norm;
-
-        return new UnitVector(x * invNorm, y * invNorm, z * 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
@@ -596,10 +579,23 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
                 LinearCombination.value(a1, v1.z, a2, v2.z, a3, v3.z, a4, 
v4.z));
     }
 
-    /** 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 Vector3D {
+    public static final class Unit extends Vector3D {
+        /** Unit vector (coordinates: 1, 0, 0). */
+        static final Unit PLUS_X  = new Unit(1d, 0d, 0d);
+        /** Negation of unit vector (coordinates: -1, 0, 0). */
+        static final Unit MINUS_X = new Unit(-1d, 0d, 0d);
+        /** Unit vector (coordinates: 0, 1, 0). */
+        static final Unit PLUS_Y  = new Unit(0d, 1d, 0d);
+        /** Negation of unit vector (coordinates: 0, -1, 0). */
+        static final Unit MINUS_Y = new Unit(0d, -1d, 0d);
+        /** Unit vector (coordinates: 0, 0, 1). */
+        static final Unit PLUS_Z  = new Unit(0d, 0d, 1d);
+        /** Negation of unit vector (coordinates: 0, 0, -1). */
+        static final Unit MINUS_Z = new Unit(0d, 0d, -1d);
 
         /** Serializable version identifier */
         private static final long serialVersionUID = 20180903L;
@@ -610,10 +606,35 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
          * @param y ordinate (second coordinate value)
          * @param z height (third coordinate value)
          */
-        private UnitVector(final double x, final double y, final double z) {
+        private Unit(final double x, final double y, final double z) {
             super(x, y, z);
         }
 
+        /**
+         * Creates a normalized vector.
+         *
+         * @param x Vector coordinate.
+         * @param y Vector coordinate.
+         * @param z 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, double z) {
+            final double invNorm = 1 / Vectors.checkedNorm(Vectors.norm(x, y, 
z));
+            return new Unit(x * invNorm, y * invNorm, z * 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(Vector3D v) {
+            return from(v.getX(), v.getY(), v.getZ());
+        }
+
         /** {@inheritDoc} */
         @Override
         public double norm() {
@@ -640,8 +661,8 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
 
         /** {@inheritDoc} */
         @Override
-        public UnitVector negate() {
-            return new UnitVector(-getX(), -getY(), -getZ());
+        public Unit negate() {
+            return new Unit(-getX(), -getY(), -getZ());
         }
     }
 }
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/QuaternionRotation.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/QuaternionRotation.java
index 957ff56..2e67ce5 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/QuaternionRotation.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/QuaternionRotation.java
@@ -91,7 +91,7 @@ public final class QuaternionRotation implements Rotation3D, 
Serializable {
         // the most straightforward way to check if we have a normalizable
         // vector is to just try to normalize it and see if we fail
         try {
-            return Vector3D.normalize(quat.getX(), quat.getY(), quat.getZ());
+            return Vector3D.Unit.from(quat.getX(), quat.getY(), quat.getZ());
         }
         catch (IllegalNormException exc) {
             return Vector3D.PLUS_X;
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
index af76826..9757ce3 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
@@ -280,22 +280,22 @@ public class PlaneTest {
                 origin, Vector3D.MINUS_Z, Vector3D.PLUS_Y);
 
         checkPlane(Plane.fromPoints(rotate(pts, 2), TEST_PRECISION),
-                origin, Vector3D.normalize(0, 1, -1), Vector3D.normalize(0, 1, 
1));
+                origin, Vector3D.Unit.from(0, 1, -1), Vector3D.Unit.from(0, 1, 
1));
 
         checkPlane(Plane.fromPoints(rotate(pts, 3), TEST_PRECISION),
-                origin, Vector3D.normalize(0, 1, 1), Vector3D.normalize(0, -1, 
1));
+                origin, Vector3D.Unit.from(0, 1, 1), Vector3D.Unit.from(0, -1, 
1));
 
         checkPlane(Plane.fromPoints(rotate(pts, 4), TEST_PRECISION),
-                origin, Vector3D.normalize(0, -1, -0.5), Vector3D.normalize(0, 
0.5, -1));
+                origin, Vector3D.Unit.from(0, -1, -0.5), Vector3D.Unit.from(0, 
0.5, -1));
         checkPlane(Plane.fromPoints(rotate(pts, 5), TEST_PRECISION),
-                origin, Vector3D.normalize(0, -1, -0.5), Vector3D.normalize(0, 
0.5, -1));
+                origin, Vector3D.Unit.from(0, -1, -0.5), Vector3D.Unit.from(0, 
0.5, -1));
 
         checkPlane(Plane.fromPoints(rotate(pts, 6), TEST_PRECISION),
-                origin, Vector3D.normalize(0, -1, 0.5), Vector3D.normalize(0, 
-0.5, -1));
+                origin, Vector3D.Unit.from(0, -1, 0.5), Vector3D.Unit.from(0, 
-0.5, -1));
         checkPlane(Plane.fromPoints(rotate(pts, 7), TEST_PRECISION),
-                origin, Vector3D.normalize(0, -1, 0.5), Vector3D.normalize(0, 
-0.5, -1));
+                origin, Vector3D.Unit.from(0, -1, 0.5), Vector3D.Unit.from(0, 
-0.5, -1));
         checkPlane(Plane.fromPoints(rotate(pts, 8), TEST_PRECISION),
-                origin, Vector3D.normalize(0, -1, 0.5), Vector3D.normalize(0, 
-0.5, -1));
+                origin, Vector3D.Unit.from(0, -1, 0.5), Vector3D.Unit.from(0, 
-0.5, -1));
 
         checkPlane(Plane.fromPoints(rotate(pts, 9), TEST_PRECISION),
                 origin, Vector3D.PLUS_Z, Vector3D.MINUS_Y);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
index c4b5de3..f876dff 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
@@ -1140,19 +1140,19 @@ public class Vector3DTest {
         double invSqrt3 = 1.0 / Math.sqrt(3.0);
 
         // act/assert
-        checkVector(Vector3D.normalize(2.0, -2.0, 2.0), invSqrt3, -invSqrt3, 
invSqrt3);
-        checkVector(Vector3D.normalize(-4.0, 4.0, -4.0), -invSqrt3, invSqrt3, 
-invSqrt3);
+        checkVector(Vector3D.Unit.from(2.0, -2.0, 2.0), invSqrt3, -invSqrt3, 
invSqrt3);
+        checkVector(Vector3D.Unit.from(-4.0, 4.0, -4.0), -invSqrt3, invSqrt3, 
-invSqrt3);
     }
 
     @Test
     public void testNormalize_static_illegalNorm() {
-        GeometryTestUtils.assertThrows(() -> Vector3D.normalize(0.0, 0.0, 0.0),
+        GeometryTestUtils.assertThrows(() -> Vector3D.Unit.from(0.0, 0.0, 0.0),
                 IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> Vector3D.normalize(Double.NaN, 
1.0, 1.0),
+        GeometryTestUtils.assertThrows(() -> Vector3D.Unit.from(Double.NaN, 
1.0, 1.0),
                 IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> Vector3D.normalize(1.0, 
Double.NEGATIVE_INFINITY, 1.0),
+        GeometryTestUtils.assertThrows(() -> Vector3D.Unit.from(1.0, 
Double.NEGATIVE_INFINITY, 1.0),
                 IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> Vector3D.normalize(1.0, 1.0, 
Double.POSITIVE_INFINITY),
+        GeometryTestUtils.assertThrows(() -> Vector3D.Unit.from(1.0, 1.0, 
Double.POSITIVE_INFINITY),
                 IllegalNormException.class);
     }
 

Reply via email to