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 2018/07/21 10:07:45 UTC

[commons-geometry] 07/15: GEOMETRY-7: adding toSpherical() and ofSpherical() to Cartesian 3D classes

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 f1a6d4b05b3cd6443236fe5e02ceb0f94c0a5f91
Author: Matt Juntunen <ma...@hotmail.com>
AuthorDate: Sun Jul 1 00:33:13 2018 -0400

    GEOMETRY-7: adding toSpherical() and ofSpherical() to Cartesian 3D classes
---
 .../geometry/euclidean/threed/Cartesian3D.java     |  7 ++++
 .../commons/geometry/euclidean/threed/Point3D.java | 11 ++++++
 .../geometry/euclidean/threed/Vector3D.java        | 22 ++++-------
 .../geometry/euclidean/threed/Cartesian3DTest.java | 29 ++++++++++++++
 .../geometry/euclidean/threed/Point3DTest.java     | 24 +++++++++++-
 .../euclidean/threed/SphericalCoordinatesTest.java |  4 +-
 .../geometry/euclidean/threed/Vector3DTest.java    | 44 +++++++++++-----------
 7 files changed, 102 insertions(+), 39 deletions(-)

diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java
index 6b619ac..af412f0 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java
@@ -77,6 +77,13 @@ public abstract class Cartesian3D implements Spatial, Serializable {
         return new double[] { x, y, z };
     }
 
+    /** Return an equivalent set of coordinates in spherical form.
+     * @return an equivalent set of coordinates in spherical form.
+     */
+    public SphericalCoordinates toSpherical() {
+        return SphericalCoordinates.ofCartesian(x, y, z);
+    }
+
     /** {@inheritDoc} */
     @Override
     public int getDimension() {
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java
index f257425..6e4da3e 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java
@@ -190,6 +190,17 @@ public final class Point3D extends Cartesian3D implements EuclideanPoint<Point3D
         return new Point3D(p[0], p[1], p[2]);
     }
 
+    /** Create a point from a set of spherical coordinates.
+     * @param radius the spherical radius value
+     * @param azimuth the angle in the x-y plane measured in radians counter-clockwise from the
+     *      positive x axis.
+     * @param polar the angle with the positive z axis in radians.
+     * @return a point instance with the given set of spherical coordinates
+     */
+    public static Point3D ofSpherical(double radius, double azimuth, double polar) {
+        return SphericalCoordinates.toCartesian(radius, azimuth, polar, FACTORY);
+    }
+
     /** Parses the given string and returns a new point instance. The expected string
      * format is the same as that returned by {@link #toString()}.
      * @param str the string to parse
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 7d8c5e8..eeeeb72 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
@@ -437,21 +437,15 @@ public final class Vector3D extends Cartesian3D implements EuclideanVector<Point
         return new Vector3D(v[0], v[1], v[2]);
     }
 
-    /** Builds a vector from its azimuthal coordinates
-     * @param alpha azimuth (&alpha;) around Z
-     *              (0 is +X, &pi;/2 is +Y, &pi; is -X and 3&pi;/2 is -Y)
-     * @param delta elevation (&delta;) above (XY) plane, from -&pi;/2 to +&pi;/2
-     * @see #getAlpha()
-     * @see #getDelta()
-     * @return new vector instance with the given azimuthal coordinates
+    /** Create a vector from a set of spherical coordinates.
+     * @param radius the spherical radius value
+     * @param azimuth the angle in the x-y plane measured in radians counter-clockwise from the
+     *      positive x axis.
+     * @param polar the angle with the positive z axis in radians.
+     * @return a vector instance with the given set of spherical coordinates
      */
