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 <[email protected]> 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 (α) around Z - * (0 is +X, π/2 is +Y, π is -X and 3π/2 is -Y) - * @param delta elevation (δ) above (XY) plane, from -π/2 to +π/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);
