Re: [11/11] [math] MATH-1284: Vector no longer extends Point. Replace/rename Vector?D classes with Coordinate?D classes which implement both Vector and Point. When there are multiple implementations of the same method which would confuse the compiler, prefer

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [11/11] [math] MATH-1284: Vector no longer extends Point. Replace/rename Vector?D classes with Coordinate?D classes which implement both Vector and Point. When there are multiple implementations of the same method which would confuse the compiler, prefer

Gilles Sadowski
Hi Ray.

On Tue, 25 Apr 2017 22:57:07 -0000, [hidden email] wrote:
> MATH-1284: Vector no longer extends Point.
> Replace/rename Vector?D classes with Coordinate?D classes which
> implement both Vector and Point.

Shouldn't it be "Cartesian?D"?

Regards,
Gilles

> When there are multiple implementations of the same method which
> would confuse the compiler, prefer the one which matches the
> documentation of the method.
>
> Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
> Commit:
> http://git-wip-us.apache.org/repos/asf/commons-math/commit/b815d2af
> Tree:
> http://git-wip-us.apache.org/repos/asf/commons-math/tree/b815d2af
> Diff:
> http://git-wip-us.apache.org/repos/asf/commons-math/diff/b815d2af
>
> Branch: refs/heads/feature-MATH-1284
> Commit: b815d2af5a15901dcfd90cd76f0b6f431b0f0048
> Parents: b645f5d
> Author: Ray DeCampo <[hidden email]>
> Authored: Tue Apr 25 18:55:22 2017 -0400
> Committer: Ray DeCampo <[hidden email]>
> Committed: Tue Apr 25 18:55:22 2017 -0400
>
>
> ----------------------------------------------------------------------
>  .../apache/commons/math4/geometry/Vector.java   |   19 +-
>  .../geometry/euclidean/oned/Coordinates1D.java  |  386 ++++++
>  .../geometry/euclidean/oned/IntervalsSet.java   |   18 +-
>  .../geometry/euclidean/oned/OrientedPoint.java  |    8 +-
>  .../math4/geometry/euclidean/oned/Vector1D.java |  369 -----
>  .../geometry/euclidean/oned/Vector1DFormat.java |   12 +-
>  .../euclidean/threed/Coordinates3D.java         |  621 +++++++++
>  .../euclidean/threed/FieldRotation.java         |   52 +-
>  .../euclidean/threed/FieldVector3D.java         |   78 +-
>  .../math4/geometry/euclidean/threed/Line.java   |   60 +-
>  .../euclidean/threed/OutlineExtractor.java      |   46 +-
>  .../math4/geometry/euclidean/threed/Plane.java  |  109 +-
>  .../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     |   12 +-
>  .../geometry/euclidean/threed/Vector3D.java     |  604 ---------
>  .../euclidean/threed/Vector3DFormat.java        |   22 +-
>  .../geometry/euclidean/twod/Coordinates2D.java  |  492 +++++++
>  .../geometry/euclidean/twod/DiskGenerator.java  |   16 +-
>  .../math4/geometry/euclidean/twod/Line.java     |   67 +-
>  .../geometry/euclidean/twod/NestedLoops.java    |   12 +-
>  .../geometry/euclidean/twod/PolygonsSet.java    |   74 +-
>  .../math4/geometry/euclidean/twod/Segment.java  |   14 +-
>  .../math4/geometry/euclidean/twod/SubLine.java  |   22 +-
>  .../math4/geometry/euclidean/twod/Vector2D.java |  475 -------
>  .../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 +-
>  .../geometry/partitioning/AbstractRegion.java   |    6 +-
>  .../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        |   42 +-
>  .../oned/Vector1DFormatAbstractTest.java        |   70 +-
>  .../geometry/euclidean/oned/Vector1DTest.java   |  130 +-
>  .../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 |   66 +-
>  .../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 +-
>  88 files changed, 4081 insertions(+), 4015 deletions(-)
>
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/src/main/java/org/apache/commons/math4/geometry/Vector.java
>
> ----------------------------------------------------------------------
> diff --git
> a/src/main/java/org/apache/commons/math4/geometry/Vector.java
> b/src/main/java/org/apache/commons/math4/geometry/Vector.java
> index 93a6656..fad858e 100644
> --- a/src/main/java/org/apache/commons/math4/geometry/Vector.java
> +++ b/src/main/java/org/apache/commons/math4/geometry/Vector.java
> @@ -26,7 +26,12 @@ import
> org.apache.commons.math4.exception.MathArithmeticException;
>   * @see Point
>   * @since 3.0
>   */
> -public interface Vector<S extends Space> extends Point<S> {
> +public interface Vector<S extends Space> {
> +
> +    /** Get the space to which the point belongs.
> +     * @return containing space
> +     */
> +    Space getSpace();
>
>      /** Get the null vector of the vectorial space or origin point
> of the affine space.
>       * @return null vector of the vectorial space or origin point of
> the affine space
> @@ -97,6 +102,12 @@ public interface Vector<S extends Space> extends
> Point<S> {
>      Vector<S> scalarMultiply(double a);
>
>      /**
> +     * Returns true if any coordinate of this point is NaN; false
> otherwise
> +     * @return  true if any coordinate of this point is NaN; false
> otherwise
> +     */
> +    boolean isNaN();
> +
> +    /**
>       * Returns true if any coordinate of this vector is infinite and
> none are NaN;
>       * false otherwise
>       * @return  true if any coordinate of this vector is infinite
> and none are NaN;
> @@ -113,6 +124,12 @@ public interface Vector<S extends Space> extends
> Point<S> {
>       */
>      double distance1(Vector<S> v);
>
> +    /** Compute the distance between the instance and another
> vector.
> +     * @param v second vector
> +     * @return the distance between the instance and v
> +     */
> +    double distance(Vector<S> v);
> +
>      /** Compute the distance between the instance and another vector
> according to the L<sub>&infin;</sub> norm.
>       * <p>Calling this method is equivalent to calling:
>       * <code>q.subtract(p).getNormInf()</code> except that no
> intermediate
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/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
> new file mode 100644
> index 0000000..1f31594
> --- /dev/null
> +++
>
> b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Coordinates1D.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 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/b815d2af/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 1b58cd9..78c50c1 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 Vector1D(upper), true,
> tolerance).wholeHyperplane();
> +                new OrientedPoint(new Coordinates1D(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 Vector1D(lower), false,
> tolerance).wholeHyperplane();
> +            new OrientedPoint(new Coordinates1D(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 Vector1D(upper), true,
> tolerance).wholeHyperplane();
> +            new OrientedPoint(new Coordinates1D(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>) Vector1D.NaN);
> +            setBarycenter((Point<Euclidean1D>) Coordinates1D.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>) Vector1D.NaN);
> +                setBarycenter((Point<Euclidean1D>)
> Coordinates1D.NaN);
>              } else if (size >= Precision.SAFE_MIN) {
> -                setBarycenter((Point<Euclidean1D>) new Vector1D(sum
> / size));
> +                setBarycenter((Point<Euclidean1D>) new
> Coordinates1D(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 = ((Vector1D) point).getX();
> +        final double x = ((Coordinates1D) 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 Vector1D finiteOrNullPoint(final double x) {
> -        return Double.isInfinite(x) ? null : new Vector1D(x);
> +    private Coordinates1D finiteOrNullPoint(final double x) {
> +        return Double.isInfinite(x) ? null : new Coordinates1D(x);
>      }
>
>      /** Build an ordered list of intervals representing the
> instance.
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/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 93af5b8..2f719a2 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 Vector1D location;
> +    private final Coordinates1D 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 Vector1D location, final boolean
> direct, final double tolerance) {
> +    public OrientedPoint(final Coordinates1D 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 = ((Vector1D) point).getX() -
> location.getX();
> +        final double delta = ((Coordinates1D) 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 Vector1D getLocation() {
> +    public Coordinates1D getLocation() {
>          return location;
>      }
>
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1D.java
>
> ----------------------------------------------------------------------
> diff --git
>
> a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1D.java
>
> b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1D.java
> deleted file mode 100644
> index 2b64ff7..0000000
> ---
>
> a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1D.java
> +++ /dev/null
> @@ -1,369 +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 vector.
> - * <p>Instances of this class are guaranteed to be immutable.</p>
> - * @since 3.0
> - */
> -public class Vector1D implements Vector<Euclidean1D> {
> -
> -    /** Origin (coordinates: 0). */
> -    public static final Vector1D ZERO = new Vector1D(0.0);
> -
> -    /** Unit (coordinates: 1). */
> -    public static final Vector1D ONE  = new Vector1D(1.0);
> -
> -    // CHECKSTYLE: stop ConstantName
> -    /** A vector with all coordinates set to NaN. */
> -    public static final Vector1D NaN = new Vector1D(Double.NaN);
> -    // CHECKSTYLE: resume ConstantName
> -
> -    /** A vector with all coordinates set to positive infinity. */
> -    public static final Vector1D POSITIVE_INFINITY =
> -        new Vector1D(Double.POSITIVE_INFINITY);
> -
> -    /** A vector with all coordinates set to negative infinity. */
> -    public static final Vector1D NEGATIVE_INFINITY =
> -        new Vector1D(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 Vector1D(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 Vector1D(double a, Vector1D 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 Vector1D(double a1, Vector1D u1, double a2, Vector1D 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 Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
> -                   double a3, Vector1D 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 Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
> -                   double a3, Vector1D u3, double a4, Vector1D 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 Vector1D 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 Vector1D add(Vector<Euclidean1D> v) {
> -        Vector1D v1 = (Vector1D) v;
> -        return new Vector1D(x + v1.getX());
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public Vector1D add(double factor, Vector<Euclidean1D> v) {
> -        Vector1D v1 = (Vector1D) v;
> -        return new Vector1D(x + factor * v1.getX());
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public Vector1D subtract(Vector<Euclidean1D> p) {
> -        Vector1D p3 = (Vector1D) p;
> -        return new Vector1D(x - p3.x);
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public Vector1D subtract(double factor, Vector<Euclidean1D> v) {
> -        Vector1D v1 = (Vector1D) v;
> -        return new Vector1D(x - factor * v1.getX());
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public Vector1D 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 Vector1D negate() {
> -        return new Vector1D(-x);
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public Vector1D scalarMultiply(double a) {
> -        return new Vector1D(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) {
> -        Vector1D p3 = (Vector1D) p;
> -        final double dx = FastMath.abs(p3.x - x);
> -        return dx;
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public double distance(Point<Euclidean1D> p) {
> -        Vector1D p3 = (Vector1D) p;
> -        final double dx = p3.x - x;
> -        return FastMath.abs(dx);
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public double distanceInf(Vector<Euclidean1D> p) {
> -        Vector1D p3 = (Vector1D) p;
> -        final double dx = FastMath.abs(p3.x - x);
> -        return dx;
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public double distanceSq(Vector<Euclidean1D> p) {
> -        Vector1D p3 = (Vector1D) p;
> -        final double dx = p3.x - x;
> -        return dx * dx;
> -    }
> -
> -    /** {@inheritDoc} */
> -    @Override
> -    public double dotProduct(final Vector<Euclidean1D> v) {
> -        final Vector1D v1 = (Vector1D) 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(Vector1D p1, Vector1D 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(Vector1D p1, Vector1D 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(Vector1D p1, Vector1D 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 Vector1D) {
> -            final Vector1D rhs = (Vector1D)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/b815d2af/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 d3c4bd8..4b40bb3 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 Vector1D p1 = (Vector1D) vector;
> +        final Coordinates1D p1 = (Coordinates1D) vector;
>          return format(toAppendTo, pos, p1.getX());
>      }
>
>      /** {@inheritDoc} */
>      @Override
> -    public Vector1D parse(final String source) throws
> MathParseException {
> +    public Coordinates1D parse(final String source) throws
> MathParseException {
>          ParsePosition parsePosition = new ParsePosition(0);
> -        Vector1D result = parse(source, parsePosition);
> +        Coordinates1D result = parse(source, parsePosition);
>          if (parsePosition.getIndex() == 0) {
>              throw new MathParseException(source,
>                                          
> parsePosition.getErrorIndex(),
> -                                         Vector1D.class);
> +                                         Coordinates1D.class);
>          }
>          return result;
>      }
>
>      /** {@inheritDoc} */
>      @Override
> -    public Vector1D parse(final String source, final ParsePosition
> pos) {
> +    public Coordinates1D parse(final String source, final
> ParsePosition pos) {
>          final double[] coordinates = parseCoordinates(1, source,
> pos);
>          if (coordinates == null) {
>              return null;
>          }
> -        return new Vector1D(coordinates[0]);
> +        return new Coordinates1D(coordinates[0]);
>      }
>
>  }
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/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
> new file mode 100644
> index 0000000..ee2376c
> --- /dev/null
> +++
>
> b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Coordinates3D.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 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);
> +    }
> +
> +}
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/b815d2af/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldRotation.java
>
> ----------------------------------------------------------------------
> diff --git
>
> a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldRotation.java
>
> b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldRotation.java
> index be89ef4..a05ab8e 100644
> ---
>
> a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldRotation.java
> +++
>
> b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldRotation.java
> @@ -820,8 +820,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusK) coordinates are :
>                  // sin (theta), -sin (phi) cos (theta), cos (phi)
> cos (theta)
>                  // and we can choose to have theta in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_I);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_K);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_I);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_K);
>                  if ((v2.getX().getReal() < -0.9999999999) ||
> (v2.getX().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -836,8 +836,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusJ) coordinates are :
>                  // -sin (psi), cos (phi) cos (psi), sin (phi) cos
> (psi)
>                  // and we can choose to have psi in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_I);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_J);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_I);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_J);
>                  if ((v2.getX().getReal() < -0.9999999999) ||
> (v2.getX().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -852,8 +852,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusK) coordinates are :
>                  // sin (theta) cos (phi), -sin (phi), cos (theta)
> cos (phi)
>                  // and we can choose to have phi in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_J);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_K);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_J);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_K);
>                  if ((v2.getY().getReal() < -0.9999999999) ||
> (v2.getY().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -868,8 +868,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusI) coordinates are :
>                  // cos (theta) cos (psi), sin (psi), -sin (theta)
> cos (psi)
>                  // and we can choose to have psi in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_J);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_I);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_J);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_I);
>                  if ((v2.getY().getReal() < -0.9999999999) ||
> (v2.getY().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -884,8 +884,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusJ) coordinates are :
>                  // -sin (psi) cos (phi), cos (psi) cos (phi), sin
> (phi)
>                  // and we can choose to have phi in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_K);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_J);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_K);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_J);
>                  if ((v2.getZ().getReal() < -0.9999999999) ||
> (v2.getZ().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -900,8 +900,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusI) coordinates are :
>                  // cos (psi) cos (theta), sin (psi) cos (theta),
> -sin (theta)
>                  // and we can choose to have theta in the interval
> [-PI/2 ; +PI/2]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_K);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_I);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_K);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_I);
>                  if  ((v2.getZ().getReal() < -0.9999999999) ||
> (v2.getZ().getReal() > 0.9999999999)) {
>                      throw new CardanEulerSingularityException(true);
>                  }
> @@ -916,8 +916,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusI) coordinates are :
>                  // cos (theta), sin (theta) sin (phi1), -sin (theta)
> cos (phi1)
>                  // and we can choose to have theta in the interval
> [0 ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_I);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_I);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_I);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_I);
>                  if ((v2.getX().getReal() < -0.9999999999) ||
> (v2.getX().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -932,8 +932,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusI) coordinates are :
>                  // cos (psi), sin (psi) cos (phi1), sin (psi) sin
> (phi1)
>                  // and we can choose to have psi in the interval [0
> ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_I);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_I);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_I);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_I);
>                  if ((v2.getX().getReal() < -0.9999999999) ||
> (v2.getX().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -948,8 +948,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusJ) coordinates are :
>                  //  sin (theta1) sin (phi), cos (phi), cos (theta1)
> sin (phi)
>                  // and we can choose to have phi in the interval [0
> ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_J);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_J);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_J);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_J);
>                  if ((v2.getY().getReal() < -0.9999999999) ||
> (v2.getY().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -964,8 +964,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusJ) coordinates are :
>                  //  -cos (theta1) sin (psi), cos (psi), sin (theta1)
> sin (psi)
>                  // and we can choose to have psi in the interval [0
> ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_J);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_J);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_J);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_J);
>                  if ((v2.getY().getReal() < -0.9999999999) ||
> (v2.getY().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -980,8 +980,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusK) coordinates are :
>                  //  sin (psi1) sin (phi), -cos (psi1) sin (phi), cos
> (phi)
>                  // and we can choose to have phi in the interval [0
> ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_K);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_K);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_K);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_K);
>                  if ((v2.getZ().getReal() < -0.9999999999) ||
> (v2.getZ().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -996,8 +996,8 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>                  // (-r) (Vector3D.plusK) coordinates are :
>                  //  cos (psi1) sin (theta), sin (psi1) sin (theta),
> cos (theta)
>                  // and we can choose to have theta in the interval
> [0 ; PI]
> -                FieldVector3D<T> v1 = applyTo(Vector3D.PLUS_K);
> -                FieldVector3D<T> v2 =
> applyInverseTo(Vector3D.PLUS_K);
> +                FieldVector3D<T> v1 = applyTo(Coordinates3D.PLUS_K);
> +                FieldVector3D<T> v2 =
> applyInverseTo(Coordinates3D.PLUS_K);
>                  if ((v2.getZ().getReal() < -0.9999999999) ||
> (v2.getZ().getReal() > 0.9999999999)) {
>                      throw new
> CardanEulerSingularityException(false);
>                  }
> @@ -1100,7 +1100,7 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>       * @param u vector to apply the rotation to
>       * @return a new vector which is the image of u by the rotation
>       */
> -    public FieldVector3D<T> applyTo(final Vector3D u) {
> +    public FieldVector3D<T> applyTo(final Coordinates3D u) {
>
>          final double x = u.getX();
>          final double y = u.getY();
> @@ -1194,7 +1194,7 @@ public class FieldRotation<T extends
> RealFieldElement<T>> implements Serializabl
>       * @param u vector to apply the inverse of the rotation to
>       * @return a new vector which such that u is its image by the
> rotation
>       */
> -    public FieldVector3D<T> applyInverseTo(final Vector3D u) {
> +    public FieldVector3D<T> applyInverseTo(final Coordinates3D u) {
>
>          final double x = u.getX();
>          final double y = u.getY();


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [11/11] [math] MATH-1284: Vector no longer extends Point. Replace/rename Vector?D classes with Coordinate?D classes which implement both Vector and Point. When there are multiple implementations of the same method which would confuse the compiler, prefer

Raymond DeCampo
On Tue, Apr 25, 2017 at 8:24 PM, Gilles <[hidden email]>
wrote:

> Hi Ray.
>
> On Tue, 25 Apr 2017 22:57:07 -0000, [hidden email] wrote:
>
>> MATH-1284: Vector no longer extends Point.
>> Replace/rename Vector?D classes with Coordinate?D classes which
>> implement both Vector and Point.
>>
>
> Shouldn't it be "Cartesian?D"?
>
>
Yes, I like that name better.