commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From raydeca...@apache.org
Subject [22/31] [math] MATH-1284: Replace/rename Coordinate?D classes (nee Vector?D) as Cartesian?D classes as per discussion. When there are existing overridden methods accepting Vector<Euclidean?D> and Point<Euclidean?D>, add a disambiguating method accepting
Date Fri, 12 May 2017 21:32:31 GMT
MATH-1284: Replace/rename Coordinate?D classes (nee Vector?D) as Cartesian?D classes as per discussion.
When there are existing overridden methods accepting Vector<Euclidean?D> and Point<Euclidean?D>, add a disambiguating method accepting a Cartesian?D.
Eliminate casts where possible.

Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/e21d4d43
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/e21d4d43
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/e21d4d43

Branch: refs/heads/master
Commit: e21d4d436b51d88f9554751982cd7b8552854c49
Parents: b815d2a
Author: Ray DeCampo <ray@decampo.org>
Authored: Sat Apr 29 20:29:29 2017 -0400
Committer: Ray DeCampo <ray@decampo.org>
Committed: Sat Apr 29 20:29:29 2017 -0400

----------------------------------------------------------------------
 .../geometry/euclidean/oned/Cartesian1D.java    |  386 ++++++
 .../geometry/euclidean/oned/Coordinates1D.java  |  386 ------
 .../geometry/euclidean/oned/IntervalsSet.java   |   18 +-
 .../geometry/euclidean/oned/OrientedPoint.java  |    8 +-
 .../geometry/euclidean/oned/Vector1DFormat.java |   12 +-
 .../geometry/euclidean/threed/Cartesian3D.java  |  621 +++++++++
 .../euclidean/threed/Coordinates3D.java         |  621 ---------
 .../euclidean/threed/FieldRotation.java         |   52 +-
 .../euclidean/threed/FieldVector3D.java         |   78 +-
 .../math4/geometry/euclidean/threed/Line.java   |   80 +-
 .../euclidean/threed/OutlineExtractor.java      |   46 +-
 .../math4/geometry/euclidean/threed/Plane.java  |  131 +-
 .../euclidean/threed/PolyhedronsSet.java        |   96 +-
 .../geometry/euclidean/threed/Rotation.java     |  136 +-
 .../euclidean/threed/RotationOrder.java         |   38 +-
 .../geometry/euclidean/threed/Segment.java      |   10 +-
 .../euclidean/threed/SphereGenerator.java       |   22 +-
 .../euclidean/threed/SphericalCoordinates.java  |   10 +-
 .../geometry/euclidean/threed/SubLine.java      |   14 +-
 .../geometry/euclidean/threed/SubPlane.java     |   14 +-
 .../euclidean/threed/Vector3DFormat.java        |   22 +-
 .../geometry/euclidean/twod/Cartesian2D.java    |  492 +++++++
 .../geometry/euclidean/twod/Coordinates2D.java  |  492 -------
 .../geometry/euclidean/twod/DiskGenerator.java  |   16 +-
 .../math4/geometry/euclidean/twod/Line.java     |   93 +-
 .../geometry/euclidean/twod/NestedLoops.java    |   12 +-
 .../geometry/euclidean/twod/PolygonsSet.java    |   78 +-
 .../math4/geometry/euclidean/twod/Segment.java  |   14 +-
 .../math4/geometry/euclidean/twod/SubLine.java  |   18 +-
 .../geometry/euclidean/twod/Vector2DFormat.java |   12 +-
 .../hull/AbstractConvexHullGenerator2D.java     |   10 +-
 .../twod/hull/AklToussaintHeuristic.java        |   34 +-
 .../euclidean/twod/hull/ConvexHull2D.java       |   32 +-
 .../twod/hull/ConvexHullGenerator2D.java        |    6 +-
 .../euclidean/twod/hull/MonotoneChain.java      |   28 +-
 .../math4/geometry/spherical/oned/S1Point.java  |   14 +-
 .../math4/geometry/spherical/twod/Circle.java   |   34 +-
 .../math4/geometry/spherical/twod/Edge.java     |    4 +-
 .../geometry/spherical/twod/EdgesBuilder.java   |   10 +-
 .../spherical/twod/PropertiesComputer.java      |   30 +-
 .../math4/geometry/spherical/twod/S2Point.java  |   32 +-
 .../spherical/twod/SphericalPolygonsSet.java    |   26 +-
 .../geometry/spherical/twod/SubCircle.java      |    4 +-
 .../commons/math4/complex/QuaternionTest.java   |   30 +-
 ...stractLeastSquaresOptimizerAbstractTest.java |    6 +-
 .../fitting/leastsquares/CircleVectorial.java   |   18 +-
 .../GaussNewtonOptimizerWithSVDTest.java        |    6 +-
 .../LevenbergMarquardtOptimizerTest.java        |    6 +-
 .../RandomCirclePointGenerator.java             |   10 +-
 .../geometry/enclosing/WelzlEncloser2DTest.java |   56 +-
 .../geometry/enclosing/WelzlEncloser3DTest.java |  110 +-
 .../euclidean/oned/IntervalsSetTest.java        |   44 +-
 .../oned/Vector1DFormatAbstractTest.java        |   69 +-
 .../geometry/euclidean/oned/Vector1DTest.java   |  129 +-
 .../euclidean/threed/FieldRotationDSTest.java   |   20 +-
 .../euclidean/threed/FieldRotationDfpTest.java  |    6 +-
 .../euclidean/threed/FieldVector3DTest.java     |   70 +-
 .../geometry/euclidean/threed/LineTest.java     |   76 +-
 .../geometry/euclidean/threed/PLYParser.java    |    8 +-
 .../geometry/euclidean/threed/PlaneTest.java    |   88 +-
 .../euclidean/threed/PolyhedronsSetTest.java    |  146 +-
 .../geometry/euclidean/threed/RotationTest.java |  250 ++--
 .../euclidean/threed/SphereGeneratorTest.java   |  114 +-
 .../threed/SphericalCoordinatesTest.java        |   30 +-
 .../geometry/euclidean/threed/SubLineTest.java  |   60 +-
 .../threed/Vector3DFormatAbstractTest.java      |   74 +-
 .../geometry/euclidean/threed/Vector3DTest.java |  246 ++--
 .../euclidean/twod/DiskGeneratorTest.java       |   58 +-
 .../math4/geometry/euclidean/twod/LineTest.java |   65 +-
 .../euclidean/twod/NestedLoopsTest.java         |   16 +-
 .../euclidean/twod/PolygonsSetTest.java         | 1260 +++++++++---------
 .../geometry/euclidean/twod/SegmentTest.java    |   14 +-
 .../geometry/euclidean/twod/SubLineTest.java    |   60 +-
 .../twod/Vector2DFormatAbstractTest.java        |   74 +-
 .../geometry/euclidean/twod/Vector2DTest.java   |  110 +-
 .../twod/hull/AklToussaintHeuristicTest.java    |    4 +-
 .../hull/ConvexHullGenerator2DAbstractTest.java |  226 ++--
 .../euclidean/twod/hull/MonotoneChainTest.java  |   22 +-
 .../geometry/partitioning/RegionDumper.java     |   10 +-
 .../geometry/partitioning/RegionParser.java     |   16 +-
 .../geometry/spherical/twod/CircleTest.java     |   80 +-
 .../twod/SphericalPolygonsSetTest.java          |  152 +--
 .../geometry/spherical/twod/SubCircleTest.java  |   34 +-
 .../MultiStartMultivariateOptimizerTest.java    |    4 +-
 .../nonlinear/scalar/gradient/CircleScalar.java |   18 +-
 ...NonLinearConjugateGradientOptimizerTest.java |    4 +-
 86 files changed, 4118 insertions(+), 4073 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1D.java