-    public static Vector3D fromSpherical(double alpha, double delta) {
-        double cosDelta = Math.cos(delta);
-        double x = Math.cos(alpha) * cosDelta;
-        double y = Math.sin(alpha) * cosDelta;
-        double z = Math.sin(delta);
-
-        return new Vector3D(x, y, z);
+    public static Vector3D ofSpherical(double radius, double azimuth, double polar) {
+        return SphericalCoordinates.toCartesian(radius, azimuth, polar, FACTORY);
     }
 
     /** Parses the given string and returns a new vector instance. The expected string
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java
index 4e6205d..88547a9 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java
@@ -1,5 +1,6 @@
 package org.apache.commons.geometry.euclidean.threed;
 
+import org.apache.commons.geometry.core.Geometry;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -33,6 +34,28 @@ public class Cartesian3DTest {
         Assert.assertEquals(3.0, arr[2], TEST_TOLERANCE);
     }
 
+
+    @Test
+    public void testToSpherical() {
+        // arrange
+        double sqrt3 = Math.sqrt(3);
+
+        // act/assert
+        checkSpherical(new StubCartesian3D(0, 0, 0).toSpherical(), 0, 0, 0);
+
+        checkSpherical(new StubCartesian3D(0.1, 0, 0).toSpherical(), 0.1, 0, Geometry.HALF_PI);
+        checkSpherical(new StubCartesian3D(-0.1, 0, 0).toSpherical(), 0.1, Geometry.PI, Geometry.HALF_PI);
+
+        checkSpherical(new StubCartesian3D(0, 0.1, 0).toSpherical(), 0.1, Geometry.HALF_PI, Geometry.HALF_PI);
+        checkSpherical(new StubCartesian3D(0, -0.1, 0).toSpherical(), 0.1, Geometry.MINUS_HALF_PI, Geometry.HALF_PI);
+
+        checkSpherical(new StubCartesian3D(0, 0, 0.1).toSpherical(), 0.1, 0, 0);
+        checkSpherical(new StubCartesian3D(0, 0, -0.1).toSpherical(), 0.1, 0, Geometry.PI);
+
+        checkSpherical(new StubCartesian3D(1, 1, 1).toSpherical(), sqrt3, 0.25 * Geometry.PI, Math.acos(1 / sqrt3));
+        checkSpherical(new StubCartesian3D(-1, -1, -1).toSpherical(), sqrt3, -0.75 * Geometry.PI, Math.acos(-1 / sqrt3));
+    }
+
     @Test
     public void testDimension() {
         // arrange
@@ -73,6 +96,12 @@ public class Cartesian3DTest {
         Assert.assertFalse(new StubCartesian3D(0, Double.NaN, Double.POSITIVE_INFINITY).isInfinite());
     }
 
+    private void checkSpherical(SphericalCoordinates c, double radius, double azimuth, double polar) {
+        Assert.assertEquals(radius, c.getRadius(), TEST_TOLERANCE);
+        Assert.assertEquals(azimuth, c.getAzimuth(), TEST_TOLERANCE);
+        Assert.assertEquals(polar, c.getPolar(), TEST_TOLERANCE);
+    }
+
     private static class StubCartesian3D extends Cartesian3D {
         private static final long serialVersionUID = 1L;
 
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java
index d20d918..770cf25 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java
@@ -18,6 +18,7 @@ package org.apache.commons.geometry.euclidean.threed;
 
 import java.util.regex.Pattern;
 
+import org.apache.commons.geometry.core.Geometry;
 import org.apache.commons.geometry.core.util.Coordinates;
 import org.apache.commons.numbers.core.Precision;
 import org.junit.Assert;
@@ -25,7 +26,7 @@ import org.junit.Test;
 
 public class Point3DTest {
 
-    private static final double EPS = Math.ulp(1d);
+    private static final double EPS = 1e-15;
 
     @Test
     public void testConstants() {
@@ -243,6 +244,27 @@ public class Point3DTest {
     }
 
     @Test
+    public void testOfSpherical() {
+     // arrange
+        double sqrt3 = Math.sqrt(3);
+
+        // act/assert
+        checkPoint(Point3D.ofSpherical(0, 0, 0), 0, 0, 0);
+
+        checkPoint(Point3D.ofSpherical(1, 0, Geometry.HALF_PI), 1, 0, 0);
+        checkPoint(Point3D.ofSpherical(1, Geometry.PI, Geometry.HALF_PI), -1, 0, 0);
+
+        checkPoint(Point3D.ofSpherical(2, Geometry.HALF_PI, Geometry.HALF_PI), 0, 2, 0);
+        checkPoint(Point3D.ofSpherical(2, Geometry.MINUS_HALF_PI, Geometry.HALF_PI), 0, -2, 0);
+
+        checkPoint(Point3D.ofSpherical(3, 0, 0), 0, 0, 3);
+        checkPoint(Point3D.ofSpherical(3, 0, Geometry.PI), 0, 0, -3);
+
+        checkPoint(Point3D.ofSpherical(sqrt3, 0.25 * Geometry.PI, Math.acos(1 / sqrt3)), 1, 1, 1);
+        checkPoint(Point3D.ofSpherical(sqrt3, -0.75 * Geometry.PI, Math.acos(-1 / sqrt3)), -1, -1, -1);
+    }
+
+    @Test
     public void testGetFactory() {
         // act
         Coordinates.Factory3D<Point3D> factory = Point3D.getFactory();
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
index 37d381d..1acfde7 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
@@ -173,8 +173,8 @@ public class SphericalCoordinatesTest {
         checkVector(SphericalCoordinates.of(3, 0, 0).toVector(), 0, 0, 3);
         checkVector(SphericalCoordinates.of(3, 0, Geometry.PI).toVector(), 0, 0, -3);
 
-        checkVector(SphericalCoordinates.of(Math.sqrt(3), QUARTER_PI, Math.acos(1 / sqrt3)).toVector(), 1, 1, 1);
-        checkVector(SphericalCoordinates.of(Math.sqrt(3), MINUS_THREE_QUARTER_PI, Math.acos(-1 / sqrt3)).toVector(), -1, -1, -1);
+        checkVector(SphericalCoordinates.of(sqrt3, QUARTER_PI, Math.acos(1 / sqrt3)).toVector(), 1, 1, 1);
+        checkVector(SphericalCoordinates.of(sqrt3, MINUS_THREE_QUARTER_PI, Math.acos(-1 / sqrt3)).toVector(), -1, -1, -1);
     }
 
     @Test
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 86bf0a3..d52d358 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
@@ -29,7 +29,7 @@ import org.junit.Test;
 
 public class Vector3DTest {
 
-    private static final double EPS = Math.ulp(1d);
+    private static final double EPS = 1e-15;
 
     @Test
     public void testConstants() {
@@ -689,6 +689,27 @@ public class Vector3DTest {
     }
 
     @Test
+    public void testOfSpherical() {
+     // arrange
+        double sqrt3 = Math.sqrt(3);
+
+        // act/assert
+        checkVector(Vector3D.ofSpherical(0, 0, 0), 0, 0, 0);
+
+        checkVector(Vector3D.ofSpherical(1, 0, Geometry.HALF_PI), 1, 0, 0);
+        checkVector(Vector3D.ofSpherical(1, Geometry.PI, Geometry.HALF_PI), -1, 0, 0);
+
+        checkVector(Vector3D.ofSpherical(2, Geometry.HALF_PI, Geometry.HALF_PI), 0, 2, 0);
+        checkVector(Vector3D.ofSpherical(2, Geometry.MINUS_HALF_PI, Geometry.HALF_PI), 0, -2, 0);
+
+        checkVector(Vector3D.ofSpherical(3, 0, 0), 0, 0, 3);
+        checkVector(Vector3D.ofSpherical(3, 0, Geometry.PI), 0, 0, -3);
+
+        checkVector(Vector3D.ofSpherical(sqrt3, 0.25 * Geometry.PI, Math.acos(1 / sqrt3)), 1, 1, 1);
+        checkVector(Vector3D.ofSpherical(sqrt3, -0.75 * Geometry.PI, Math.acos(-1 / sqrt3)), -1, -1, -1);
+    }
+
+    @Test
     public void testGetFactory() {
         // act
         Coordinates.Factory3D<Vector3D> factory = Vector3D.getFactory();
@@ -749,27 +770,6 @@ public class Vector3DTest {
         checkVector(Vector3D.linearCombination(-3, p1, 2, p2, -4, p3, 5, p4), -64, -78, -2);
     }
 
-    @Test
-    public void testConstructors() {
-        double r = Math.sqrt(2) /2;
-        checkVector(Vector3D.linearCombination(2, Vector3D.fromSpherical(Math.PI / 3, -Math.PI / 4)),
-                    r, r * Math.sqrt(3), -2 * r);
-        checkVector(Vector3D.linearCombination(2, Vector3D.PLUS_X,
-                                 -3, Vector3D.MINUS_Z),
-                    2, 0, 3);
-        checkVector(Vector3D.linearCombination(2, Vector3D.PLUS_X,
-                                 5, Vector3D.PLUS_Y,
-                                 -3, Vector3D.MINUS_Z),
-                    2, 5, 3);
-        checkVector(Vector3D.linearCombination(2, Vector3D.PLUS_X,
-                                 5, Vector3D.PLUS_Y,
-                                 5, Vector3D.MINUS_Y,
-                                 -3, Vector3D.MINUS_Z),
-                    2, 0, 3);
-        checkVector(Vector3D.of(new double[] { 2,  5,  -3 }),
-                    2, 5, -3);
-    }
-
     private void checkVector(Vector3D v, double x, double y, double z) {
         Assert.assertEquals(x, v.getX(), EPS);
         Assert.assertEquals(y, v.getY(), EPS);