new file mode 100644
index 0000000..0a248a1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1D.java
@@ -0,0 +1,386 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math4.geometry.euclidean.oned;
+
+import java.text.NumberFormat;
+
+import org.apache.commons.math4.exception.MathArithmeticException;
+import org.apache.commons.math4.exception.util.LocalizedFormats;
+import org.apache.commons.math4.geometry.Point;
+import org.apache.commons.math4.geometry.Space;
+import org.apache.commons.math4.geometry.Vector;
+import org.apache.commons.math4.util.FastMath;
+import org.apache.commons.math4.util.MathUtils;
+
+/** This class represents a 1D point or a 1D vector.
+ * <p>An instance of Cartesian1D represents the point with the corresponding
+ * Cartesian coordinates.</p>
+ * <p>An instance of Cartesian1D also represents the vector which begins at
+ * the origin and ends at the point corresponding to the coordinates.</p>
+ * <p>Instances of this class are guaranteed to be immutable.</p>
+ * @since 4.0
+ */
+public class Cartesian1D implements Point<Euclidean1D>, Vector<Euclidean1D> {
+
+    /** Origin (coordinates: 0). */
+    public static final Cartesian1D ZERO = new Cartesian1D(0.0);
+
+    /** Unit (coordinates: 1). */
+    public static final Cartesian1D ONE  = new Cartesian1D(1.0);
+
+    // CHECKSTYLE: stop ConstantName
+    /** A vector with all coordinates set to NaN. */
+    public static final Cartesian1D NaN = new Cartesian1D(Double.NaN);
+    // CHECKSTYLE: resume ConstantName
+
+    /** A vector with all coordinates set to positive infinity. */
+    public static final Cartesian1D POSITIVE_INFINITY =
+        new Cartesian1D(Double.POSITIVE_INFINITY);
+
+    /** A vector with all coordinates set to negative infinity. */
+    public static final Cartesian1D NEGATIVE_INFINITY =
+        new Cartesian1D(Double.NEGATIVE_INFINITY);
+
+    /** Serializable UID. */
+    private static final long serialVersionUID = 7556674948671647925L;
+
+    /** Abscissa. */
+    private final double x;
+
+    /** Simple constructor.
+     * Build a vector from its coordinates
+     * @param x abscissa
+     * @see #getX()
+     */
+    public Cartesian1D(double x) {
+        this.x = x;
+    }
+
+    /** Multiplicative constructor
+     * Build a vector from another one and a scale factor.
+     * The vector built will be a * u
+     * @param a scale factor
+     * @param u base (unscaled) vector
+     */
+    public Cartesian1D(double a, Cartesian1D u) {
+        this.x = a * u.x;
+    }
+
+    /** Linear constructor
+     * Build a vector from two other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     */
+    public Cartesian1D(double a1, Cartesian1D u1, double a2, Cartesian1D u2) {
+        this.x = a1 * u1.x + a2 * u2.x;
+    }
+
+    /** Linear constructor
+     * Build a vector from three other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     */
+    public Cartesian1D(double a1, Cartesian1D u1, double a2, Cartesian1D u2,
+                   double a3, Cartesian1D u3) {
+        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
+    }
+
+    /** Linear constructor
+     * Build a vector from four other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     * @param a4 fourth scale factor
+     * @param u4 fourth base (unscaled) vector
+     */
+    public Cartesian1D(double a1, Cartesian1D u1, double a2, Cartesian1D u2,
+                   double a3, Cartesian1D u3, double a4, Cartesian1D u4) {
+        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
+    }
+
+    /** Get the abscissa of the vector.
+     * @return abscissa of the vector
+     * @see #Vector1D(double)
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Space getSpace() {
+        return Euclidean1D.getInstance();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D getZero() {
+        return ZERO;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm1() {
+        return FastMath.abs(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm() {
+        return FastMath.abs(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNormSq() {
+        return x * x;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNormInf() {
+        return FastMath.abs(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D add(Vector<Euclidean1D> v) {
+        Cartesian1D v1 = (Cartesian1D) v;
+        return new Cartesian1D(x + v1.getX());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D add(double factor, Vector<Euclidean1D> v) {
+        Cartesian1D v1 = (Cartesian1D) v;
+        return new Cartesian1D(x + factor * v1.getX());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D subtract(Vector<Euclidean1D> p) {
+        Cartesian1D p3 = (Cartesian1D) p;
+        return new Cartesian1D(x - p3.x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D subtract(double factor, Vector<Euclidean1D> v) {
+        Cartesian1D v1 = (Cartesian1D) v;
+        return new Cartesian1D(x - factor * v1.getX());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D normalize() throws MathArithmeticException {
+        double s = getNorm();
+        if (s == 0) {
+            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+        }
+        return scalarMultiply(1 / s);
+    }
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D negate() {
+        return new Cartesian1D(-x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian1D scalarMultiply(double a) {
+        return new Cartesian1D(a * x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isNaN() {
+        return Double.isNaN(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isInfinite() {
+        return !isNaN() && Double.isInfinite(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance1(Vector<Euclidean1D> p) {
+        Cartesian1D p1 = (Cartesian1D) p;
+        final double dx = FastMath.abs(p1.x - x);
+        return dx;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance(Point<Euclidean1D> p) {
+        return distance((Cartesian1D) p);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance(Vector<Euclidean1D> v) {
+        return distance((Cartesian1D) v);
+    }
+
+    /** Compute the distance between the instance and other coordinates.
+     * @param c other coordinates
+     * @return the distance between the instance and c
+     */
+    public double distance(Cartesian1D c) {
+        final double dx = c.x - x;
+        return FastMath.abs(dx);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distanceInf(Vector<Euclidean1D> p) {
+        Cartesian1D p1 = (Cartesian1D) p;
+        final double dx = FastMath.abs(p1.x - x);
+        return dx;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distanceSq(Vector<Euclidean1D> p) {
+        Cartesian1D p1 = (Cartesian1D) p;
+        final double dx = p1.x - x;
+        return dx * dx;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double dotProduct(final Vector<Euclidean1D> v) {
+        final Cartesian1D v1 = (Cartesian1D) v;
+        return x * v1.x;
+    }
+
+    /** Compute the distance between two points according to the L<sub>2</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>p1.subtract(p2).getNorm()</code> except that no intermediate
+     * vector is built</p>
+     * @param p1 first vector
+     * @param p2 second vector
+     * @return the distance between p1 and p2 according to the L<sub>2</sub> norm
+     */
+    public static double distance(Cartesian1D p1, Cartesian1D p2) {
+        return p1.distance(p2);
+    }
+
+    /** Compute the distance between two points according to the L<sub>&infin;</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
+     * vector is built</p>
+     * @param p1 first vector
+     * @param p2 second vector
+     * @return the distance between p1 and p2 according to the L<sub>&infin;</sub> norm
+     */
+    public static double distanceInf(Cartesian1D p1, Cartesian1D p2) {
+        return p1.distanceInf(p2);
+    }
+
+    /** Compute the square of the distance between two points.
+     * <p>Calling this method is equivalent to calling:
+     * <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
+     * vector is built</p>
+     * @param p1 first vector
+     * @param p2 second vector
+     * @return the square of the distance between p1 and p2
+     */
+    public static double distanceSq(Cartesian1D p1, Cartesian1D p2) {
+        return p1.distanceSq(p2);
+    }
+
+    /**
+     * Test for the equality of two 1D vectors.
+     * <p>
+     * If all coordinates of two 1D vectors are exactly the same, and none are
+     * <code>Double.NaN</code>, the two 1D vectors are considered to be equal.
+     * </p>
+     * <p>
+     * <code>NaN</code> coordinates are considered to affect globally the vector
+     * and be equals to each other - i.e, if either (or all) coordinates of the
+     * 1D vector are equal to <code>Double.NaN</code>, the 1D vector is equal to
+     * {@link #NaN}.
+     * </p>
+     *
+     * @param other Object to test for equality to this
+     * @return true if two 1D vector objects are equal, false if
+     *         object is null, not an instance of Vector1D, or
+     *         not equal to this Vector1D instance
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof Cartesian1D) {
+            final Cartesian1D rhs = (Cartesian1D)other;
+            if (rhs.isNaN()) {
+                return this.isNaN();
+            }
+
+            return x == rhs.x;
+        }
+        return false;
+    }
+
+    /**
+     * Get a hashCode for the 1D vector.
+     * <p>
+     * All NaN values have the same hash code.</p>
+     *
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        if (isNaN()) {
+            return 7785;
+        }
+        return 997 * MathUtils.hash(x);
+    }
+
+    /** Get a string representation of this vector.
+     * @return a string representation of this vector
+     */
+    @Override
+    public String toString() {
+        return Vector1DFormat.getInstance().format(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString(final NumberFormat format) {
+        return new Vector1DFormat(format).format(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Coordinates1D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Coordinates1D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Coordinates1D.java
deleted file mode 100644
index 1f31594..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Coordinates1D.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math4.geometry.euclidean.oned;
-
-import java.text.NumberFormat;
-
-import org.apache.commons.math4.exception.MathArithmeticException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.MathUtils;
-
-/** This class represents a 1D point or a 1D vector.
- * <p>An instance of Coordinates1D represents the point with the corresponding
- * coordinates.</p>
- * <p>An instance of Coordinates1D also represents the vector which begins at
- * the origin and ends at the point corresponding to the coordinates.</p>
- * <p>Instances of this class are guaranteed to be immutable.</p>
- * @since 4.0
- */
-public class Coordinates1D implements Point<Euclidean1D>, Vector<Euclidean1D> {
-
-    /** Origin (coordinates: 0). */
-    public static final Coordinates1D ZERO = new Coordinates1D(0.0);
-
-    /** Unit (coordinates: 1). */
-    public static final Coordinates1D ONE  = new Coordinates1D(1.0);
-
-    // CHECKSTYLE: stop ConstantName
-    /** A vector with all coordinates set to NaN. */
-    public static final Coordinates1D NaN = new Coordinates1D(Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A vector with all coordinates set to positive infinity. */
-    public static final Coordinates1D POSITIVE_INFINITY =
-        new Coordinates1D(Double.POSITIVE_INFINITY);
-
-    /** A vector with all coordinates set to negative infinity. */
-    public static final Coordinates1D NEGATIVE_INFINITY =
-        new Coordinates1D(Double.NEGATIVE_INFINITY);
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 7556674948671647925L;
-
-    /** Abscissa. */
-    private final double x;
-
-    /** Simple constructor.
-     * Build a vector from its coordinates
-     * @param x abscissa
-     * @see #getX()
-     */
-    public Coordinates1D(double x) {
-        this.x = x;
-    }
-
-    /** Multiplicative constructor
-     * Build a vector from another one and a scale factor.
-     * The vector built will be a * u
-     * @param a scale factor
-     * @param u base (unscaled) vector
-     */
-    public Coordinates1D(double a, Coordinates1D u) {
-        this.x = a * u.x;
-    }
-
-    /** Linear constructor
-     * Build a vector from two other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     */
-    public Coordinates1D(double a1, Coordinates1D u1, double a2, Coordinates1D u2) {
-        this.x = a1 * u1.x + a2 * u2.x;
-    }
-
-    /** Linear constructor
-     * Build a vector from three other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     * @param a3 third scale factor
-     * @param u3 third base (unscaled) vector
-     */
-    public Coordinates1D(double a1, Coordinates1D u1, double a2, Coordinates1D u2,
-                   double a3, Coordinates1D u3) {
-        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
-    }
-
-    /** Linear constructor
-     * Build a vector from four other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     * @param a3 third scale factor
-     * @param u3 third base (unscaled) vector
-     * @param a4 fourth scale factor
-     * @param u4 fourth base (unscaled) vector
-     */
-    public Coordinates1D(double a1, Coordinates1D u1, double a2, Coordinates1D u2,
-                   double a3, Coordinates1D u3, double a4, Coordinates1D u4) {
-        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
-    }
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see #Vector1D(double)
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Space getSpace() {
-        return Euclidean1D.getInstance();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D getZero() {
-        return ZERO;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm1() {
-        return FastMath.abs(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm() {
-        return FastMath.abs(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormSq() {
-        return x * x;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormInf() {
-        return FastMath.abs(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D add(Vector<Euclidean1D> v) {
-        Coordinates1D v1 = (Coordinates1D) v;
-        return new Coordinates1D(x + v1.getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D add(double factor, Vector<Euclidean1D> v) {
-        Coordinates1D v1 = (Coordinates1D) v;
-        return new Coordinates1D(x + factor * v1.getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D subtract(Vector<Euclidean1D> p) {
-        Coordinates1D p3 = (Coordinates1D) p;
-        return new Coordinates1D(x - p3.x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D subtract(double factor, Vector<Euclidean1D> v) {
-        Coordinates1D v1 = (Coordinates1D) v;
-        return new Coordinates1D(x - factor * v1.getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D normalize() throws MathArithmeticException {
-        double s = getNorm();
-        if (s == 0) {
-            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
-        }
-        return scalarMultiply(1 / s);
-    }
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D negate() {
-        return new Coordinates1D(-x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates1D scalarMultiply(double a) {
-        return new Coordinates1D(a * x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isNaN() {
-        return Double.isNaN(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isInfinite() {
-        return !isNaN() && Double.isInfinite(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance1(Vector<Euclidean1D> p) {
-        Coordinates1D p3 = (Coordinates1D) p;
-        final double dx = FastMath.abs(p3.x - x);
-        return dx;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point<Euclidean1D> p) {
-        return distance((Coordinates1D) p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Vector<Euclidean1D> v) {
-        return distance((Coordinates1D) v);
-    }
-
-    /** Compute the distance between the instance and other coordinates.
-     * @param c other coordinates
-     * @return the distance between the instance and c
-     */
-    public double distance(Coordinates1D c) {
-        final double dx = c.x - x;
-        return FastMath.abs(dx);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceInf(Vector<Euclidean1D> p) {
-        Coordinates1D p3 = (Coordinates1D) p;
-        final double dx = FastMath.abs(p3.x - x);
-        return dx;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceSq(Vector<Euclidean1D> p) {
-        Coordinates1D p3 = (Coordinates1D) p;
-        final double dx = p3.x - x;
-        return dx * dx;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double dotProduct(final Vector<Euclidean1D> v) {
-        final Coordinates1D v1 = (Coordinates1D) v;
-        return x * v1.x;
-    }
-
-    /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>p1.subtract(p2).getNorm()</code> except that no intermediate
-     * vector is built</p>
-     * @param p1 first vector
-     * @param p2 second vector
-     * @return the distance between p1 and p2 according to the L<sub>2</sub> norm
-     */
-    public static double distance(Coordinates1D p1, Coordinates1D p2) {
-        return p1.distance(p2);
-    }
-
-    /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
-     * vector is built</p>
-     * @param p1 first vector
-     * @param p2 second vector
-     * @return the distance between p1 and p2 according to the L<sub>&infin;</sub> norm
-     */
-    public static double distanceInf(Coordinates1D p1, Coordinates1D p2) {
-        return p1.distanceInf(p2);
-    }
-
-    /** Compute the square of the distance between two vectors.
-     * <p>Calling this method is equivalent to calling:
-     * <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
-     * vector is built</p>
-     * @param p1 first vector
-     * @param p2 second vector
-     * @return the square of the distance between p1 and p2
-     */
-    public static double distanceSq(Coordinates1D p1, Coordinates1D p2) {
-        return p1.distanceSq(p2);
-    }
-
-    /**
-     * Test for the equality of two 1D vectors.
-     * <p>
-     * If all coordinates of two 1D vectors are exactly the same, and none are
-     * <code>Double.NaN</code>, the two 1D vectors are considered to be equal.
-     * </p>
-     * <p>
-     * <code>NaN</code> coordinates are considered to affect globally the vector
-     * and be equals to each other - i.e, if either (or all) coordinates of the
-     * 1D vector are equal to <code>Double.NaN</code>, the 1D vector is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if two 1D vector objects are equal, false if
-     *         object is null, not an instance of Vector1D, or
-     *         not equal to this Vector1D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Coordinates1D) {
-            final Coordinates1D rhs = (Coordinates1D)other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return x == rhs.x;
-        }
-        return false;
-    }
-
-    /**
-     * Get a hashCode for the 1D vector.
-     * <p>
-     * All NaN values have the same hash code.</p>
-     *
-     * @return a hash code value for this object
-     */
-    @Override
-    public int hashCode() {
-        if (isNaN()) {
-            return 7785;
-        }
-        return 997 * MathUtils.hash(x);
-    }
-
-    /** Get a string representation of this vector.
-     * @return a string representation of this vector
-     */
-    @Override
-    public String toString() {
-        return Vector1DFormat.getInstance().format(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString(final NumberFormat format) {
-        return new Vector1DFormat(format).format(this);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
index 78c50c1..acab5a6 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
@@ -112,14 +112,14 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
             }
             // the tree must be open on the negative infinity side
             final SubHyperplane<Euclidean1D> upperCut =
-                new OrientedPoint(new Coordinates1D(upper), true, tolerance).wholeHyperplane();
+                new OrientedPoint(new Cartesian1D(upper), true, tolerance).wholeHyperplane();
             return new BSPTree<>(upperCut,
                                new BSPTree<Euclidean1D>(Boolean.FALSE),
                                new BSPTree<Euclidean1D>(Boolean.TRUE),
                                null);
         }
         final SubHyperplane<Euclidean1D> lowerCut =
-            new OrientedPoint(new Coordinates1D(lower), false, tolerance).wholeHyperplane();
+            new OrientedPoint(new Cartesian1D(lower), false, tolerance).wholeHyperplane();
         if (Double.isInfinite(upper) && (upper > 0)) {
             // the tree must be open on the positive infinity side
             return new BSPTree<>(lowerCut,
@@ -130,7 +130,7 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
 
         // the tree must be bounded on the two sides
         final SubHyperplane<Euclidean1D> upperCut =
-            new OrientedPoint(new Coordinates1D(upper), true, tolerance).wholeHyperplane();
+            new OrientedPoint(new Cartesian1D(upper), true, tolerance).wholeHyperplane();
         return new BSPTree<>(lowerCut,
                                         new BSPTree<Euclidean1D>(Boolean.FALSE),
                                         new BSPTree<>(upperCut,
@@ -151,7 +151,7 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
     @Override
     protected void computeGeometricalProperties() {
         if (getTree(false).getCut() == null) {
-            setBarycenter((Point<Euclidean1D>) Coordinates1D.NaN);
+            setBarycenter((Point<Euclidean1D>) Cartesian1D.NaN);
             setSize(((Boolean) getTree(false).getAttribute()) ? Double.POSITIVE_INFINITY : 0);
         } else {
             double size = 0.0;
@@ -162,9 +162,9 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
             }
             setSize(size);
             if (Double.isInfinite(size)) {
-                setBarycenter((Point<Euclidean1D>) Coordinates1D.NaN);
+                setBarycenter((Point<Euclidean1D>) Cartesian1D.NaN);
             } else if (size >= Precision.SAFE_MIN) {
-                setBarycenter((Point<Euclidean1D>) new Coordinates1D(sum / size));
+                setBarycenter((Point<Euclidean1D>) new Cartesian1D(sum / size));
             } else {
                 setBarycenter((Point<Euclidean1D>) ((OrientedPoint) getTree(false).getCut().getHyperplane()).getLocation());
             }
@@ -212,7 +212,7 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
     public BoundaryProjection<Euclidean1D> projectToBoundary(final Point<Euclidean1D> point) {
 
         // get position of test point
-        final double x = ((Coordinates1D) point).getX();
+        final double x = ((Cartesian1D) point).getX();
 
         double previous = Double.NEGATIVE_INFINITY;
         for (final double[] a : this) {
@@ -249,8 +249,8 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> imple
      * @param x abscissa of the point
      * @return a new point for finite abscissa, null otherwise
      */
-    private Coordinates1D finiteOrNullPoint(final double x) {
-        return Double.isInfinite(x) ? null : new Coordinates1D(x);
+    private Cartesian1D finiteOrNullPoint(final double x) {
+        return Double.isInfinite(x) ? null : new Cartesian1D(x);
     }
 
     /** Build an ordered list of intervals representing the instance.

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java
index 2f719a2..f917bcc 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java
@@ -29,7 +29,7 @@ import org.apache.commons.math4.geometry.partitioning.Hyperplane;
 public class OrientedPoint implements Hyperplane<Euclidean1D> {
 
     /** Vector location. */
-    private final Coordinates1D location;
+    private final Cartesian1D location;
 
     /** Orientation. */
     private boolean direct;
@@ -44,7 +44,7 @@ public class OrientedPoint implements Hyperplane<Euclidean1D> {
      * @param tolerance tolerance below which points are considered to belong to the hyperplane
      * @since 3.3
      */
-    public OrientedPoint(final Coordinates1D location, final boolean direct, final double tolerance) {
+    public OrientedPoint(final Cartesian1D location, final boolean direct, final double tolerance) {
         this.location  = location;
         this.direct    = direct;
         this.tolerance = tolerance;
@@ -71,7 +71,7 @@ public class OrientedPoint implements Hyperplane<Euclidean1D> {
     /** {@inheritDoc} */
     @Override
     public double getOffset(final Point<Euclidean1D> point) {
-        final double delta = ((Coordinates1D) point).getX() - location.getX();
+        final double delta = ((Cartesian1D) point).getX() - location.getX();
         return direct ? delta : -delta;
     }
 
@@ -125,7 +125,7 @@ public class OrientedPoint implements Hyperplane<Euclidean1D> {
     /** Get the hyperplane location on the real line.
      * @return the hyperplane location
      */
-    public Coordinates1D getLocation() {
+    public Cartesian1D getLocation() {
         return location;
     }
 

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java
index 4b40bb3..c5cead3 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java
@@ -105,31 +105,31 @@ public class Vector1DFormat extends VectorFormat<Euclidean1D> {
     @Override
     public StringBuffer format(final Vector<Euclidean1D> vector, final StringBuffer toAppendTo,
                                final FieldPosition pos) {
-        final Coordinates1D p1 = (Coordinates1D) vector;
+        final Cartesian1D p1 = (Cartesian1D) vector;
         return format(toAppendTo, pos, p1.getX());
     }
 
     /** {@inheritDoc} */
     @Override
-    public Coordinates1D parse(final String source) throws MathParseException {
+    public Cartesian1D parse(final String source) throws MathParseException {
         ParsePosition parsePosition = new ParsePosition(0);
-        Coordinates1D result = parse(source, parsePosition);
+        Cartesian1D result = parse(source, parsePosition);
         if (parsePosition.getIndex() == 0) {
             throw new MathParseException(source,
                                          parsePosition.getErrorIndex(),
-                                         Coordinates1D.class);
+                                         Cartesian1D.class);
         }
         return result;
     }
 
     /** {@inheritDoc} */
     @Override
-    public Coordinates1D parse(final String source, final ParsePosition pos) {
+    public Cartesian1D parse(final String source, final ParsePosition pos) {
         final double[] coordinates = parseCoordinates(1, source, pos);
         if (coordinates == null) {
             return null;
         }
-        return new Coordinates1D(coordinates[0]);
+        return new Cartesian1D(coordinates[0]);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Cartesian3D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Cartesian3D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Cartesian3D.java
new file mode 100644
index 0000000..85696f6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Cartesian3D.java
@@ -0,0 +1,621 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math4.geometry.euclidean.threed;
+
+import java.io.Serializable;
+import java.text.NumberFormat;
+
+import org.apache.commons.math4.exception.DimensionMismatchException;
+import org.apache.commons.math4.exception.MathArithmeticException;
+import org.apache.commons.math4.exception.util.LocalizedFormats;
+import org.apache.commons.math4.geometry.Point;
+import org.apache.commons.math4.geometry.Space;
+import org.apache.commons.math4.geometry.Vector;
+import org.apache.commons.math4.util.FastMath;
+import org.apache.commons.math4.util.MathArrays;
+import org.apache.commons.math4.util.MathUtils;
+
+/**
+ * This class represents points or vectors in a three-dimensional space.
+ * <p>An instance of Cartesian3D represents the point with the corresponding
+ * coordinates.</p>
+ * <p>An instance of Cartesian3D also represents the vector which begins at
+ * the origin and ends at the point corresponding to the coordinates.</p>
+ * <p>Instance of this class are guaranteed to be immutable.</p>
+ * @since 4.0
+ */
+public class Cartesian3D implements Serializable, Point<Euclidean3D>, Vector<Euclidean3D> {
+
+    /** Null vector (coordinates: 0, 0, 0). */
+    public static final Cartesian3D ZERO   = new Cartesian3D(0, 0, 0);
+
+    /** First canonical vector (coordinates: 1, 0, 0). */
+    public static final Cartesian3D PLUS_I = new Cartesian3D(1, 0, 0);
+
+    /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */
+    public static final Cartesian3D MINUS_I = new Cartesian3D(-1, 0, 0);
+
+    /** Second canonical vector (coordinates: 0, 1, 0). */
+    public static final Cartesian3D PLUS_J = new Cartesian3D(0, 1, 0);
+
+    /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */
+    public static final Cartesian3D MINUS_J = new Cartesian3D(0, -1, 0);
+
+    /** Third canonical vector (coordinates: 0, 0, 1). */
+    public static final Cartesian3D PLUS_K = new Cartesian3D(0, 0, 1);
+
+    /** Opposite of the third canonical vector (coordinates: 0, 0, -1).  */
+    public static final Cartesian3D MINUS_K = new Cartesian3D(0, 0, -1);
+
+    // CHECKSTYLE: stop ConstantName
+    /** A vector with all coordinates set to NaN. */
+    public static final Cartesian3D NaN = new Cartesian3D(Double.NaN, Double.NaN, Double.NaN);
+    // CHECKSTYLE: resume ConstantName
+
+    /** A vector with all coordinates set to positive infinity. */
+    public static final Cartesian3D POSITIVE_INFINITY =
+        new Cartesian3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+
+    /** A vector with all coordinates set to negative infinity. */
+    public static final Cartesian3D NEGATIVE_INFINITY =
+        new Cartesian3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1313493323784566947L;
+
+    /** Abscissa. */
+    private final double x;
+
+    /** Ordinate. */
+    private final double y;
+
+    /** Height. */
+    private final double z;
+
+    /** Simple constructor.
+     * Build a vector from its coordinates
+     * @param x abscissa
+     * @param y ordinate
+     * @param z height
+     * @see #getX()
+     * @see #getY()
+     * @see #getZ()
+     */
+    public Cartesian3D(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** Simple constructor.
+     * Build a vector from its coordinates
+     * @param v coordinates array
+     * @exception DimensionMismatchException if array does not have 3 elements
+     * @see #toArray()
+     */
+    public Cartesian3D(double[] v) throws DimensionMismatchException {
+        if (v.length != 3) {
+            throw new DimensionMismatchException(v.length, 3);
+        }
+        this.x = v[0];
+        this.y = v[1];
+        this.z = v[2];
+    }
+
+    /** Simple constructor.
+     * Build 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()
+     */
+    public Cartesian3D(double alpha, double delta) {
+        double cosDelta = FastMath.cos(delta);
+        this.x = FastMath.cos(alpha) * cosDelta;
+        this.y = FastMath.sin(alpha) * cosDelta;
+        this.z = FastMath.sin(delta);
+    }
+
+    /** Multiplicative constructor
+     * Build a vector from another one and a scale factor.
+     * The vector built will be a * u
+     * @param a scale factor
+     * @param u base (unscaled) vector
+     */
+    public Cartesian3D(double a, Cartesian3D u) {
+        this.x = a * u.x;
+        this.y = a * u.y;
+        this.z = a * u.z;
+    }
+
+    /** Linear constructor
+     * Build a vector from two other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     */
+    public Cartesian3D(double a1, Cartesian3D u1, double a2, Cartesian3D u2) {
+        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x);
+        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y);
+        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z);
+    }
+
+    /** Linear constructor
+     * Build a vector from three other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     */
+    public Cartesian3D(double a1, Cartesian3D u1, double a2, Cartesian3D u2,
+                    double a3, Cartesian3D u3) {
+        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x, a3, u3.x);
+        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y, a3, u3.y);
+        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z, a3, u3.z);
+    }
+
+    /** Linear constructor
+     * Build a vector from four other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     * @param a4 fourth scale factor
+     * @param u4 fourth base (unscaled) vector
+     */
+    public Cartesian3D(double a1, Cartesian3D u1, double a2, Cartesian3D u2,
+                    double a3, Cartesian3D u3, double a4, Cartesian3D u4) {
+        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x, a3, u3.x, a4, u4.x);
+        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y, a3, u3.y, a4, u4.y);
+        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z, a3, u3.z, a4, u4.z);
+    }
+
+    /** Get the abscissa of the vector.
+     * @return abscissa of the vector
+     * @see #Vector3D(double, double, double)
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** Get the ordinate of the vector.
+     * @return ordinate of the vector
+     * @see #Vector3D(double, double, double)
+     */
+    public double getY() {
+        return y;
+    }
+
+    /** Get the height of the vector.
+     * @return height of the vector
+     * @see #Vector3D(double, double, double)
+     */
+    public double getZ() {
+        return z;
+    }
+
+    /** Get the vector coordinates as a dimension 3 array.
+     * @return vector coordinates
+     * @see #Vector3D(double[])
+     */
+    public double[] toArray() {
+        return new double[] { x, y, z };
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Space getSpace() {
+        return Euclidean3D.getInstance();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D getZero() {
+        return ZERO;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm1() {
+        return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm() {
+        // there are no cancellation problems here, so we use the straightforward formula
+        return FastMath.sqrt (x * x + y * y + z * z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNormSq() {
+        // there are no cancellation problems here, so we use the straightforward formula
+        return x * x + y * y + z * z;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNormInf() {
+        return FastMath.max(FastMath.max(FastMath.abs(x), FastMath.abs(y)), FastMath.abs(z));
+    }
+
+    /** Get the azimuth of the vector.
+     * @return azimuth (&alpha;) of the vector, between -&pi; and +&pi;
+     * @see #Vector3D(double, double)
+     */
+    public double getAlpha() {
+        return FastMath.atan2(y, x);
+    }
+
+    /** Get the elevation of the vector.
+     * @return elevation (&delta;) of the vector, between -&pi;/2 and +&pi;/2
+     * @see #Vector3D(double, double)
+     */
+    public double getDelta() {
+        return FastMath.asin(z / getNorm());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D add(final Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        return new Cartesian3D(x + v3.x, y + v3.y, z + v3.z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D add(double factor, final Vector<Euclidean3D> v) {
+        return new Cartesian3D(1, this, factor, (Cartesian3D) v);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D subtract(final Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        return new Cartesian3D(x - v3.x, y - v3.y, z - v3.z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D subtract(final double factor, final Vector<Euclidean3D> v) {
+        return new Cartesian3D(1, this, -factor, (Cartesian3D) v);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D normalize() throws MathArithmeticException {
+        double s = getNorm();
+        if (s == 0) {
+            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+        }
+        return scalarMultiply(1 / s);
+    }
+
+    /** Get a vector orthogonal to the instance.
+     * <p>There are an infinite number of normalized vectors orthogonal
+     * to the instance. This method picks up one of them almost
+     * arbitrarily. It is useful when one needs to compute a reference
+     * frame with one of the axes in a predefined direction. The
+     * following example shows how to build a frame having the k axis
+     * aligned with the known vector u :
+     * <pre><code>
+     *   Vector3D k = u.normalize();
+     *   Vector3D i = k.orthogonal();
+     *   Vector3D j = Vector3D.crossProduct(k, i);
+     * </code></pre></p>
+     * @return a new normalized vector orthogonal to the instance
+     * @exception MathArithmeticException if the norm of the instance is null
+     */
+    public Cartesian3D orthogonal() throws MathArithmeticException {
+
+        double threshold = 0.6 * getNorm();
+        if (threshold == 0) {
+            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+
+        if (FastMath.abs(x) <= threshold) {
+            double inverse  = 1 / FastMath.sqrt(y * y + z * z);
+            return new Cartesian3D(0, inverse * z, -inverse * y);
+        } else if (FastMath.abs(y) <= threshold) {
+            double inverse  = 1 / FastMath.sqrt(x * x + z * z);
+            return new Cartesian3D(-inverse * z, 0, inverse * x);
+        }
+        double inverse  = 1 / FastMath.sqrt(x * x + y * y);
+        return new Cartesian3D(inverse * y, -inverse * x, 0);
+
+    }
+
+    /** Compute the angular separation between two vectors.
+     * <p>This method computes the angular separation between two
+     * vectors using the dot product for well separated vectors and the
+     * cross product for almost aligned vectors. This allows to have a
+     * good accuracy in all cases, even for vectors very close to each
+     * other.</p>
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return angular separation between v1 and v2
+     * @exception MathArithmeticException if either vector has a null norm
+     */
+    public static double angle(Cartesian3D v1, Cartesian3D v2) throws MathArithmeticException {
+
+        double normProduct = v1.getNorm() * v2.getNorm();
+        if (normProduct == 0) {
+            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+
+        double dot = v1.dotProduct(v2);
+        double threshold = normProduct * 0.9999;
+        if ((dot < -threshold) || (dot > threshold)) {
+            // the vectors are almost aligned, compute using the sine
+            Cartesian3D v3 = crossProduct(v1, v2);
+            if (dot >= 0) {
+                return FastMath.asin(v3.getNorm() / normProduct);
+            }
+            return FastMath.PI - FastMath.asin(v3.getNorm() / normProduct);
+        }
+
+        // the vectors are sufficiently separated to use the cosine
+        return FastMath.acos(dot / normProduct);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D negate() {
+        return new Cartesian3D(-x, -y, -z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cartesian3D scalarMultiply(double a) {
+        return new Cartesian3D(a * x, a * y, a * z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isNaN() {
+        return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isInfinite() {
+        return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z));
+    }
+
+    /**
+     * Test for the equality of two 3D vectors.
+     * <p>
+     * If all coordinates of two 3D vectors are exactly the same, and none are
+     * <code>Double.NaN</code>, the two 3D vectors are considered to be equal.
+     * </p>
+     * <p>
+     * <code>NaN</code> coordinates are considered to affect globally the vector
+     * and be equals to each other - i.e, if either (or all) coordinates of the
+     * 3D vector are equal to <code>Double.NaN</code>, the 3D vector is equal to
+     * {@link #NaN}.
+     * </p>
+     *
+     * @param other Object to test for equality to this
+     * @return true if two 3D vector objects are equal, false if
+     *         object is null, not an instance of Vector3D, or
+     *         not equal to this Vector3D instance
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof Cartesian3D) {
+            final Cartesian3D rhs = (Cartesian3D)other;
+            if (rhs.isNaN()) {
+                return this.isNaN();
+            }
+
+            return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
+        }
+        return false;
+    }
+
+    /**
+     * Get a hashCode for the 3D vector.
+     * <p>
+     * All NaN values have the same hash code.</p>
+     *
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        if (isNaN()) {
+            return 642;
+        }
+        return 643 * (164 * MathUtils.hash(x) +  3 * MathUtils.hash(y) +  MathUtils.hash(z));
+    }
+
+    /** {@inheritDoc}
+     * <p>
+     * The implementation uses specific multiplication and addition
+     * algorithms to preserve accuracy and reduce cancellation effects.
+     * It should be very accurate even for nearly orthogonal vectors.
+     * </p>
+     * @see MathArrays#linearCombination(double, double, double, double, double, double)
+     */
+    @Override
+    public double dotProduct(final Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        return MathArrays.linearCombination(x, v3.x, y, v3.y, z, v3.z);
+    }
+
+    /** Compute the cross-product of the instance with another vector.
+     * @param v other vector
+     * @return the cross product this ^ v as a new Vector3D
+     */
+    public Cartesian3D crossProduct(final Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        return new Cartesian3D(MathArrays.linearCombination(y, v3.z, -z, v3.y),
+                            MathArrays.linearCombination(z, v3.x, -x, v3.z),
+                            MathArrays.linearCombination(x, v3.y, -y, v3.x));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance1(Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        final double dx = FastMath.abs(v3.x - x);
+        final double dy = FastMath.abs(v3.y - y);
+        final double dz = FastMath.abs(v3.z - z);
+        return dx + dy + dz;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance(Point<Euclidean3D> p) {
+        return distance((Cartesian3D) p);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distance(Vector<Euclidean3D> v) {
+        return distance((Cartesian3D) v);
+    }
+
+    /** Compute the distance between the instance and other coordinates.
+     * @param c other coordinates
+     * @return the distance between the instance and c
+     */
+    public double distance(Cartesian3D c) {
+        final double dx = c.x - x;
+        final double dy = c.y - y;
+        final double dz = c.z - z;
+        return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distanceInf(Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        final double dx = FastMath.abs(v3.x - x);
+        final double dy = FastMath.abs(v3.y - y);
+        final double dz = FastMath.abs(v3.z - z);
+        return FastMath.max(FastMath.max(dx, dy), dz);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double distanceSq(Vector<Euclidean3D> v) {
+        final Cartesian3D v3 = (Cartesian3D) v;
+        final double dx = v3.x - x;
+        final double dy = v3.y - y;
+        final double dz = v3.z - z;
+        return dx * dx + dy * dy + dz * dz;
+    }
+
+    /** Compute the dot-product of two vectors.
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the dot product v1.v2
+     */
+    public static double dotProduct(Cartesian3D v1, Cartesian3D v2) {
+        return v1.dotProduct(v2);
+    }
+
+    /** Compute the cross-product of two vectors.
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the cross product v1 ^ v2 as a new Vector
+     */
+    public static Cartesian3D crossProduct(final Cartesian3D v1, final Cartesian3D v2) {
+        return v1.crossProduct(v2);
+    }
+
+    /** Compute the distance between two vectors according to the L<sub>1</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>v1.subtract(v2).getNorm1()</code> except that no intermediate
+     * vector is built</p>
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the distance between v1 and v2 according to the L<sub>1</sub> norm
+     */
+    public static double distance1(Cartesian3D v1, Cartesian3D v2) {
+        return v1.distance1(v2);
+    }
+
+    /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>v1.subtract(v2).getNorm()</code> except that no intermediate
+     * vector is built</p>
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
+     */
+    public static double distance(Cartesian3D v1, Cartesian3D v2) {
+        return v1.distance(v2);
+    }
+
+    /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>v1.subtract(v2).getNormInf()</code> except that no intermediate
+     * vector is built</p>
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the distance between v1 and v2 according to the L<sub>&infin;</sub> norm
+     */
+    public static double distanceInf(Cartesian3D v1, Cartesian3D v2) {
+        return v1.distanceInf(v2);
+    }
+
+    /** Compute the square of the distance between two vectors.
+     * <p>Calling this method is equivalent to calling:
+     * <code>v1.subtract(v2).getNormSq()</code> except that no intermediate
+     * vector is built</p>
+     * @param v1 first vector
+     * @param v2 second vector
+     * @return the square of the distance between v1 and v2
+     */
+    public static double distanceSq(Cartesian3D v1, Cartesian3D v2) {
+        return v1.distanceSq(v2);
+    }
+
+    /** Get a string representation of this vector.
+     * @return a string representation of this vector
+     */
+    @Override
+    public String toString() {
+        return Vector3DFormat.getInstance().format(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString(final NumberFormat format) {
+        return new Vector3DFormat(format).format(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/e21d4d43/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Coordinates3D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Coordinates3D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Coordinates3D.java
deleted file mode 100644
index ee2376c..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Coordinates3D.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.math4.geometry.euclidean.threed;
-
-import java.io.Serializable;
-import java.text.NumberFormat;
-
-import org.apache.commons.math4.exception.DimensionMismatchException;
-import org.apache.commons.math4.exception.MathArithmeticException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.MathArrays;
-import org.apache.commons.math4.util.MathUtils;
-
-/**
- * This class represents points or vectors in a three-dimensional space.
- * <p>An instance of Coordinates3D represents the point with the corresponding
- * coordinates.</p>
- * <p>An instance of Coordinates3D also represents the vector which begins at
- * the origin and ends at the point corresponding to the coordinates.</p>
- * <p>Instance of this class are guaranteed to be immutable.</p>
- * @since 4.0
- */
-public class Coordinates3D implements Serializable, Point<Euclidean3D>, Vector<Euclidean3D> {
-
-    /** Null vector (coordinates: 0, 0, 0). */
-    public static final Coordinates3D ZERO   = new Coordinates3D(0, 0, 0);
-
-    /** First canonical vector (coordinates: 1, 0, 0). */
-    public static final Coordinates3D PLUS_I = new Coordinates3D(1, 0, 0);
-
-    /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */
-    public static final Coordinates3D MINUS_I = new Coordinates3D(-1, 0, 0);
-
-    /** Second canonical vector (coordinates: 0, 1, 0). */
-    public static final Coordinates3D PLUS_J = new Coordinates3D(0, 1, 0);
-
-    /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */
-    public static final Coordinates3D MINUS_J = new Coordinates3D(0, -1, 0);
-
-    /** Third canonical vector (coordinates: 0, 0, 1). */
-    public static final Coordinates3D PLUS_K = new Coordinates3D(0, 0, 1);
-
-    /** Opposite of the third canonical vector (coordinates: 0, 0, -1).  */
-    public static final Coordinates3D MINUS_K = new Coordinates3D(0, 0, -1);
-
-    // CHECKSTYLE: stop ConstantName
-    /** A vector with all coordinates set to NaN. */
-    public static final Coordinates3D NaN = new Coordinates3D(Double.NaN, Double.NaN, Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A vector with all coordinates set to positive infinity. */
-    public static final Coordinates3D POSITIVE_INFINITY =
-        new Coordinates3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-
-    /** A vector with all coordinates set to negative infinity. */
-    public static final Coordinates3D NEGATIVE_INFINITY =
-        new Coordinates3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-
-    /** Serializable version identifier. */
-    private static final long serialVersionUID = 1313493323784566947L;
-
-    /** Abscissa. */
-    private final double x;
-
-    /** Ordinate. */
-    private final double y;
-
-    /** Height. */
-    private final double z;
-
-    /** Simple constructor.
-     * Build a vector from its coordinates
-     * @param x abscissa
-     * @param y ordinate
-     * @param z height
-     * @see #getX()
-     * @see #getY()
-     * @see #getZ()
-     */
-    public Coordinates3D(double x, double y, double z) {
-        this.x = x;
-        this.y = y;
-        this.z = z;
-    }
-
-    /** Simple constructor.
-     * Build a vector from its coordinates
-     * @param v coordinates array
-     * @exception DimensionMismatchException if array does not have 3 elements
-     * @see #toArray()
-     */
-    public Coordinates3D(double[] v) throws DimensionMismatchException {
-        if (v.length != 3) {
-            throw new DimensionMismatchException(v.length, 3);
-        }
-        this.x = v[0];
-        this.y = v[1];
-        this.z = v[2];
-    }
-
-    /** Simple constructor.
-     * Build 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()
-     */
-    public Coordinates3D(double alpha, double delta) {
-        double cosDelta = FastMath.cos(delta);
-        this.x = FastMath.cos(alpha) * cosDelta;
-        this.y = FastMath.sin(alpha) * cosDelta;
-        this.z = FastMath.sin(delta);
-    }
-
-    /** Multiplicative constructor
-     * Build a vector from another one and a scale factor.
-     * The vector built will be a * u
-     * @param a scale factor
-     * @param u base (unscaled) vector
-     */
-    public Coordinates3D(double a, Coordinates3D u) {
-        this.x = a * u.x;
-        this.y = a * u.y;
-        this.z = a * u.z;
-    }
-
-    /** Linear constructor
-     * Build a vector from two other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     */
-    public Coordinates3D(double a1, Coordinates3D u1, double a2, Coordinates3D u2) {
-        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x);
-        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y);
-        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z);
-    }
-
-    /** Linear constructor
-     * Build a vector from three other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     * @param a3 third scale factor
-     * @param u3 third base (unscaled) vector
-     */
-    public Coordinates3D(double a1, Coordinates3D u1, double a2, Coordinates3D u2,
-                    double a3, Coordinates3D u3) {
-        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x, a3, u3.x);
-        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y, a3, u3.y);
-        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z, a3, u3.z);
-    }
-
-    /** Linear constructor
-     * Build a vector from four other ones and corresponding scale factors.
-     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
-     * @param a1 first scale factor
-     * @param u1 first base (unscaled) vector
-     * @param a2 second scale factor
-     * @param u2 second base (unscaled) vector
-     * @param a3 third scale factor
-     * @param u3 third base (unscaled) vector
-     * @param a4 fourth scale factor
-     * @param u4 fourth base (unscaled) vector
-     */
-    public Coordinates3D(double a1, Coordinates3D u1, double a2, Coordinates3D u2,
-                    double a3, Coordinates3D u3, double a4, Coordinates3D u4) {
-        this.x = MathArrays.linearCombination(a1, u1.x, a2, u2.x, a3, u3.x, a4, u4.x);
-        this.y = MathArrays.linearCombination(a1, u1.y, a2, u2.y, a3, u3.y, a4, u4.y);
-        this.z = MathArrays.linearCombination(a1, u1.z, a2, u2.z, a3, u3.z, a4, u4.z);
-    }
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see #Vector3D(double, double, double)
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** Get the ordinate of the vector.
-     * @return ordinate of the vector
-     * @see #Vector3D(double, double, double)
-     */
-    public double getY() {
-        return y;
-    }
-
-    /** Get the height of the vector.
-     * @return height of the vector
-     * @see #Vector3D(double, double, double)
-     */
-    public double getZ() {
-        return z;
-    }
-
-    /** Get the vector coordinates as a dimension 3 array.
-     * @return vector coordinates
-     * @see #Vector3D(double[])
-     */
-    public double[] toArray() {
-        return new double[] { x, y, z };
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Space getSpace() {
-        return Euclidean3D.getInstance();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D getZero() {
-        return ZERO;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm1() {
-        return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm() {
-        // there are no cancellation problems here, so we use the straightforward formula
-        return FastMath.sqrt (x * x + y * y + z * z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormSq() {
-        // there are no cancellation problems here, so we use the straightforward formula
-        return x * x + y * y + z * z;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormInf() {
-        return FastMath.max(FastMath.max(FastMath.abs(x), FastMath.abs(y)), FastMath.abs(z));
-    }
-
-    /** Get the azimuth of the vector.
-     * @return azimuth (&alpha;) of the vector, between -&pi; and +&pi;
-     * @see #Vector3D(double, double)
-     */
-    public double getAlpha() {
-        return FastMath.atan2(y, x);
-    }
-
-    /** Get the elevation of the vector.
-     * @return elevation (&delta;) of the vector, between -&pi;/2 and +&pi;/2
-     * @see #Vector3D(double, double)
-     */
-    public double getDelta() {
-        return FastMath.asin(z / getNorm());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D add(final Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        return new Coordinates3D(x + v3.x, y + v3.y, z + v3.z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D add(double factor, final Vector<Euclidean3D> v) {
-        return new Coordinates3D(1, this, factor, (Coordinates3D) v);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D subtract(final Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        return new Coordinates3D(x - v3.x, y - v3.y, z - v3.z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D subtract(final double factor, final Vector<Euclidean3D> v) {
-        return new Coordinates3D(1, this, -factor, (Coordinates3D) v);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D normalize() throws MathArithmeticException {
-        double s = getNorm();
-        if (s == 0) {
-            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
-        }
-        return scalarMultiply(1 / s);
-    }
-
-    /** Get a vector orthogonal to the instance.
-     * <p>There are an infinite number of normalized vectors orthogonal
-     * to the instance. This method picks up one of them almost
-     * arbitrarily. It is useful when one needs to compute a reference
-     * frame with one of the axes in a predefined direction. The
-     * following example shows how to build a frame having the k axis
-     * aligned with the known vector u :
-     * <pre><code>
-     *   Vector3D k = u.normalize();
-     *   Vector3D i = k.orthogonal();
-     *   Vector3D j = Vector3D.crossProduct(k, i);
-     * </code></pre></p>
-     * @return a new normalized vector orthogonal to the instance
-     * @exception MathArithmeticException if the norm of the instance is null
-     */
-    public Coordinates3D orthogonal() throws MathArithmeticException {
-
-        double threshold = 0.6 * getNorm();
-        if (threshold == 0) {
-            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
-        }
-
-        if (FastMath.abs(x) <= threshold) {
-            double inverse  = 1 / FastMath.sqrt(y * y + z * z);
-            return new Coordinates3D(0, inverse * z, -inverse * y);
-        } else if (FastMath.abs(y) <= threshold) {
-            double inverse  = 1 / FastMath.sqrt(x * x + z * z);
-            return new Coordinates3D(-inverse * z, 0, inverse * x);
-        }
-        double inverse  = 1 / FastMath.sqrt(x * x + y * y);
-        return new Coordinates3D(inverse * y, -inverse * x, 0);
-
-    }
-
-    /** Compute the angular separation between two vectors.
-     * <p>This method computes the angular separation between two
-     * vectors using the dot product for well separated vectors and the
-     * cross product for almost aligned vectors. This allows to have a
-     * good accuracy in all cases, even for vectors very close to each
-     * other.</p>
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return angular separation between v1 and v2
-     * @exception MathArithmeticException if either vector has a null norm
-     */
-    public static double angle(Coordinates3D v1, Coordinates3D v2) throws MathArithmeticException {
-
-        double normProduct = v1.getNorm() * v2.getNorm();
-        if (normProduct == 0) {
-            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
-        }
-
-        double dot = v1.dotProduct(v2);
-        double threshold = normProduct * 0.9999;
-        if ((dot < -threshold) || (dot > threshold)) {
-            // the vectors are almost aligned, compute using the sine
-            Coordinates3D v3 = crossProduct(v1, v2);
-            if (dot >= 0) {
-                return FastMath.asin(v3.getNorm() / normProduct);
-            }
-            return FastMath.PI - FastMath.asin(v3.getNorm() / normProduct);
-        }
-
-        // the vectors are sufficiently separated to use the cosine
-        return FastMath.acos(dot / normProduct);
-
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D negate() {
-        return new Coordinates3D(-x, -y, -z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Coordinates3D scalarMultiply(double a) {
-        return new Coordinates3D(a * x, a * y, a * z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isNaN() {
-        return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isInfinite() {
-        return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z));
-    }
-
-    /**
-     * Test for the equality of two 3D vectors.
-     * <p>
-     * If all coordinates of two 3D vectors are exactly the same, and none are
-     * <code>Double.NaN</code>, the two 3D vectors are considered to be equal.
-     * </p>
-     * <p>
-     * <code>NaN</code> coordinates are considered to affect globally the vector
-     * and be equals to each other - i.e, if either (or all) coordinates of the
-     * 3D vector are equal to <code>Double.NaN</code>, the 3D vector is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if two 3D vector objects are equal, false if
-     *         object is null, not an instance of Vector3D, or
-     *         not equal to this Vector3D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Coordinates3D) {
-            final Coordinates3D rhs = (Coordinates3D)other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
-        }
-        return false;
-    }
-
-    /**
-     * Get a hashCode for the 3D vector.
-     * <p>
-     * All NaN values have the same hash code.</p>
-     *
-     * @return a hash code value for this object
-     */
-    @Override
-    public int hashCode() {
-        if (isNaN()) {
-            return 642;
-        }
-        return 643 * (164 * MathUtils.hash(x) +  3 * MathUtils.hash(y) +  MathUtils.hash(z));
-    }
-
-    /** {@inheritDoc}
-     * <p>
-     * The implementation uses specific multiplication and addition
-     * algorithms to preserve accuracy and reduce cancellation effects.
-     * It should be very accurate even for nearly orthogonal vectors.
-     * </p>
-     * @see MathArrays#linearCombination(double, double, double, double, double, double)
-     */
-    @Override
-    public double dotProduct(final Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        return MathArrays.linearCombination(x, v3.x, y, v3.y, z, v3.z);
-    }
-
-    /** Compute the cross-product of the instance with another vector.
-     * @param v other vector
-     * @return the cross product this ^ v as a new Vector3D
-     */
-    public Coordinates3D crossProduct(final Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        return new Coordinates3D(MathArrays.linearCombination(y, v3.z, -z, v3.y),
-                            MathArrays.linearCombination(z, v3.x, -x, v3.z),
-                            MathArrays.linearCombination(x, v3.y, -y, v3.x));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance1(Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        final double dx = FastMath.abs(v3.x - x);
-        final double dy = FastMath.abs(v3.y - y);
-        final double dz = FastMath.abs(v3.z - z);
-        return dx + dy + dz;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point<Euclidean3D> p) {
-        return distance((Coordinates3D) p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Vector<Euclidean3D> v) {
-        return distance((Coordinates3D) v);
-    }
-
-    /** Compute the distance between the instance and other coordinates.
-     * @param c other coordinates
-     * @return the distance between the instance and c
-     */
-    public double distance(Coordinates3D c) {
-        final double dx = c.x - x;
-        final double dy = c.y - y;
-        final double dz = c.z - z;
-        return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceInf(Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        final double dx = FastMath.abs(v3.x - x);
-        final double dy = FastMath.abs(v3.y - y);
-        final double dz = FastMath.abs(v3.z - z);
-        return FastMath.max(FastMath.max(dx, dy), dz);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceSq(Vector<Euclidean3D> v) {
-        final Coordinates3D v3 = (Coordinates3D) v;
-        final double dx = v3.x - x;
-        final double dy = v3.y - y;
-        final double dz = v3.z - z;
-        return dx * dx + dy * dy + dz * dz;
-    }
-
-    /** Compute the dot-product of two vectors.
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the dot product v1.v2
-     */
-    public static double dotProduct(Coordinates3D v1, Coordinates3D v2) {
-        return v1.dotProduct(v2);
-    }
-
-    /** Compute the cross-product of two vectors.
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the cross product v1 ^ v2 as a new Vector
-     */
-    public static Coordinates3D crossProduct(final Coordinates3D v1, final Coordinates3D v2) {
-        return v1.crossProduct(v2);
-    }
-
-    /** Compute the distance between two vectors according to the L<sub>1</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>v1.subtract(v2).getNorm1()</code> except that no intermediate
-     * vector is built</p>
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the distance between v1 and v2 according to the L<sub>1</sub> norm
-     */
-    public static double distance1(Coordinates3D v1, Coordinates3D v2) {
-        return v1.distance1(v2);
-    }
-
-    /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>v1.subtract(v2).getNorm()</code> except that no intermediate
-     * vector is built</p>
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
-     */
-    public static double distance(Coordinates3D v1, Coordinates3D v2) {
-        return v1.distance(v2);
-    }
-
-    /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>v1.subtract(v2).getNormInf()</code> except that no intermediate
-     * vector is built</p>
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the distance between v1 and v2 according to the L<sub>&infin;</sub> norm
-     */
-    public static double distanceInf(Coordinates3D v1, Coordinates3D v2) {
-        return v1.distanceInf(v2);
-    }
-
-    /** Compute the square of the distance between two vectors.
-     * <p>Calling this method is equivalent to calling:
-     * <code>v1.subtract(v2).getNormSq()</code> except that no intermediate
-     * vector is built</p>
-     * @param v1 first vector
-     * @param v2 second vector
-     * @return the square of the distance between v1 and v2
-     */
-    public static double distanceSq(Coordinates3D v1, Coordinates3D v2) {
-        return v1.distanceSq(v2);
-    }
-
-    /** Get a string representation of this vector.
-     * @return a string representation of this vector
-     */
-    @Override
-    public String toString() {
-        return Vector3DFormat.getInstance().format(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString(final NumberFormat format) {
-        return new Vector3DFormat(format).format(this);
-    }
-
-}


Mime
View raw message