You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2019/12/02 04:46:53 UTC

[commons-math] branch master updated: MATH-1469: Removal of codes ported to "Commons Geometry".

This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git


The following commit(s) were added to refs/heads/master by this push:
     new 735dbc7  MATH-1469: Removal of codes ported to "Commons Geometry".
735dbc7 is described below

commit 735dbc79340d609318a339cf7b85cb542e969d0a
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Mon Dec 2 05:25:25 2019 +0100

    MATH-1469: Removal of codes ported to "Commons Geometry".
    
    Classes "FieldVector3D" and "FieldRotation" were not ported as they depend on "RealFieldElement".
---
 pom.xml                                            |   13 +
 .../org/apache/commons/math4/geometry/Point.java   |   46 -
 .../org/apache/commons/math4/geometry/Space.java   |   42 -
 .../org/apache/commons/math4/geometry/Vector.java  |  163 --
 .../commons/math4/geometry/VectorFormat.java       |  290 ---
 .../commons/math4/geometry/enclosing/Encloser.java |   36 -
 .../math4/geometry/enclosing/EnclosingBall.java    |  104 --
 .../geometry/enclosing/SupportBallGenerator.java   |   42 -
 .../math4/geometry/enclosing/WelzlEncloser.java    |  182 --
 .../math4/geometry/enclosing/package-info.java     |   24 -
 .../math4/geometry/euclidean/oned/Cartesian1D.java |  387 ----
 .../math4/geometry/euclidean/oned/Euclidean1D.java |  102 --
 .../math4/geometry/euclidean/oned/Interval.java    |   99 --
 .../geometry/euclidean/oned/IntervalsSet.java      |  627 -------
 .../geometry/euclidean/oned/OrientedPoint.java     |  146 --
 .../geometry/euclidean/oned/SubOrientedPoint.java  |   77 -
 .../math4/geometry/euclidean/oned/Vector1D.java    |   33 -
 .../geometry/euclidean/oned/Vector1DFormat.java    |  135 --
 .../geometry/euclidean/oned/package-info.java      |   24 -
 .../geometry/euclidean/threed/Cartesian3D.java     |  621 -------
 .../geometry/euclidean/threed/Euclidean3D.java     |   76 -
 .../geometry/euclidean/threed/FieldRotation.java   |  139 +-
 .../geometry/euclidean/threed/FieldVector3D.java   |   98 +-
 .../math4/geometry/euclidean/threed/Line.java      |  281 ---
 .../euclidean/threed/OutlineExtractor.java         |  266 ---
 .../math4/geometry/euclidean/threed/Plane.java     |  509 ------
 .../geometry/euclidean/threed/PolyhedronsSet.java  |  725 --------
 .../math4/geometry/euclidean/threed/Rotation.java  | 1424 ---------------
 .../geometry/euclidean/threed/RotationOrder.java   |   40 +-
 .../math4/geometry/euclidean/threed/Segment.java   |   66 -
 .../geometry/euclidean/threed/SphereGenerator.java |  153 --
 .../euclidean/threed/SphericalCoordinates.java     |  395 -----
 .../math4/geometry/euclidean/threed/SubLine.java   |  151 --
 .../math4/geometry/euclidean/threed/SubPlane.java  |  106 --
 .../math4/geometry/euclidean/threed/Vector3D.java  |   46 -
 .../geometry/euclidean/threed/Vector3DFormat.java  |  155 --
 .../geometry/euclidean/threed/package-info.java    |   24 -
 .../math4/geometry/euclidean/twod/Cartesian2D.java |  492 ------
 .../geometry/euclidean/twod/DiskGenerator.java     |  109 --
 .../math4/geometry/euclidean/twod/Euclidean2D.java |   76 -
 .../math4/geometry/euclidean/twod/Line.java        |  574 ------
 .../math4/geometry/euclidean/twod/NestedLoops.java |  201 ---
 .../math4/geometry/euclidean/twod/PolygonsSet.java | 1111 ------------
 .../math4/geometry/euclidean/twod/Segment.java     |  112 --
 .../math4/geometry/euclidean/twod/SubLine.java     |  201 ---
 .../math4/geometry/euclidean/twod/Vector2D.java    |   38 -
 .../geometry/euclidean/twod/Vector2DFormat.java    |  138 --
 .../twod/hull/AbstractConvexHullGenerator2D.java   |  117 --
 .../euclidean/twod/hull/AklToussaintHeuristic.java |  153 --
 .../geometry/euclidean/twod/hull/ConvexHull2D.java |  174 --
 .../euclidean/twod/hull/ConvexHullGenerator2D.java |   38 -
 .../euclidean/twod/hull/MonotoneChain.java         |  182 --
 .../geometry/euclidean/twod/hull/package-info.java |   25 -
 .../geometry/euclidean/twod/package-info.java      |   24 -
 .../commons/math4/geometry/hull/ConvexHull.java    |   48 -
 .../math4/geometry/hull/ConvexHullGenerator.java   |   49 -
 .../commons/math4/geometry/hull/package-info.java  |   24 -
 .../geometry/partitioning/AbstractRegion.java      |  548 ------
 .../partitioning/AbstractSubHyperplane.java        |  191 --
 .../math4/geometry/partitioning/BSPTree.java       |  784 ---------
 .../geometry/partitioning/BSPTreeVisitor.java      |  114 --
 .../geometry/partitioning/BoundaryAttribute.java   |   99 --
 .../geometry/partitioning/BoundaryBuilder.java     |   98 --
 .../geometry/partitioning/BoundaryProjection.java  |   83 -
 .../geometry/partitioning/BoundaryProjector.java   |  203 ---
 .../geometry/partitioning/BoundarySizeVisitor.java |   68 -
 .../geometry/partitioning/Characterization.java    |  197 ---
 .../math4/geometry/partitioning/Embedding.java     |   68 -
 .../math4/geometry/partitioning/Hyperplane.java    |   98 --
 .../math4/geometry/partitioning/InsideFinder.java  |  150 --
 .../math4/geometry/partitioning/NodesSet.java      |   73 -
 .../math4/geometry/partitioning/Region.java        |  208 ---
 .../math4/geometry/partitioning/RegionFactory.java |  388 ----
 .../commons/math4/geometry/partitioning/Side.java  |   37 -
 .../math4/geometry/partitioning/SubHyperplane.java |  145 --
 .../math4/geometry/partitioning/Transform.java     |   80 -
 .../math4/geometry/partitioning/package-info.java  |  114 --
 .../commons/math4/geometry/spherical/oned/Arc.java |  133 --
 .../math4/geometry/spherical/oned/ArcsSet.java     |  960 ----------
 .../math4/geometry/spherical/oned/LimitAngle.java  |  134 --
 .../math4/geometry/spherical/oned/S1Point.java     |  161 --
 .../math4/geometry/spherical/oned/Sphere1D.java    |  108 --
 .../geometry/spherical/oned/SubLimitAngle.java     |   66 -
 .../geometry/spherical/oned/package-info.java      |   30 -
 .../math4/geometry/spherical/twod/Circle.java      |  338 ----
 .../math4/geometry/spherical/twod/Edge.java        |  223 ---
 .../geometry/spherical/twod/EdgesBuilder.java      |  172 --
 .../spherical/twod/PropertiesComputer.java         |  176 --
 .../math4/geometry/spherical/twod/S2Point.java     |  240 ---
 .../math4/geometry/spherical/twod/Sphere2D.java    |   82 -
 .../spherical/twod/SphericalPolygonsSet.java       |  565 ------
 .../math4/geometry/spherical/twod/SubCircle.java   |   72 -
 .../math4/geometry/spherical/twod/Vertex.java      |  124 --
 .../geometry/spherical/twod/package-info.java      |   30 -
 .../AbstractLeastSquaresOptimizerAbstractTest.java |    6 +-
 .../fitting/leastsquares/CircleVectorial.java      |   18 +-
 .../GaussNewtonOptimizerWithSVDTest.java           |   10 +-
 .../LevenbergMarquardtOptimizerTest.java           |    8 +-
 .../leastsquares/RandomCirclePointGenerator.java   |   10 +-
 .../commons/math4/geometry/GeometryTestUtils.java  |  356 ----
 .../geometry/enclosing/WelzlEncloser2DTest.java    |  179 --
 .../geometry/enclosing/WelzlEncloser3DTest.java    |  187 --
 .../geometry/euclidean/oned/Cartesian1DTest.java   |  387 ----
 .../geometry/euclidean/oned/Euclidean1DTest.java   |   44 -
 .../euclidean/oned/FrenchVector1DFormatTest.java   |   34 -
 .../geometry/euclidean/oned/IntervalTest.java      |  184 --
 .../geometry/euclidean/oned/IntervalsSetTest.java  |  587 -------
 .../geometry/euclidean/oned/OrientedPointTest.java |  189 --
 .../euclidean/oned/SubOrientedPointTest.java       |  160 --
 .../euclidean/oned/Vector1DFormatAbstractTest.java |  274 ---
 .../euclidean/oned/Vector1DFormatTest.java         |   34 -
 .../geometry/euclidean/threed/Euclidean3DTest.java |   45 -
 .../euclidean/threed/FieldRotationDSTest.java      |   97 +-
 .../euclidean/threed/FieldRotationDfpTest.java     |   78 +-
 .../euclidean/threed/FieldVector3DTest.java        |   76 +-
 .../euclidean/threed/FrenchVector3DFormatTest.java |   34 -
 .../math4/geometry/euclidean/threed/LineTest.java  |  149 --
 .../math4/geometry/euclidean/threed/OBJWriter.java |  337 ----
 .../math4/geometry/euclidean/threed/PLYParser.java |  290 ---
 .../math4/geometry/euclidean/threed/PlaneTest.java |  171 --
 .../euclidean/threed/PolyhedronsSetTest.java       | 1511 ----------------
 .../geometry/euclidean/threed/RotationTest.java    |  823 ---------
 .../euclidean/threed/SphereGeneratorTest.java      |  187 --
 .../euclidean/threed/SphericalCoordinatesTest.java |  188 --
 .../geometry/euclidean/threed/SubLineTest.java     |  168 --
 .../threed/Vector3DFormatAbstractTest.java         |  330 ----
 .../euclidean/threed/Vector3DFormatTest.java       |   34 -
 .../geometry/euclidean/threed/Vector3DTest.java    |  415 -----
 .../geometry/euclidean/twod/Cartesian2DTest.java   |  235 ---
 .../geometry/euclidean/twod/DiskGeneratorTest.java |  121 --
 .../geometry/euclidean/twod/Euclidean2DTest.java   |   45 -
 .../euclidean/twod/FrenchVector2DFormatTest.java   |   34 -
 .../math4/geometry/euclidean/twod/LineTest.java    |  133 --
 .../geometry/euclidean/twod/NestedLoopsTest.java   |   67 -
 .../geometry/euclidean/twod/PolygonsSetTest.java   | 1844 --------------------
 .../math4/geometry/euclidean/twod/SegmentTest.java |   46 -
 .../math4/geometry/euclidean/twod/SubLineTest.java |  159 --
 .../euclidean/twod/Vector2DFormatAbstractTest.java |  316 ----
 .../euclidean/twod/Vector2DFormatTest.java         |   34 -
 .../twod/hull/AklToussaintHeuristicTest.java       |   41 -
 .../hull/ConvexHullGenerator2DAbstractTest.java    |  446 -----
 .../euclidean/twod/hull/MonotoneChainTest.java     |   58 -
 .../partitioning/CharacterizationTest.java         |  420 -----
 .../math4/geometry/partitioning/RegionDumper.java  |  244 ---
 .../math4/geometry/partitioning/RegionParser.java  |  303 ----
 .../math4/geometry/spherical/oned/ArcTest.java     |   82 -
 .../math4/geometry/spherical/oned/ArcsSetTest.java |  598 -------
 .../geometry/spherical/oned/LimitAngleTest.java    |   40 -
 .../math4/geometry/spherical/oned/S1PointTest.java |   77 -
 .../math4/geometry/spherical/oned/Sphere1Test.java |   44 -
 .../math4/geometry/spherical/twod/CircleTest.java  |  192 --
 .../math4/geometry/spherical/twod/S2PointTest.java |   90 -
 .../spherical/twod/SphericalPolygonsSetTest.java   |  558 ------
 .../geometry/spherical/twod/SubCircleTest.java     |  141 --
 .../MultiStartMultivariateOptimizerTest.java       |    4 +-
 .../nonlinear/scalar/gradient/CircleScalar.java    |   18 +-
 .../NonLinearConjugateGradientOptimizerTest.java   |    4 +-
 157 files changed, 312 insertions(+), 32775 deletions(-)

diff --git a/pom.xml b/pom.xml
index ad44243..c868737 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,7 @@
     <math.mathjax.version>2.7.2</math.mathjax.version>
     <math.commons.numbers.version>1.0-SNAPSHOT</math.commons.numbers.version>
     <math.commons.rng.version>1.2</math.commons.rng.version>
+    <math.commons.geometry.version>1.0-SNAPSHOT</math.commons.geometry.version>
 
     <commons.site.path>math</commons.site.path>
     <commons.scmPubUrl>https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-math</commons.scmPubUrl>
@@ -169,6 +170,12 @@
 
     <dependency>
       <groupId>org.apache.commons</groupId>
+      <artifactId>commons-numbers-quaternion</artifactId>
+      <version>${math.commons.numbers.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.commons</groupId>
       <artifactId>commons-rng-client-api</artifactId>
       <version>${math.commons.rng.version}</version>
     </dependency>
@@ -186,6 +193,12 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-geometry-euclidean</artifactId>
+      <version>${math.commons.geometry.version}</version>
+    </dependency>
+
+    <dependency>
       <groupId>org.openjdk.jmh</groupId>
       <artifactId>jmh-core</artifactId>
       <version>${jmh.version}</version>
diff --git a/src/main/java/org/apache/commons/math4/geometry/Point.java b/src/main/java/org/apache/commons/math4/geometry/Point.java
deleted file mode 100644
index d45421a..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/Point.java
+++ /dev/null
@@ -1,46 +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;
-
-import java.io.Serializable;
-
-/** This interface represents a generic geometrical point.
- * @param <S> Type of the space.
- * @see Space
- * @see Vector
- * @since 3.3
- */
-public interface Point<S extends Space> extends Serializable {
-
-    /** Get the space to which the point belongs.
-     * @return containing space
-     */
-    Space getSpace();
-
-    /**
-     * 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();
-
-    /** Compute the distance between the instance and another point.
-     * @param p second point
-     * @return the distance between the instance and p
-     */
-    double distance(Point<S> p);
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/Space.java b/src/main/java/org/apache/commons/math4/geometry/Space.java
deleted file mode 100644
index 8413c7c..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/Space.java
+++ /dev/null
@@ -1,42 +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;
-
-import java.io.Serializable;
-
-import org.apache.commons.math4.exception.MathUnsupportedOperationException;
-
-/** This interface represents a generic space, with affine and vectorial counterparts.
- * @see Vector
- * @since 3.0
- */
-public interface Space extends Serializable {
-
-    /** Get the dimension of the space.
-     * @return dimension of the space
-     */
-    int getDimension();
-
-    /** Get the n-1 dimension subspace of this space.
-     * @return n-1 dimension sub-space of this space
-     * @see #getDimension()
-     * @exception MathUnsupportedOperationException for dimension-1 spaces
-     * which do not have sub-spaces
-     */
-    Space getSubSpace() throws MathUnsupportedOperationException;
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/Vector.java b/src/main/java/org/apache/commons/math4/geometry/Vector.java
deleted file mode 100644
index fad858e..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/Vector.java
+++ /dev/null
@@ -1,163 +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;
-
-import java.text.NumberFormat;
-
-import org.apache.commons.math4.exception.MathArithmeticException;
-
-/** This interface represents a generic vector in a vectorial space or a point in an affine space.
- * @param <S> Type of the space.
- * @see Space
- * @see Point
- * @since 3.0
- */
-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
-     */
-    Vector<S> getZero();
-
-    /** Get the L<sub>1</sub> norm for the vector.
-     * @return L<sub>1</sub> norm for the vector
-     */
-    double getNorm1();
-
-    /** Get the L<sub>2</sub> norm for the vector.
-     * @return Euclidean norm for the vector
-     */
-    double getNorm();
-
-    /** Get the square of the norm for the vector.
-     * @return square of the Euclidean norm for the vector
-     */
-    double getNormSq();
-
-    /** Get the L<sub>&infin;</sub> norm for the vector.
-     * @return L<sub>&infin;</sub> norm for the vector
-     */
-    double getNormInf();
-
-    /** Add a vector to the instance.
-     * @param v vector to add
-     * @return a new vector
-     */
-    Vector<S> add(Vector<S> v);
-
-    /** Add a scaled vector to the instance.
-     * @param factor scale factor to apply to v before adding it
-     * @param v vector to add
-     * @return a new vector
-     */
-    Vector<S> add(double factor, Vector<S> v);
-
-    /** Subtract a vector from the instance.
-     * @param v vector to subtract
-     * @return a new vector
-     */
-    Vector<S> subtract(Vector<S> v);
-
-    /** Subtract a scaled vector from the instance.
-     * @param factor scale factor to apply to v before subtracting it
-     * @param v vector to subtract
-     * @return a new vector
-     */
-    Vector<S> subtract(double factor, Vector<S> v);
-
-    /** Get the opposite of the instance.
-     * @return a new vector which is opposite to the instance
-     */
-    Vector<S> negate();
-
-    /** Get a normalized vector aligned with the instance.
-     * @return a new normalized vector
-     * @exception MathArithmeticException if the norm is zero
-     */
-    Vector<S> normalize() throws MathArithmeticException;
-
-    /** Multiply the instance by a scalar.
-     * @param a scalar
-     * @return a new vector
-     */
-    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;
-     * false otherwise
-     */
-    boolean isInfinite();
-
-    /** Compute the distance between the instance and another vector according to the L<sub>1</sub> norm.
-     * <p>Calling this method is equivalent to calling:
-     * <code>q.subtract(p).getNorm1()</code> except that no intermediate
-     * vector is built</p>
-     * @param v second vector
-     * @return the distance between the instance and p according to the L<sub>1</sub> norm
-     */
-    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
-     * vector is built</p>
-     * @param v second vector
-     * @return the distance between the instance and p according to the L<sub>&infin;</sub> norm
-     */
-    double distanceInf(Vector<S> v);
-
-    /** Compute the square of the distance between the instance and another vector.
-     * <p>Calling this method is equivalent to calling:
-     * <code>q.subtract(p).getNormSq()</code> except that no intermediate
-     * vector is built</p>
-     * @param v second vector
-     * @return the square of the distance between the instance and p
-     */
-    double distanceSq(Vector<S> v);
-
-    /** Compute the dot-product of the instance and another vector.
-     * @param v second vector
-     * @return the dot product this.v
-     */
-    double dotProduct(Vector<S> v);
-
-    /** Get a string representation of this vector.
-     * @param format the custom format for components
-     * @return a string representation of this vector
-     */
-    String toString(final NumberFormat format);
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/VectorFormat.java b/src/main/java/org/apache/commons/math4/geometry/VectorFormat.java
deleted file mode 100644
index 7278a2f..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/VectorFormat.java
+++ /dev/null
@@ -1,290 +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;
-
-import java.text.FieldPosition;
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-import org.apache.commons.math4.exception.MathParseException;
-import org.apache.commons.math4.util.CompositeFormat;
-
-/**
- * Formats a vector in components list format "{x; y; ...}".
- * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
- * any user-defined strings. The number format for components can be configured.</p>
- * <p>White space is ignored at parse time, even if it is in the prefix, suffix
- * or separator specifications. So even if the default separator does include a space
- * character that is used at format time, both input string "{1;1;1}" and
- * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be
- * returned. In the second case, however, the parse position after parsing will be
- * just after the closing curly brace, i.e. just before the trailing space.</p>
- * <p><b>Note:</b> using "," as a separator may interfere with the grouping separator
- * of the default {@link NumberFormat} for the current locale. Thus it is advised
- * to use a {@link NumberFormat} instance with disabled grouping in such a case.</p>
- *
- * @param <S> Type of the space.
- * @since 3.0
- */
-public abstract class VectorFormat<S extends Space> {
-
-    /** The default prefix: "{". */
-    public static final String DEFAULT_PREFIX = "{";
-
-    /** The default suffix: "}". */
-    public static final String DEFAULT_SUFFIX = "}";
-
-    /** The default separator: ", ". */
-    public static final String DEFAULT_SEPARATOR = "; ";
-
-    /** Prefix. */
-    private final String prefix;
-
-    /** Suffix. */
-    private final String suffix;
-
-    /** Separator. */
-    private final String separator;
-
-    /** Trimmed prefix. */
-    private final String trimmedPrefix;
-
-    /** Trimmed suffix. */
-    private final String trimmedSuffix;
-
-    /** Trimmed separator. */
-    private final String trimmedSeparator;
-
-    /** The format used for components. */
-    private final NumberFormat format;
-
-    /**
-     * Create an instance with default settings.
-     * <p>The instance uses the default prefix, suffix and separator:
-     * "{", "}", and "; " and the default number format for components.</p>
-     */
-    protected VectorFormat() {
-        this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
-             CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with a custom number format for components.
-     * @param format the custom format for components.
-     */
-    protected VectorFormat(final NumberFormat format) {
-        this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix and separator.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     * @param separator separator to use instead of the default "; "
-     */
-    protected VectorFormat(final String prefix, final String suffix,
-                          final String separator) {
-        this(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix, separator and format
-     * for components.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     * @param separator separator to use instead of the default "; "
-     * @param format the custom format for components.
-     */
-    protected VectorFormat(final String prefix, final String suffix,
-                          final String separator, final NumberFormat format) {
-        this.prefix      = prefix;
-        this.suffix      = suffix;
-        this.separator   = separator;
-        trimmedPrefix    = prefix.trim();
-        trimmedSuffix    = suffix.trim();
-        trimmedSeparator = separator.trim();
-        this.format      = format;
-    }
-
-    /**
-     * Get the set of locales for which point/vector formats are available.
-     * <p>This is the same set as the {@link NumberFormat} set.</p>
-     * @return available point/vector format locales.
-     */
-    public static Locale[] getAvailableLocales() {
-        return NumberFormat.getAvailableLocales();
-    }
-
-    /**
-     * Get the format prefix.
-     * @return format prefix.
-     */
-    public String getPrefix() {
-        return prefix;
-    }
-
-    /**
-     * Get the format suffix.
-     * @return format suffix.
-     */
-    public String getSuffix() {
-        return suffix;
-    }
-
-    /**
-     * Get the format separator between components.
-     * @return format separator.
-     */
-    public String getSeparator() {
-        return separator;
-    }
-
-    /**
-     * Get the components format.
-     * @return components format.
-     */
-    public NumberFormat getFormat() {
-        return format;
-    }
-
-    /**
-     * Formats a {@link Vector} object to produce a string.
-     * @param vector the object to format.
-     * @return a formatted string.
-     */
-    public String format(Vector<S> vector) {
-        return format(vector, new StringBuffer(), new FieldPosition(0)).toString();
-    }
-
-    /**
-     * Formats a {@link Vector} object to produce a string.
-     * @param vector the object to format.
-     * @param toAppendTo where the text is to be appended
-     * @param pos On input: an alignment field, if desired. On output: the
-     *            offsets of the alignment field
-     * @return the value passed in as toAppendTo.
-     */
-    public abstract StringBuffer format(Vector<S> vector,
-                                        StringBuffer toAppendTo, FieldPosition pos);
-
-    /**
-     * Formats the coordinates of a {@link Vector} to produce a string.
-     * @param toAppendTo where the text is to be appended
-     * @param pos On input: an alignment field, if desired. On output: the
-     *            offsets of the alignment field
-     * @param coordinates coordinates of the object to format.
-     * @return the value passed in as toAppendTo.
-     */
-    protected StringBuffer format(StringBuffer toAppendTo, FieldPosition pos,
-                                  double ... coordinates) {
-
-        pos.setBeginIndex(0);
-        pos.setEndIndex(0);
-
-        // format prefix
-        toAppendTo.append(prefix);
-
-        // format components
-        for (int i = 0; i < coordinates.length; ++i) {
-            if (i > 0) {
-                toAppendTo.append(separator);
-            }
-            CompositeFormat.formatDouble(coordinates[i], format, toAppendTo, pos);
-        }
-
-        // format suffix
-        toAppendTo.append(suffix);
-
-        return toAppendTo;
-
-    }
-
-    /**
-     * Parses a string to produce a {@link Vector} object.
-     * @param source the string to parse
-     * @return the parsed {@link Vector} object.
-     * @throws MathParseException if the beginning of the specified string
-     * cannot be parsed.
-     */
-    public abstract Vector<S> parse(String source) throws MathParseException;
-
-    /**
-     * Parses a string to produce a {@link Vector} object.
-     * @param source the string to parse
-     * @param pos input/output parsing parameter.
-     * @return the parsed {@link Vector} object.
-     */
-    public abstract Vector<S> parse(String source, ParsePosition pos);
-
-    /**
-     * Parses a string to produce an array of coordinates.
-     * @param dimension dimension of the space
-     * @param source the string to parse
-     * @param pos input/output parsing parameter.
-     * @return coordinates array.
-     */
-    protected double[] parseCoordinates(int dimension, String source, ParsePosition pos) {
-
-        int initialIndex = pos.getIndex();
-        double[] coordinates = new double[dimension];
-
-        // parse prefix
-        CompositeFormat.parseAndIgnoreWhitespace(source, pos);
-        if (!CompositeFormat.parseFixedstring(source, trimmedPrefix, pos)) {
-            return null;
-        }
-
-        for (int i = 0; i < dimension; ++i) {
-
-            // skip whitespace
-            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
-
-            // parse separator
-            if (i > 0 && !CompositeFormat.parseFixedstring(source, trimmedSeparator, pos)) {
-                return null;
-            }
-
-            // skip whitespace
-            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
-
-            // parse coordinate
-            Number c = CompositeFormat.parseNumber(source, format, pos);
-            if (c == null) {
-                // invalid coordinate
-                // set index back to initial, error index should already be set
-                pos.setIndex(initialIndex);
-                return null;
-            }
-
-            // store coordinate
-            coordinates[i] = c.doubleValue();
-
-        }
-
-        // parse suffix
-        CompositeFormat.parseAndIgnoreWhitespace(source, pos);
-        if (!CompositeFormat.parseFixedstring(source, trimmedSuffix, pos)) {
-            return null;
-        }
-
-        return coordinates;
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/enclosing/Encloser.java b/src/main/java/org/apache/commons/math4/geometry/enclosing/Encloser.java
deleted file mode 100644
index 5997779..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/enclosing/Encloser.java
+++ /dev/null
@@ -1,36 +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.enclosing;
-
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-
-/** Interface for algorithms computing enclosing balls.
- * @param <S> Space type.
- * @param <P> Point type.
- * @see EnclosingBall
- * @since 3.3
- */
-public interface Encloser<S extends Space, P extends Point<S>> {
-
-    /** Find a ball enclosing a list of points.
-     * @param points points to enclose
-     * @return enclosing ball
-     */
-    EnclosingBall<S, P> enclose(Iterable<P> points);
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/enclosing/EnclosingBall.java b/src/main/java/org/apache/commons/math4/geometry/enclosing/EnclosingBall.java
deleted file mode 100644
index 9279377..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/enclosing/EnclosingBall.java
+++ /dev/null
@@ -1,104 +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.enclosing;
-
-import java.io.Serializable;
-
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-
-/** This class represents a ball enclosing some points.
- * @param <S> Space type.
- * @param <P> Point type.
- * @see Space
- * @see Point
- * @see Encloser
- * @since 3.3
- */
-public class EnclosingBall<S extends Space, P extends Point<S>> implements Serializable {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20140126L;
-
-    /** Center of the ball. */
-    private final P center;
-
-    /** Radius of the ball. */
-    private final double radius;
-
-    /** Support points used to define the ball. */
-    private final P[] support;
-
-    /** Simple constructor.
-     * @param center center of the ball
-     * @param radius radius of the ball
-     * @param support support points used to define the ball
-     */
-    @SafeVarargs
-    public EnclosingBall(final P center, final double radius, final P ... support) {
-        this.center  = center;
-        this.radius  = radius;
-        this.support = support.clone();
-    }
-
-    /** Get the center of the ball.
-     * @return center of the ball
-     */
-    public P getCenter() {
-        return center;
-    }
-
-    /** Get the radius of the ball.
-     * @return radius of the ball (can be negative if the ball is empty)
-     */
-    public double getRadius() {
-        return radius;
-    }
-
-    /** Get the support points used to define the ball.
-     * @return support points used to define the ball
-     */
-    public P[] getSupport() {
-        return support.clone();
-    }
-
-    /** Get the number of support points used to define the ball.
-     * @return number of support points used to define the ball
-     */
-    public int getSupportSize() {
-        return support.length;
-    }
-
-    /** Check if a point is within the ball or at boundary.
-     * @param point point to test
-     * @return true if the point is within the ball or at boundary
-     */
-    public boolean contains(final P point) {
-        return point.distance(center) <= radius;
-    }
-
-    /** Check if a point is within an enlarged ball or at boundary.
-     * @param point point to test
-     * @param margin margin to consider
-     * @return true if the point is within the ball enlarged
-     * by the margin or at boundary
-     */
-    public boolean contains(final P point, final double margin) {
-        return point.distance(center) <= radius + margin;
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/enclosing/SupportBallGenerator.java b/src/main/java/org/apache/commons/math4/geometry/enclosing/SupportBallGenerator.java
deleted file mode 100644
index 9886d97..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/enclosing/SupportBallGenerator.java
+++ /dev/null
@@ -1,42 +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.enclosing;
-
-import java.util.List;
-
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-
-/** Interface for generating balls based on support points.
- * <p>
- * This generator is used in the {@link WelzlEncloser Emo Welzl} algorithm
- * and its derivatives.
- * </p>
- * @param <S> Space type.
- * @param <P> Point type.
- * @see EnclosingBall
- * @since 3.3
- */
-public interface SupportBallGenerator<S extends Space, P extends Point<S>> {
-
-    /** Create a ball whose boundary lies on prescribed support points.
-     * @param support support points (may be empty)
-     * @return ball whose boundary lies on the prescribed support points
-     */
-    EnclosingBall<S, P> ballOnSupport(List<P> support);
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/enclosing/WelzlEncloser.java b/src/main/java/org/apache/commons/math4/geometry/enclosing/WelzlEncloser.java
deleted file mode 100644
index 924fa83..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/enclosing/WelzlEncloser.java
+++ /dev/null
@@ -1,182 +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.enclosing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.math4.exception.MathInternalError;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Space;
-
-/** Class implementing Emo Welzl algorithm to find the smallest enclosing ball in linear time.
- * <p>
- * The class implements the algorithm described in paper <a
- * href="http://www.inf.ethz.ch/personal/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf">Smallest
- * Enclosing Disks (Balls and Ellipsoids)</a> by Emo Welzl, Lecture Notes in Computer Science
- * 555 (1991) 359-370. The pivoting improvement published in the paper <a
- * href="http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf">Fast and
- * Robust Smallest Enclosing Balls</a>, by Bernd Gärtner and further modified in
- * paper <a
- * href="http://www.idt.mdh.se/kurser/ct3340/ht12/MINICONFERENCE/FinalPapers/ircse12_submission_30.pdf">
- * Efficient Computation of Smallest Enclosing Balls in Three Dimensions</a> by Linus Källberg
- * to avoid performing local copies of data have been included.
- * </p>
- * @param <S> Space type.
- * @param <P> Point type.
- * @since 3.3
- */
-public class WelzlEncloser<S extends Space, P extends Point<S>> implements Encloser<S, P> {
-
-    /** Tolerance below which points are consider to be identical. */
-    private final double tolerance;
-
-    /** Generator for balls on support. */
-    private final SupportBallGenerator<S, P> generator;
-
-    /** Simple constructor.
-     * @param tolerance below which points are consider to be identical
-     * @param generator generator for balls on support
-     */
-    public WelzlEncloser(final double tolerance, final SupportBallGenerator<S, P> generator) {
-        this.tolerance = tolerance;
-        this.generator = generator;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public EnclosingBall<S, P> enclose(final Iterable<P> points) {
-
-        if (points == null || !points.iterator().hasNext()) {
-            // return an empty ball
-            return generator.ballOnSupport(new ArrayList<P>());
-        }
-
-        // Emo Welzl algorithm with Bernd Gärtner and Linus Källberg improvements
-        return pivotingBall(points);
-
-    }
-
-    /** Compute enclosing ball using Gärtner's pivoting heuristic.
-     * @param points points to be enclosed
-     * @return enclosing ball
-     */
-    private EnclosingBall<S, P> pivotingBall(final Iterable<P> points) {
-
-        final P first = points.iterator().next();
-        final List<P> extreme = new ArrayList<>(first.getSpace().getDimension() + 1);
-        final List<P> support = new ArrayList<>(first.getSpace().getDimension() + 1);
-
-        // start with only first point selected as a candidate support
-        extreme.add(first);
-        EnclosingBall<S, P> ball = moveToFrontBall(extreme, extreme.size(), support);
-
-        while (true) {
-
-            // select the point farthest to current ball
-            final P farthest = selectFarthest(points, ball);
-
-            if (ball.contains(farthest, tolerance)) {
-                // we have found a ball containing all points
-                return ball;
-            }
-
-            // recurse search, restricted to the small subset containing support and farthest point
-            support.clear();
-            support.add(farthest);
-            EnclosingBall<S, P> savedBall = ball;
-            ball = moveToFrontBall(extreme, extreme.size(), support);
-            if (ball.getRadius() < savedBall.getRadius()) {
-                // this should never happen
-                throw new MathInternalError();
-            }
-
-            // it was an interesting point, move it to the front
-            // according to Gärtner's heuristic
-            extreme.add(0, farthest);
-
-            // prune the least interesting points
-            extreme.subList(ball.getSupportSize(), extreme.size()).clear();
-
-
-        }
-    }
-
-    /** Compute enclosing ball using Welzl's move to front heuristic.
-     * @param extreme subset of extreme points
-     * @param nbExtreme number of extreme points to consider
-     * @param support points that must belong to the ball support
-     * @return enclosing ball, for the extreme subset only
-     */
-    private EnclosingBall<S, P> moveToFrontBall(final List<P> extreme, final int nbExtreme,
-                                                final List<P> support) {
-
-        // create a new ball on the prescribed support
-        EnclosingBall<S, P> ball = generator.ballOnSupport(support);
-
-        if (ball.getSupportSize() <= ball.getCenter().getSpace().getDimension()) {
-
-            for (int i = 0; i < nbExtreme; ++i) {
-                final P pi = extreme.get(i);
-                if (!ball.contains(pi, tolerance)) {
-
-                    // we have found an outside point,
-                    // enlarge the ball by adding it to the support
-                    support.add(pi);
-                    ball = moveToFrontBall(extreme, i, support);
-                    support.remove(support.size() - 1);
-
-                    // it was an interesting point, move it to the front
-                    // according to Welzl's heuristic
-                    for (int j = i; j > 0; --j) {
-                        extreme.set(j, extreme.get(j - 1));
-                    }
-                    extreme.set(0, pi);
-
-                }
-            }
-
-        }
-
-        return ball;
-
-    }
-
-    /** Select the point farthest to the current ball.
-     * @param points points to be enclosed
-     * @param ball current ball
-     * @return farthest point
-     */
-    public P selectFarthest(final Iterable<P> points, final EnclosingBall<S, P> ball) {
-
-        final P center = ball.getCenter();
-        P farthest   = null;
-        double dMax  = -1.0;
-
-        for (final P point : points) {
-            final double d = point.distance(center);
-            if (d > dMax) {
-                farthest = point;
-                dMax     = d;
-            }
-        }
-
-        return farthest;
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/enclosing/package-info.java b/src/main/java/org/apache/commons/math4/geometry/enclosing/package-info.java
deleted file mode 100644
index 7456a41..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/enclosing/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-/**
- *
- * <p>
- * This package provides interfaces and classes related to the smallest enclosing ball problem.
- * </p>
- *
- */
-package org.apache.commons.math4.geometry.enclosing;
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
deleted file mode 100644
index de3f7d2..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1D.java
+++ /dev/null
@@ -1,387 +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 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 extends Vector1D implements Point<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 #Cartesian1D(double)
-     */
-    @Override
-    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 Cartesian1D, or
-     *         not equal to this Cartesian1D 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);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Euclidean1D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Euclidean1D.java
deleted file mode 100644
index 91e97f5..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Euclidean1D.java
+++ /dev/null
@@ -1,102 +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.io.Serializable;
-
-import org.apache.commons.math4.exception.MathUnsupportedOperationException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Space;
-
-/**
- * This class implements a one-dimensional space.
- * @since 3.0
- */
-public class Euclidean1D implements Serializable, Space {
-
-    /** Serializable version identifier. */
-    private static final long serialVersionUID = -1178039568877797126L;
-
-    /** Private constructor for the singleton.
-     */
-    private Euclidean1D() {
-    }
-
-    /** Get the unique instance.
-     * @return the unique instance
-     */
-    public static Euclidean1D getInstance() {
-        return LazyHolder.INSTANCE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 1;
-    }
-
-    /** {@inheritDoc}
-     * <p>
-     * As the 1-dimension Euclidean space does not have proper sub-spaces,
-     * this method always throws a {@link NoSubSpaceException}
-     * </p>
-     * @return nothing
-     * @throws NoSubSpaceException in all cases
-     */
-    @Override
-    public Space getSubSpace() throws NoSubSpaceException {
-        throw new NoSubSpaceException();
-    }
-
-    // CHECKSTYLE: stop HideUtilityClassConstructor
-    /** Holder for the instance.
-     * <p>We use here the Initialization On Demand Holder Idiom.</p>
-     */
-    private static class LazyHolder {
-        /** Cached field instance. */
-        private static final Euclidean1D INSTANCE = new Euclidean1D();
-    }
-    // CHECKSTYLE: resume HideUtilityClassConstructor
-
-    /** Handle deserialization of the singleton.
-     * @return the singleton instance
-     */
-    private Object readResolve() {
-        // return the singleton instance
-        return LazyHolder.INSTANCE;
-    }
-
-    /** Specialized exception for inexistent sub-space.
-     * <p>
-     * This exception is thrown when attempting to get the sub-space of a one-dimensional space
-     * </p>
-     */
-    public static class NoSubSpaceException extends MathUnsupportedOperationException {
-
-        /** Serializable UID. */
-        private static final long serialVersionUID = 20140225L;
-
-        /** Simple constructor.
-         */
-        public NoSubSpaceException() {
-            super(LocalizedFormats.NOT_SUPPORTED_IN_DIMENSION_N, 1);
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Interval.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Interval.java
deleted file mode 100644
index 87dbba1..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Interval.java
+++ /dev/null
@@ -1,99 +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 org.apache.commons.math4.geometry.partitioning.Region.Location;
-import org.apache.commons.math4.exception.NumberIsTooSmallException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-
-
-/** This class represents a 1D interval.
- * @see IntervalsSet
- * @since 3.0
- */
-public class Interval {
-
-    /** The lower bound of the interval. */
-    private final double lower;
-
-    /** The upper bound of the interval. */
-    private final double upper;
-
-    /** Simple constructor.
-     * @param lower lower bound of the interval
-     * @param upper upper bound of the interval
-     */
-    public Interval(final double lower, final double upper) {
-        if (upper < lower) {
-            throw new NumberIsTooSmallException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
-                                                upper, lower, true);
-        }
-        this.lower = lower;
-        this.upper = upper;
-    }
-
-    /** Get the lower bound of the interval.
-     * @return lower bound of the interval
-     * @since 3.1
-     */
-    public double getInf() {
-        return lower;
-    }
-
-    /** Get the upper bound of the interval.
-     * @return upper bound of the interval
-     * @since 3.1
-     */
-    public double getSup() {
-        return upper;
-    }
-
-    /** Get the size of the interval.
-     * @return size of the interval
-     * @since 3.1
-     */
-    public double getSize() {
-        return upper - lower;
-    }
-
-    /** Get the barycenter of the interval.
-     * @return barycenter of the interval
-     * @since 3.1
-     */
-    public double getBarycenter() {
-        return 0.5 * (lower + upper);
-    }
-
-    /** Check a point with respect to the interval.
-     * @param point point to check
-     * @param tolerance tolerance below which points are considered to
-     * belong to the boundary
-     * @return a code representing the point status: either {@link
-     * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY}
-     * @since 3.1
-     */
-    public Location checkPoint(final double point, final double tolerance) {
-        if (point < lower - tolerance || point > upper + tolerance) {
-            return Location.OUTSIDE;
-        } else if (point > lower + tolerance && point < upper - tolerance) {
-            return Location.INSIDE;
-        } else {
-            return Location.BOUNDARY;
-        }
-    }
-
-}
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
deleted file mode 100644
index 2c50558..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
+++ /dev/null
@@ -1,627 +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.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.partitioning.AbstractRegion;
-import org.apache.commons.math4.geometry.partitioning.BSPTree;
-import org.apache.commons.math4.geometry.partitioning.BoundaryProjection;
-import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
-import org.apache.commons.numbers.core.Precision;
-
-/** This class represents a 1D region: a set of intervals.
- * @since 3.0
- */
-public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> implements Iterable<double[]> {
-
-    /** Build an intervals set representing the whole real line.
-     * @param tolerance tolerance below which points are considered identical.
-     * @since 3.3
-     */
-    public IntervalsSet(final double tolerance) {
-        super(tolerance);
-    }
-
-    /** Build an intervals set corresponding to a single interval.
-     * @param lower lower bound of the interval, must be lesser or equal
-     * to {@code upper} (may be {@code Double.NEGATIVE_INFINITY})
-     * @param upper upper bound of the interval, must be greater or equal
-     * to {@code lower} (may be {@code Double.POSITIVE_INFINITY})
-     * @param tolerance tolerance below which points are considered identical.
-     * @since 3.3
-     */
-    public IntervalsSet(final double lower, final double upper, final double tolerance) {
-        super(buildTree(lower, upper, tolerance), tolerance);
-    }
-
-    /** Build an intervals set from an inside/outside BSP tree.
-     * <p>The leaf nodes of the BSP tree <em>must</em> have a
-     * {@code Boolean} attribute representing the inside status of
-     * the corresponding cell (true for inside cells, false for outside
-     * cells). In order to avoid building too many small objects, it is
-     * recommended to use the predefined constants
-     * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p>
-     * @param tree inside/outside BSP tree representing the intervals set
-     * @param tolerance tolerance below which points are considered identical.
-     * @since 3.3
-     */
-    public IntervalsSet(final BSPTree<Euclidean1D> tree, final double tolerance) {
-        super(tree, tolerance);
-    }
-
-    /** Build an intervals set from a Boundary REPresentation (B-rep).
-     * <p>The boundary is provided as a collection of {@link
-     * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the
-     * interior part of the region on its minus side and the exterior on
-     * its plus side.</p>
-     * <p>The boundary elements can be in any order, and can form
-     * several non-connected sets (like for example polygons with holes
-     * or a set of disjoints polyhedrons considered as a whole). In
-     * fact, the elements do not even need to be connected together
-     * (their topological connections are not used here). However, if the
-     * boundary does not really separate an inside open from an outside
-     * open (open having here its topological meaning), then subsequent
-     * calls to the {@link
-     * org.apache.commons.math4.geometry.partitioning.Region#checkPoint(org.apache.commons.math4.geometry.Point)
-     * checkPoint} method will not be meaningful anymore.</p>
-     * <p>If the boundary is empty, the region will represent the whole
-     * space.</p>
-     * @param boundary collection of boundary elements
-     * @param tolerance tolerance below which points are considered identical.
-     * @since 3.3
-     */
-    public IntervalsSet(final Collection<SubHyperplane<Euclidean1D>> boundary,
-                        final double tolerance) {
-        super(boundary, tolerance);
-    }
-
-    /** Build an inside/outside tree representing a single interval.
-     * @param lower lower bound of the interval, must be lesser or equal
-     * to {@code upper} (may be {@code Double.NEGATIVE_INFINITY})
-     * @param upper upper bound of the interval, must be greater or equal
-     * to {@code lower} (may be {@code Double.POSITIVE_INFINITY})
-     * @param tolerance tolerance below which points are considered identical.
-     * @return the built tree
-     */
-    private static BSPTree<Euclidean1D> buildTree(final double lower, final double upper,
-                                                  final double tolerance) {
-        if (Double.isInfinite(lower) && (lower < 0)) {
-            if (Double.isInfinite(upper) && (upper > 0)) {
-                // the tree must cover the whole real line
-                return new BSPTree<>(Boolean.TRUE);
-            }
-            // the tree must be open on the negative infinity side
-            final SubHyperplane<Euclidean1D> upperCut =
-                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 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,
-                                            new BSPTree<Euclidean1D>(Boolean.FALSE),
-                                            new BSPTree<Euclidean1D>(Boolean.TRUE),
-                                            null);
-        }
-
-        // the tree must be bounded on the two sides
-        final SubHyperplane<Euclidean1D> upperCut =
-            new OrientedPoint(new Cartesian1D(upper), true, tolerance).wholeHyperplane();
-        return new BSPTree<>(lowerCut,
-                                        new BSPTree<Euclidean1D>(Boolean.FALSE),
-                                        new BSPTree<>(upperCut,
-                                                                 new BSPTree<Euclidean1D>(Boolean.FALSE),
-                                                                 new BSPTree<Euclidean1D>(Boolean.TRUE),
-                                                                 null),
-                                        null);
-
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IntervalsSet buildNew(final BSPTree<Euclidean1D> tree) {
-        return new IntervalsSet(tree, getTolerance());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void computeGeometricalProperties() {
-        if (getTree(false).getCut() == null) {
-            setBarycenter((Point<Euclidean1D>) Cartesian1D.NaN);
-            setSize(((Boolean) getTree(false).getAttribute()) ? Double.POSITIVE_INFINITY : 0);
-        } else {
-            double size = 0.0;
-            double sum = 0.0;
-            for (final Interval interval : asList()) {
-                size += interval.getSize();
-                sum  += interval.getSize() * interval.getBarycenter();
-            }
-            setSize(size);
-            if (Double.isInfinite(size)) {
-                setBarycenter((Point<Euclidean1D>) Cartesian1D.NaN);
-            } else if (size >= Precision.SAFE_MIN) {
-                setBarycenter((Point<Euclidean1D>) new Cartesian1D(sum / size));
-            } else {
-                setBarycenter((Point<Euclidean1D>) ((OrientedPoint) getTree(false).getCut().getHyperplane()).getLocation());
-            }
-        }
-    }
-
-    /** Get the lowest value belonging to the instance.
-     * @return lowest value belonging to the instance
-     * ({@code Double.NEGATIVE_INFINITY} if the instance doesn't
-     * have any low bound, {@code Double.POSITIVE_INFINITY} if the
-     * instance is empty)
-     */
-    public double getInf() {
-        BSPTree<Euclidean1D> node = getTree(false);
-        double  inf  = Double.POSITIVE_INFINITY;
-        while (node.getCut() != null) {
-            final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane();
-            inf  = op.getLocation().getX();
-            node = op.isDirect() ? node.getMinus() : node.getPlus();
-        }
-        return ((Boolean) node.getAttribute()) ? Double.NEGATIVE_INFINITY : inf;
-    }
-
-    /** Get the highest value belonging to the instance.
-     * @return highest value belonging to the instance
-     * ({@code Double.POSITIVE_INFINITY} if the instance doesn't
-     * have any high bound, {@code Double.NEGATIVE_INFINITY} if the
-     * instance is empty)
-     */
-    public double getSup() {
-        BSPTree<Euclidean1D> node = getTree(false);
-        double  sup  = Double.NEGATIVE_INFINITY;
-        while (node.getCut() != null) {
-            final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane();
-            sup  = op.getLocation().getX();
-            node = op.isDirect() ? node.getPlus() : node.getMinus();
-        }
-        return ((Boolean) node.getAttribute()) ? Double.POSITIVE_INFINITY : sup;
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public BoundaryProjection<Euclidean1D> projectToBoundary(final Point<Euclidean1D> point) {
-
-        // get position of test point
-        final double x = ((Cartesian1D) point).getX();
-
-        double previous = Double.NEGATIVE_INFINITY;
-        for (final double[] a : this) {
-            if (x < a[0]) {
-                // the test point lies between the previous and the current intervals
-                // offset will be positive
-                final double previousOffset = x - previous;
-                final double currentOffset  = a[0] - x;
-                if (previousOffset < currentOffset) {
-                    return new BoundaryProjection<>(point, finiteOrNullPoint(previous), previousOffset);
-                } else {
-                    return new BoundaryProjection<>(point, finiteOrNullPoint(a[0]), currentOffset);
-                }
-            } else if (x <= a[1]) {
-                // the test point lies within the current interval
-                // offset will be negative
-                final double offset0 = a[0] - x;
-                final double offset1 = x - a[1];
-                if (offset0 < offset1) {
-                    return new BoundaryProjection<>(point, finiteOrNullPoint(a[1]), offset1);
-                } else {
-                    return new BoundaryProjection<>(point, finiteOrNullPoint(a[0]), offset0);
-                }
-            }
-            previous = a[1];
-        }
-
-        // the test point if past the last sub-interval
-        return new BoundaryProjection<>(point, finiteOrNullPoint(previous), x - previous);
-
-    }
-
-    /** Build a finite point.
-     * @param x abscissa of the point
-     * @return a new point for finite abscissa, null otherwise
-     */
-    private Cartesian1D finiteOrNullPoint(final double x) {
-        return Double.isInfinite(x) ? null : new Cartesian1D(x);
-    }
-
-    /** Build an ordered list of intervals representing the instance.
-     * <p>This method builds this intervals set as an ordered list of
-     * {@link Interval Interval} elements. If the intervals set has no
-     * lower limit, the first interval will have its low bound equal to
-     * {@code Double.NEGATIVE_INFINITY}. If the intervals set has
-     * no upper limit, the last interval will have its upper bound equal
-     * to {@code Double.POSITIVE_INFINITY}. An empty tree will
-     * build an empty list while a tree representing the whole real line
-     * will build a one element list with both bounds being
-     * infinite.</p>
-     * @return a new ordered list containing {@link Interval Interval}
-     * elements
-     */
-    public List<Interval> asList() {
-        final List<Interval> list = new ArrayList<>();
-        for (final double[] a : this) {
-            list.add(new Interval(a[0], a[1]));
-        }
-        return list;
-    }
-
-    /** Get the first leaf node of a tree.
-     * @param root tree root
-     * @return first leaf node
-     */
-    private BSPTree<Euclidean1D> getFirstLeaf(final BSPTree<Euclidean1D> root) {
-
-        if (root.getCut() == null) {
-            return root;
-        }
-
-        // find the smallest internal node
-        BSPTree<Euclidean1D> smallest = null;
-        for (BSPTree<Euclidean1D> n = root; n != null; n = previousInternalNode(n)) {
-            smallest = n;
-        }
-
-        return leafBefore(smallest);
-
-    }
-
-    /** Get the node corresponding to the first interval boundary.
-     * @return smallest internal node,
-     * or null if there are no internal nodes (i.e. the set is either empty or covers the real line)
-     */
-    private BSPTree<Euclidean1D> getFirstIntervalBoundary() {
-
-        // start search at the tree root
-        BSPTree<Euclidean1D> node = getTree(false);
-        if (node.getCut() == null) {
-            return null;
-        }
-
-        // walk tree until we find the smallest internal node
-        node = getFirstLeaf(node).getParent();
-
-        // walk tree until we find an interval boundary
-        while (node != null && !(isIntervalStart(node) || isIntervalEnd(node))) {
-            node = nextInternalNode(node);
-        }
-
-        return node;
-
-    }
-
-    /** Check if an internal node corresponds to the start abscissa of an interval.
-     * @param node internal node to check
-     * @return true if the node corresponds to the start abscissa of an interval
-     */
-    private boolean isIntervalStart(final BSPTree<Euclidean1D> node) {
-
-        if ((Boolean) leafBefore(node).getAttribute()) {
-            // it has an inside cell before it, it may end an interval but not start it
-            return false;
-        }
-
-        if (!(Boolean) leafAfter(node).getAttribute()) {
-            // it has an outside cell after it, it is a dummy cut away from real intervals
-            return false;
-        }
-
-        // the cell has an outside before and an inside after it
-        // it is the start of an interval
-        return true;
-
-    }
-
-    /** Check if an internal node corresponds to the end abscissa of an interval.
-     * @param node internal node to check
-     * @return true if the node corresponds to the end abscissa of an interval
-     */
-    private boolean isIntervalEnd(final BSPTree<Euclidean1D> node) {
-
-        if (!(Boolean) leafBefore(node).getAttribute()) {
-            // it has an outside cell before it, it may start an interval but not end it
-            return false;
-        }
-
-        if ((Boolean) leafAfter(node).getAttribute()) {
-            // it has an inside cell after it, it is a dummy cut in the middle of an interval
-            return false;
-        }
-
-        // the cell has an inside before and an outside after it
-        // it is the end of an interval
-        return true;
-
-    }
-
-    /** Get the next internal node.
-     * @param node current internal node
-     * @return next internal node in ascending order, or null
-     * if this is the last internal node
-     */
-    private BSPTree<Euclidean1D> nextInternalNode(BSPTree<Euclidean1D> node) {
-
-        if (childAfter(node).getCut() != null) {
-            // the next node is in the sub-tree
-            return leafAfter(node).getParent();
-        }
-
-        // there is nothing left deeper in the tree, we backtrack
-        while (isAfterParent(node)) {
-            node = node.getParent();
-        }
-        return node.getParent();
-
-    }
-
-    /** Get the previous internal node.
-     * @param node current internal node
-     * @return previous internal node in ascending order, or null
-     * if this is the first internal node
-     */
-    private BSPTree<Euclidean1D> previousInternalNode(BSPTree<Euclidean1D> node) {
-
-        if (childBefore(node).getCut() != null) {
-            // the next node is in the sub-tree
-            return leafBefore(node).getParent();
-        }
-
-        // there is nothing left deeper in the tree, we backtrack
-        while (isBeforeParent(node)) {
-            node = node.getParent();
-        }
-        return node.getParent();
-
-    }
-
-    /** Find the leaf node just before an internal node.
-     * @param node internal node at which the sub-tree starts
-     * @return leaf node just before the internal node
-     */
-    private BSPTree<Euclidean1D> leafBefore(BSPTree<Euclidean1D> node) {
-
-        node = childBefore(node);
-        while (node.getCut() != null) {
-            node = childAfter(node);
-        }
-
-        return node;
-
-    }
-
-    /** Find the leaf node just after an internal node.
-     * @param node internal node at which the sub-tree starts
-     * @return leaf node just after the internal node
-     */
-    private BSPTree<Euclidean1D> leafAfter(BSPTree<Euclidean1D> node) {
-
-        node = childAfter(node);
-        while (node.getCut() != null) {
-            node = childBefore(node);
-        }
-
-        return node;
-
-    }
-
-    /** Check if a node is the child before its parent in ascending order.
-     * @param node child node considered
-     * @return true is the node has a parent end is before it in ascending order
-     */
-    private boolean isBeforeParent(final BSPTree<Euclidean1D> node) {
-        final BSPTree<Euclidean1D> parent = node.getParent();
-        if (parent == null) {
-            return false;
-        } else {
-            return node == childBefore(parent);
-        }
-    }
-
-    /** Check if a node is the child after its parent in ascending order.
-     * @param node child node considered
-     * @return true is the node has a parent end is after it in ascending order
-     */
-    private boolean isAfterParent(final BSPTree<Euclidean1D> node) {
-        final BSPTree<Euclidean1D> parent = node.getParent();
-        if (parent == null) {
-            return false;
-        } else {
-            return node == childAfter(parent);
-        }
-    }
-
-    /** Find the child node just before an internal node.
-     * @param node internal node at which the sub-tree starts
-     * @return child node just before the internal node
-     */
-    private BSPTree<Euclidean1D> childBefore(BSPTree<Euclidean1D> node) {
-        if (isDirect(node)) {
-            // smaller abscissas are on minus side, larger abscissas are on plus side
-            return node.getMinus();
-        } else {
-            // smaller abscissas are on plus side, larger abscissas are on minus side
-            return node.getPlus();
-        }
-    }
-
-    /** Find the child node just after an internal node.
-     * @param node internal node at which the sub-tree starts
-     * @return child node just after the internal node
-     */
-    private BSPTree<Euclidean1D> childAfter(BSPTree<Euclidean1D> node) {
-        if (isDirect(node)) {
-            // smaller abscissas are on minus side, larger abscissas are on plus side
-            return node.getPlus();
-        } else {
-            // smaller abscissas are on plus side, larger abscissas are on minus side
-            return node.getMinus();
-        }
-    }
-
-    /** Check if an internal node has a direct oriented point.
-     * @param node internal node to check
-     * @return true if the oriented point is direct
-     */
-    private boolean isDirect(final BSPTree<Euclidean1D> node) {
-        return ((OrientedPoint) node.getCut().getHyperplane()).isDirect();
-    }
-
-    /** Get the abscissa of an internal node.
-     * @param node internal node to check
-     * @return abscissa
-     */
-    private double getAngle(final BSPTree<Euclidean1D> node) {
-        return ((OrientedPoint) node.getCut().getHyperplane()).getLocation().getX();
-    }
-
-    /** {@inheritDoc}
-     * <p>
-     * The iterator returns the limit values of sub-intervals in ascending order.
-     * </p>
-     * <p>
-     * The iterator does <em>not</em> support the optional {@code remove} operation.
-     * </p>
-     * @since 3.3
-     */
-    @Override
-    public Iterator<double[]> iterator() {
-        return new SubIntervalsIterator();
-    }
-
-    /** Local iterator for sub-intervals. */
-    private class SubIntervalsIterator implements Iterator<double[]> {
-
-        /** Current node. */
-        private BSPTree<Euclidean1D> current;
-
-        /** Sub-interval no yet returned. */
-        private double[] pending;
-
-        /** Simple constructor.
-         */
-        SubIntervalsIterator() {
-
-            current = getFirstIntervalBoundary();
-
-            if (current == null) {
-                // all the leaf tree nodes share the same inside/outside status
-                if ((Boolean) getFirstLeaf(getTree(false)).getAttribute()) {
-                    // it is an inside node, it represents the full real line
-                    pending = new double[] {
-                        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY
-                    };
-                } else {
-                    pending = null;
-                }
-            } else if (isIntervalEnd(current)) {
-                // the first boundary is an interval end,
-                // so the first interval starts at infinity
-                pending = new double[] {
-                    Double.NEGATIVE_INFINITY, getAngle(current)
-                };
-            } else {
-                selectPending();
-            }
-        }
-
-        /** Walk the tree to select the pending sub-interval.
-         */
-        private void selectPending() {
-
-            // look for the start of the interval
-            BSPTree<Euclidean1D> start = current;
-            while (start != null && !isIntervalStart(start)) {
-                start = nextInternalNode(start);
-            }
-
-            if (start == null) {
-                // we have exhausted the iterator
-                current = null;
-                pending = null;
-                return;
-            }
-
-            // look for the end of the interval
-            BSPTree<Euclidean1D> end = start;
-            while (end != null && !isIntervalEnd(end)) {
-                end = nextInternalNode(end);
-            }
-
-            if (end != null) {
-
-                // we have identified the interval
-                pending = new double[] {
-                    getAngle(start), getAngle(end)
-                };
-
-                // prepare search for next interval
-                current = end;
-
-            } else {
-
-                // the final interval is open toward infinity
-                pending = new double[] {
-                    getAngle(start), Double.POSITIVE_INFINITY
-                };
-
-                // there won't be any other intervals
-                current = null;
-
-            }
-
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean hasNext() {
-            return pending != null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public double[] next() {
-            if (pending == null) {
-                throw new NoSuchElementException();
-            }
-            final double[] next = pending;
-            selectPending();
-            return next;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-}
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
deleted file mode 100644
index f917bcc..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/OrientedPoint.java
+++ /dev/null
@@ -1,146 +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 org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-
-/** This class represents a 1D oriented hyperplane.
- * <p>An hyperplane in 1D is a simple point, its orientation being a
- * boolean.</p>
- * <p>Instances of this class are guaranteed to be immutable.</p>
- * @since 3.0
- */
-public class OrientedPoint implements Hyperplane<Euclidean1D> {
-
-    /** Vector location. */
-    private final Cartesian1D location;
-
-    /** Orientation. */
-    private boolean direct;
-
-    /** Tolerance below which points are considered to belong to the hyperplane. */
-    private final double tolerance;
-
-    /** Simple constructor.
-     * @param location location of the hyperplane
-     * @param direct if true, the plus side of the hyperplane is towards
-     * abscissas greater than {@code location}
-     * @param tolerance tolerance below which points are considered to belong to the hyperplane
-     * @since 3.3
-     */
-    public OrientedPoint(final Cartesian1D location, final boolean direct, final double tolerance) {
-        this.location  = location;
-        this.direct    = direct;
-        this.tolerance = tolerance;
-    }
-
-    /** Copy the instance.
-     * <p>Since instances are immutable, this method directly returns
-     * the instance.</p>
-     * @return the instance itself
-     */
-    @Override
-    public OrientedPoint copySelf() {
-        return this;
-    }
-
-    /** Get the offset (oriented distance) of a vector.
-     * @param vector vector to check
-     * @return offset of the vector
-     */
-    public double getOffset(Vector<Euclidean1D> vector) {
-        return getOffset((Point<Euclidean1D>) vector);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getOffset(final Point<Euclidean1D> point) {
-        final double delta = ((Cartesian1D) point).getX() - location.getX();
-        return direct ? delta : -delta;
-    }
-
-    /** Build a region covering the whole hyperplane.
-     * <p>Since this class represent zero dimension spaces which does
-     * not have lower dimension sub-spaces, this method returns a dummy
-     * implementation of a {@link
-     * org.apache.commons.math4.geometry.partitioning.SubHyperplane SubHyperplane}.
-     * This implementation is only used to allow the {@link
-     * org.apache.commons.math4.geometry.partitioning.SubHyperplane
-     * SubHyperplane} class implementation to work properly, it should
-     * <em>not</em> be used otherwise.</p>
-     * @return a dummy sub hyperplane
-     */
-    @Override
-    public SubOrientedPoint wholeHyperplane() {
-        return new SubOrientedPoint(this, null);
-    }
-
-    /** Build a region covering the whole space.
-     * @return a region containing the instance (really an {@link
-     * IntervalsSet IntervalsSet} instance)
-     */
-    @Override
-    public IntervalsSet wholeSpace() {
-        return new IntervalsSet(tolerance);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean sameOrientationAs(final Hyperplane<Euclidean1D> other) {
-        return !(direct ^ ((OrientedPoint) other).direct);
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public Point<Euclidean1D> project(Point<Euclidean1D> point) {
-        return location;
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public double getTolerance() {
-        return tolerance;
-    }
-
-    /** Get the hyperplane location on the real line.
-     * @return the hyperplane location
-     */
-    public Cartesian1D getLocation() {
-        return location;
-    }
-
-    /** Check if the hyperplane orientation is direct.
-     * @return true if the plus side of the hyperplane is towards
-     * abscissae greater than hyperplane location
-     */
-    public boolean isDirect() {
-        return direct;
-    }
-
-    /** Revert the instance.
-     */
-    public void revertSelf() {
-        direct = !direct;
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
deleted file mode 100644
index b6c90e9..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
+++ /dev/null
@@ -1,77 +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 org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-import org.apache.commons.math4.geometry.partitioning.Region;
-
-/** This class represents sub-hyperplane for {@link OrientedPoint}.
- * <p>An hyperplane in 1D is a simple point, its orientation being a
- * boolean.</p>
- * <p>Instances of this class are guaranteed to be immutable.</p>
- * @since 3.0
- */
-public class SubOrientedPoint extends AbstractSubHyperplane<Euclidean1D, Euclidean1D> {
-
-    /** Simple constructor.
-     * @param hyperplane underlying hyperplane
-     * @param remainingRegion remaining region of the hyperplane
-     */
-    public SubOrientedPoint(final Hyperplane<Euclidean1D> hyperplane,
-                            final Region<Euclidean1D> remainingRegion) {
-        super(hyperplane, remainingRegion);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getSize() {
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isEmpty() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected AbstractSubHyperplane<Euclidean1D, Euclidean1D> buildNew(final Hyperplane<Euclidean1D> hyperplane,
-                                                                       final Region<Euclidean1D> remainingRegion) {
-        return new SubOrientedPoint(hyperplane, remainingRegion);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public SplitSubHyperplane<Euclidean1D> split(final Hyperplane<Euclidean1D> hyperplane) {
-        final OrientedPoint thisHyperplane = (OrientedPoint) getHyperplane();
-        final double global = hyperplane.getOffset(thisHyperplane.getLocation());
-
-        // use the tolerance value from our parent hyperplane to determine equality
-        final double tolerance = thisHyperplane.getTolerance();
-
-        if (global < -tolerance) {
-            return new SplitSubHyperplane<Euclidean1D>(null, this);
-        } else if (global > tolerance) {
-            return new SplitSubHyperplane<Euclidean1D>(this, null);
-        } else {
-            return new SplitSubHyperplane<Euclidean1D>(null, null);
-        }
-    }
-
-}
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 7411dd6..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1D.java
+++ /dev/null
@@ -1,33 +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 org.apache.commons.math4.geometry.Vector;
-
-/** This class represents a 1D vector.
- *
- * @since 3.0
- */
-public abstract class Vector1D implements Vector<Euclidean1D> {
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see Cartesian1D#Cartesian1D(double)
-     */
-    public abstract double getX();
-
-}
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
deleted file mode 100644
index 911d6f4..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/Vector1DFormat.java
+++ /dev/null
@@ -1,135 +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.FieldPosition;
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-import org.apache.commons.math4.exception.MathParseException;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.geometry.VectorFormat;
-import org.apache.commons.math4.util.CompositeFormat;
-
-/**
- * Formats a 1D vector in components list format "{x}".
- * <p>The prefix and suffix "{" and "}" can be replaced by
- * any user-defined strings. The number format for components can be configured.</p>
- * <p>White space is ignored at parse time, even if it is in the prefix, suffix
- * or separator specifications. So even if the default separator does include a space
- * character that is used at format time, both input string "{1}" and
- * " { 1 } " will be parsed without error and the same vector will be
- * returned. In the second case, however, the parse position after parsing will be
- * just after the closing curly brace, i.e. just before the trailing space.</p>
- * <p><b>Note:</b> using "," as a separator may interfere with the grouping separator
- * of the default {@link NumberFormat} for the current locale. Thus it is advised
- * to use a {@link NumberFormat} instance with disabled grouping in such a case.</p>
- *
- * @since 3.0
- */
-public class Vector1DFormat extends VectorFormat<Euclidean1D> {
-
-    /**
-     * Create an instance with default settings.
-     * <p>The instance uses the default prefix, suffix and separator:
-     * "{", "}", and "; " and the default number format for components.</p>
-     */
-    public Vector1DFormat() {
-        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
-              CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with a custom number format for components.
-     * @param format the custom format for components.
-     */
-    public Vector1DFormat(final NumberFormat format) {
-        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix and separator.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     */
-    public Vector1DFormat(final String prefix, final String suffix) {
-        super(prefix, suffix, DEFAULT_SEPARATOR, CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix, separator and format
-     * for components.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     * @param format the custom format for components.
-     */
-    public Vector1DFormat(final String prefix, final String suffix,
-                         final NumberFormat format) {
-        super(prefix, suffix, DEFAULT_SEPARATOR, format);
-    }
-
-    /**
-     * Returns the default 1D vector format for the current locale.
-     * @return the default 1D vector format.
-     */
-    public static Vector1DFormat getInstance() {
-        return getInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns the default 1D vector format for the given locale.
-     * @param locale the specific locale used by the format.
-     * @return the 1D vector format specific to the given locale.
-     */
-    public static Vector1DFormat getInstance(final Locale locale) {
-        return new Vector1DFormat(CompositeFormat.getDefaultNumberFormat(locale));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public StringBuffer format(final Vector<Euclidean1D> vector, final StringBuffer toAppendTo,
-                               final FieldPosition pos) {
-        final Vector1D p1 = (Vector1D) vector;
-        return format(toAppendTo, pos, p1.getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D parse(final String source) throws MathParseException {
-        ParsePosition parsePosition = new ParsePosition(0);
-        Vector1D result = parse(source, parsePosition);
-        if (parsePosition.getIndex() == 0) {
-            throw new MathParseException(source,
-                                         parsePosition.getErrorIndex(),
-                                         Vector1D.class);
-        }
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D parse(final String source, final ParsePosition pos) {
-        final double[] coordinates = parseCoordinates(1, source, pos);
-        if (coordinates == null) {
-            return null;
-        }
-        return new Cartesian1D(coordinates[0]);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/package-info.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/package-info.java
deleted file mode 100644
index 9ec9d8b..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-/**
- *
- * <p>
- * This package provides basic 1D geometry components.
- * </p>
- *
- */
-package org.apache.commons.math4.geometry.euclidean.oned;
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
deleted file mode 100644
index 774a5ba..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Cartesian3D.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.numbers.arrays.LinearCombination;
-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.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 extends Vector3D implements Serializable, Point<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 = LinearCombination.value(a1, u1.x, a2, u2.x);
-        this.y = LinearCombination.value(a1, u1.y, a2, u2.y);
-        this.z = LinearCombination.value(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 = LinearCombination.value(a1, u1.x, a2, u2.x, a3, u3.x);
-        this.y = LinearCombination.value(a1, u1.y, a2, u2.y, a3, u3.y);
-        this.z = LinearCombination.value(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 = LinearCombination.value(a1, u1.x, a2, u2.x, a3, u3.x, a4, u4.x);
-        this.y = LinearCombination.value(a1, u1.y, a2, u2.y, a3, u3.y, a4, u4.y);
-        this.z = LinearCombination.value(a1, u1.z, a2, u2.z, a3, u3.z, a4, u4.z);
-    }
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see #Cartesian3D(double, double, double)
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** Get the ordinate of the vector.
-     * @return ordinate of the vector
-     * @see #Cartesian3D(double, double, double)
-     */
-    public double getY() {
-        return y;
-    }
-
-    /** Get the height of the vector.
-     * @return height of the vector
-     * @see #Cartesian3D(double, double, double)
-     */
-    public double getZ() {
-        return z;
-    }
-
-    /** Get the vector coordinates as a dimension 3 array.
-     * @return vector coordinates
-     * @see #Cartesian3D(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 #Cartesian3D(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 #Cartesian3D(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>
-     *   Cartesian3D k = u.normalize();
-     *   Cartesian3D i = k.orthogonal();
-     *   Cartesian3D j = Cartesian3D.crossProduct(k, i);
-     * </code></pre>
-     * @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 Cartesian3D, or
-     *         not equal to this Cartesian3D 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 LinearCombination#value(double, double, double, double, double, double)
-     */
-    @Override
-    public double dotProduct(final Vector<Euclidean3D> v) {
-        final Cartesian3D v3 = (Cartesian3D) v;
-        return LinearCombination.value(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 Cartesian3D
-     */
-    public Cartesian3D crossProduct(final Vector<Euclidean3D> v) {
-        final Cartesian3D v3 = (Cartesian3D) v;
-        return new Cartesian3D(LinearCombination.value(y, v3.z, -z, v3.y),
-                            LinearCombination.value(z, v3.x, -x, v3.z),
-                            LinearCombination.value(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);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Euclidean3D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Euclidean3D.java
deleted file mode 100644
index cde306f..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Euclidean3D.java
+++ /dev/null
@@ -1,76 +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 org.apache.commons.math4.geometry.Space;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-
-/**
- * This class implements a three-dimensional space.
- * @since 3.0
- */
-public class Euclidean3D implements Serializable, Space {
-
-    /** Serializable version identifier. */
-    private static final long serialVersionUID = 6249091865814886817L;
-
-    /** Private constructor for the singleton.
-     */
-    private Euclidean3D() {
-    }
-
-    /** Get the unique instance.
-     * @return the unique instance
-     */
-    public static Euclidean3D getInstance() {
-        return LazyHolder.INSTANCE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Euclidean2D getSubSpace() {
-        return Euclidean2D.getInstance();
-    }
-
-    // CHECKSTYLE: stop HideUtilityClassConstructor
-    /** Holder for the instance.
-     * <p>We use here the Initialization On Demand Holder Idiom.</p>
-     */
-    private static class LazyHolder {
-        /** Cached field instance. */
-        private static final Euclidean3D INSTANCE = new Euclidean3D();
-    }
-    // CHECKSTYLE: resume HideUtilityClassConstructor
-
-    /** Handle deserialization of the singleton.
-     * @return the singleton instance
-     */
-    private Object readResolve() {
-        // return the singleton instance
-        return LazyHolder.INSTANCE;
-    }
-
-}
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 d4c7a18..2ed4b59 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
@@ -19,6 +19,9 @@ package org.apache.commons.math4.geometry.euclidean.threed;
 
 import java.io.Serializable;
 
+import org.apache.commons.numbers.quaternion.Quaternion;
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
+import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
 import org.apache.commons.math4.Field;
 import org.apache.commons.math4.RealFieldElement;
 import org.apache.commons.math4.exception.MathArithmeticException;
@@ -28,7 +31,7 @@ import org.apache.commons.math4.util.FastMath;
 import org.apache.commons.math4.util.MathArrays;
 
 /**
- * This class is a re-implementation of {@link Rotation} using {@link RealFieldElement}.
+ * Implementation of rotation using {@link RealFieldElement}.
  * <p>Instance of this class are guaranteed to be immutable.</p>
  *
  * @param <T> the type of the field elements
@@ -820,8 +823,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_I);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_K);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_X);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Z);
                 if ((v2.getX().getReal() < -0.9999999999) || (v2.getX().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -836,8 +839,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_I);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_J);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_X);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Y);
                 if ((v2.getX().getReal() < -0.9999999999) || (v2.getX().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -852,8 +855,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_J);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_K);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Y);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Z);
                 if ((v2.getY().getReal() < -0.9999999999) || (v2.getY().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -868,8 +871,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_J);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_I);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Y);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_X);
                 if ((v2.getY().getReal() < -0.9999999999) || (v2.getY().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -884,8 +887,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_K);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_J);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Z);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Y);
                 if ((v2.getZ().getReal() < -0.9999999999) || (v2.getZ().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -900,8 +903,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_K);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_I);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Z);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_X);
                 if  ((v2.getZ().getReal() < -0.9999999999) || (v2.getZ().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(true);
                 }
@@ -916,8 +919,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_I);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_I);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_X);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_X);
                 if ((v2.getX().getReal() < -0.9999999999) || (v2.getX().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -932,8 +935,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_I);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_I);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_X);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_X);
                 if ((v2.getX().getReal() < -0.9999999999) || (v2.getX().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -948,8 +951,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_J);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_J);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Y);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Y);
                 if ((v2.getY().getReal() < -0.9999999999) || (v2.getY().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -964,8 +967,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_J);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_J);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Y);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Y);
                 if ((v2.getY().getReal() < -0.9999999999) || (v2.getY().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -980,8 +983,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_K);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_K);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Z);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Z);
                 if ((v2.getZ().getReal() < -0.9999999999) || (v2.getZ().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -996,8 +999,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
                 // (-r) (Cartesian3D.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(Cartesian3D.PLUS_K);
-                FieldVector3D<T> v2 = applyInverseTo(Cartesian3D.PLUS_K);
+                FieldVector3D<T> v1 = applyTo(Vector3D.Unit.PLUS_Z);
+                FieldVector3D<T> v2 = applyInverseTo(Vector3D.Unit.PLUS_Z);
                 if ((v2.getZ().getReal() < -0.9999999999) || (v2.getZ().getReal() > 0.9999999999)) {
                     throw new CardanEulerSingularityException(false);
                 }
@@ -1074,8 +1077,8 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
     /** Convert to a constant vector without derivatives.
      * @return a constant vector
      */
-    public Rotation toRotation() {
-        return new Rotation(q0.getReal(), q1.getReal(), q2.getReal(), q3.getReal(), false);
+    public QuaternionRotation toRotation() {
+        return QuaternionRotation.of(q0.getReal(), q1.getReal(), q2.getReal(), q3.getReal());
     }
 
     /** Apply the rotation to a vector.
@@ -1100,7 +1103,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 Cartesian3D u) {
+    public FieldVector3D<T> applyTo(final Vector3D u) {
 
         final double x = u.getX();
         final double y = u.getY();
@@ -1157,17 +1160,17 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return a new vector which is the image of u by the rotation
      */
-    public static <T extends RealFieldElement<T>> FieldVector3D<T> applyTo(final Rotation r, final FieldVector3D<T> u) {
-
+    public static <T extends RealFieldElement<T>> FieldVector3D<T> applyTo(final QuaternionRotation rot, final FieldVector3D<T> u) {
+        final Quaternion r = rot.getQuaternion();
         final T x = u.getX();
         final T y = u.getY();
         final T z = u.getZ();
 
-        final T s = x.multiply(r.getQ1()).add(y.multiply(r.getQ2())).add(z.multiply(r.getQ3()));
+        final T s = x.multiply(r.getX()).add(y.multiply(r.getY())).add(z.multiply(r.getZ()));
 
-        return new FieldVector3D<>(x.multiply(r.getQ0()).subtract(z.multiply(r.getQ2()).subtract(y.multiply(r.getQ3()))).multiply(r.getQ0()).add(s.multiply(r.getQ1())).multiply(2).subtract(x),
-                                    y.multiply(r.getQ0()).subtract(x.multiply(r.getQ3()).subtract(z.multiply(r.getQ1()))).multiply(r.getQ0()).add(s.multiply(r.getQ2())).multiply(2).subtract(y),
-                                    z.multiply(r.getQ0()).subtract(y.multiply(r.getQ1()).subtract(x.multiply(r.getQ2()))).multiply(r.getQ0()).add(s.multiply(r.getQ3())).multiply(2).subtract(z));
+        return new FieldVector3D<>(x.multiply(r.getW()).subtract(z.multiply(r.getY()).subtract(y.multiply(r.getZ()))).multiply(r.getW()).add(s.multiply(r.getX())).multiply(2).subtract(x),
+                                    y.multiply(r.getW()).subtract(x.multiply(r.getZ()).subtract(z.multiply(r.getX()))).multiply(r.getW()).add(s.multiply(r.getY())).multiply(2).subtract(y),
+                                    z.multiply(r.getW()).subtract(y.multiply(r.getX()).subtract(x.multiply(r.getY()))).multiply(r.getW()).add(s.multiply(r.getZ())).multiply(2).subtract(z));
 
     }
 
@@ -1194,7 +1197,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 Cartesian3D u) {
+    public FieldVector3D<T> applyInverseTo(final Vector3D u) {
 
         final double x = u.getX();
         final double y = u.getY();
@@ -1254,18 +1257,18 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return a new vector which such that u is its image by the rotation
      */
-    public static <T extends RealFieldElement<T>> FieldVector3D<T> applyInverseTo(final Rotation r, final FieldVector3D<T> u) {
-
+    public static <T extends RealFieldElement<T>> FieldVector3D<T> applyInverseTo(final QuaternionRotation rot, final FieldVector3D<T> u) {
+        final Quaternion r = rot.getQuaternion();
         final T x = u.getX();
         final T y = u.getY();
         final T z = u.getZ();
 
-        final T s  = x.multiply(r.getQ1()).add(y.multiply(r.getQ2())).add(z.multiply(r.getQ3()));
-        final double m0 = -r.getQ0();
+        final T s  = x.multiply(r.getX()).add(y.multiply(r.getY())).add(z.multiply(r.getZ()));
+        final double m0 = -r.getW();
 
-        return new FieldVector3D<>(x.multiply(m0).subtract(z.multiply(r.getQ2()).subtract(y.multiply(r.getQ3()))).multiply(m0).add(s.multiply(r.getQ1())).multiply(2).subtract(x),
-                                    y.multiply(m0).subtract(x.multiply(r.getQ3()).subtract(z.multiply(r.getQ1()))).multiply(m0).add(s.multiply(r.getQ2())).multiply(2).subtract(y),
-                                    z.multiply(m0).subtract(y.multiply(r.getQ1()).subtract(x.multiply(r.getQ2()))).multiply(m0).add(s.multiply(r.getQ3())).multiply(2).subtract(z));
+        return new FieldVector3D<>(x.multiply(m0).subtract(z.multiply(r.getY()).subtract(y.multiply(r.getZ()))).multiply(m0).add(s.multiply(r.getX())).multiply(2).subtract(x),
+                                    y.multiply(m0).subtract(x.multiply(r.getZ()).subtract(z.multiply(r.getX()))).multiply(m0).add(s.multiply(r.getY())).multiply(2).subtract(y),
+                                    z.multiply(m0).subtract(y.multiply(r.getX()).subtract(x.multiply(r.getY()))).multiply(m0).add(s.multiply(r.getZ())).multiply(2).subtract(z));
 
     }
 
@@ -1333,7 +1336,7 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @param r rotation to apply the rotation to
      * @return a new rotation which is the composition of r by the instance
      */
-    public FieldRotation<T> applyTo(final Rotation r) {
+    public FieldRotation<T> applyTo(final QuaternionRotation r) {
         return compose(r, RotationConvention.VECTOR_OPERATOR);
     }
 
@@ -1361,7 +1364,7 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @param convention convention to use for the semantics of the angle
      * @return a new rotation which is the composition of r by the instance
      */
-    public FieldRotation<T> compose(final Rotation r, final RotationConvention convention) {
+    public FieldRotation<T> compose(final QuaternionRotation r, final RotationConvention convention) {
         return convention == RotationConvention.VECTOR_OPERATOR ?
                              composeInternal(r) : applyTo(r, this);
     }
@@ -1371,11 +1374,12 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @return a new rotation which is the composition of r by the instance
      * using vector operator convention
      */
-    private FieldRotation<T> composeInternal(final Rotation r) {
-        return new FieldRotation<>(q0.multiply(r.getQ0()).subtract(q1.multiply(r.getQ1()).add(q2.multiply(r.getQ2())).add(q3.multiply(r.getQ3()))),
-                        q0.multiply(r.getQ1()).add(q1.multiply(r.getQ0())).add(q3.multiply(r.getQ2()).subtract(q2.multiply(r.getQ3()))),
-                        q0.multiply(r.getQ2()).add(q2.multiply(r.getQ0())).add(q1.multiply(r.getQ3()).subtract(q3.multiply(r.getQ1()))),
-                        q0.multiply(r.getQ3()).add(q3.multiply(r.getQ0())).add(q2.multiply(r.getQ1()).subtract(q1.multiply(r.getQ2()))),
+    private FieldRotation<T> composeInternal(final QuaternionRotation rot) {
+        final Quaternion r = rot.getQuaternion();
+        return new FieldRotation<>(q0.multiply(r.getW()).subtract(q1.multiply(r.getX()).add(q2.multiply(r.getY())).add(q3.multiply(r.getZ()))),
+                        q0.multiply(r.getX()).add(q1.multiply(r.getW())).add(q3.multiply(r.getY()).subtract(q2.multiply(r.getZ()))),
+                        q0.multiply(r.getY()).add(q2.multiply(r.getW())).add(q1.multiply(r.getZ()).subtract(q3.multiply(r.getX()))),
+                        q0.multiply(r.getZ()).add(q3.multiply(r.getW())).add(q2.multiply(r.getX()).subtract(q1.multiply(r.getY()))),
                         false);
     }
 
@@ -1390,11 +1394,12 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return a new rotation which is the composition of r by the instance
      */
-    public static <T extends RealFieldElement<T>> FieldRotation<T> applyTo(final Rotation r1, final FieldRotation<T> rInner) {
-        return new FieldRotation<>(rInner.q0.multiply(r1.getQ0()).subtract(rInner.q1.multiply(r1.getQ1()).add(rInner.q2.multiply(r1.getQ2())).add(rInner.q3.multiply(r1.getQ3()))),
-                                    rInner.q1.multiply(r1.getQ0()).add(rInner.q0.multiply(r1.getQ1())).add(rInner.q2.multiply(r1.getQ3()).subtract(rInner.q3.multiply(r1.getQ2()))),
-                                    rInner.q2.multiply(r1.getQ0()).add(rInner.q0.multiply(r1.getQ2())).add(rInner.q3.multiply(r1.getQ1()).subtract(rInner.q1.multiply(r1.getQ3()))),
-                                    rInner.q3.multiply(r1.getQ0()).add(rInner.q0.multiply(r1.getQ3())).add(rInner.q1.multiply(r1.getQ2()).subtract(rInner.q2.multiply(r1.getQ1()))),
+    public static <T extends RealFieldElement<T>> FieldRotation<T> applyTo(final QuaternionRotation rot1, final FieldRotation<T> rInner) {
+        final Quaternion r1 = rot1.getQuaternion();
+        return new FieldRotation<>(rInner.q0.multiply(r1.getW()).subtract(rInner.q1.multiply(r1.getX()).add(rInner.q2.multiply(r1.getY())).add(rInner.q3.multiply(r1.getZ()))),
+                                    rInner.q1.multiply(r1.getW()).add(rInner.q0.multiply(r1.getX())).add(rInner.q2.multiply(r1.getZ()).subtract(rInner.q3.multiply(r1.getY()))),
+                                    rInner.q2.multiply(r1.getW()).add(rInner.q0.multiply(r1.getY())).add(rInner.q3.multiply(r1.getX()).subtract(rInner.q1.multiply(r1.getZ()))),
+                                    rInner.q3.multiply(r1.getW()).add(rInner.q0.multiply(r1.getZ())).add(rInner.q1.multiply(r1.getY()).subtract(rInner.q2.multiply(r1.getX()))),
                                     false);
     }
 
@@ -1467,7 +1472,7 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @return a new rotation which is the composition of r by the inverse
      * of the instance
      */
-    public FieldRotation<T> applyInverseTo(final Rotation r) {
+    public FieldRotation<T> applyInverseTo(final QuaternionRotation r) {
         return composeInverse(r, RotationConvention.VECTOR_OPERATOR);
     }
 
@@ -1497,7 +1502,7 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @return a new rotation which is the composition of r by the inverse
      * of the instance
      */
-    public FieldRotation<T> composeInverse(final Rotation r, final RotationConvention convention) {
+    public FieldRotation<T> composeInverse(final QuaternionRotation r, final RotationConvention convention) {
         return convention == RotationConvention.VECTOR_OPERATOR ?
                              composeInverseInternal(r) : applyTo(r, revert());
     }
@@ -1508,11 +1513,12 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @return a new rotation which is the composition of r by the inverse
      * of the instance using vector operator convention
      */
-    private FieldRotation<T> composeInverseInternal(Rotation r) {
-        return new FieldRotation<>(q0.multiply(r.getQ0()).add(q1.multiply(r.getQ1()).add(q2.multiply(r.getQ2())).add(q3.multiply(r.getQ3()))).negate(),
-                                    q1.multiply(r.getQ0()).add(q3.multiply(r.getQ2()).subtract(q2.multiply(r.getQ3()))).subtract(q0.multiply(r.getQ1())),
-                                    q2.multiply(r.getQ0()).add(q1.multiply(r.getQ3()).subtract(q3.multiply(r.getQ1()))).subtract(q0.multiply(r.getQ2())),
-                                    q3.multiply(r.getQ0()).add(q2.multiply(r.getQ1()).subtract(q1.multiply(r.getQ2()))).subtract(q0.multiply(r.getQ3())),
+    private FieldRotation<T> composeInverseInternal(QuaternionRotation rot) {
+        final Quaternion r = rot.getQuaternion();
+        return new FieldRotation<>(q0.multiply(r.getW()).add(q1.multiply(r.getX()).add(q2.multiply(r.getY())).add(q3.multiply(r.getZ()))).negate(),
+                                    q1.multiply(r.getW()).add(q3.multiply(r.getY()).subtract(q2.multiply(r.getZ()))).subtract(q0.multiply(r.getX())),
+                                    q2.multiply(r.getW()).add(q1.multiply(r.getZ()).subtract(q3.multiply(r.getX()))).subtract(q0.multiply(r.getY())),
+                                    q3.multiply(r.getW()).add(q2.multiply(r.getX()).subtract(q1.multiply(r.getY()))).subtract(q0.multiply(r.getZ())),
                                     false);
     }
 
@@ -1529,11 +1535,12 @@ public class FieldRotation<T extends RealFieldElement<T>> implements Serializabl
      * @return a new rotation which is the composition of r by the inverse
      * of the instance
      */
-    public static <T extends RealFieldElement<T>> FieldRotation<T> applyInverseTo(final Rotation rOuter, final FieldRotation<T> rInner) {
-        return new FieldRotation<>(rInner.q0.multiply(rOuter.getQ0()).add(rInner.q1.multiply(rOuter.getQ1()).add(rInner.q2.multiply(rOuter.getQ2())).add(rInner.q3.multiply(rOuter.getQ3()))).negate(),
-                                    rInner.q0.multiply(rOuter.getQ1()).add(rInner.q2.multiply(rOuter.getQ3()).subtract(rInner.q3.multiply(rOuter.getQ2()))).subtract(rInner.q1.multiply(rOuter.getQ0())),
-                                    rInner.q0.multiply(rOuter.getQ2()).add(rInner.q3.multiply(rOuter.getQ1()).subtract(rInner.q1.multiply(rOuter.getQ3()))).subtract(rInner.q2.multiply(rOuter.getQ0())),
-                                    rInner.q0.multiply(rOuter.getQ3()).add(rInner.q1.multiply(rOuter.getQ2()).subtract(rInner.q2.multiply(rOuter.getQ1()))).subtract(rInner.q3.multiply(rOuter.getQ0())),
+    public static <T extends RealFieldElement<T>> FieldRotation<T> applyInverseTo(final QuaternionRotation rotOuter, final FieldRotation<T> rInner) {
+        final Quaternion rOuter = rotOuter.getQuaternion();
+        return new FieldRotation<>(rInner.q0.multiply(rOuter.getW()).add(rInner.q1.multiply(rOuter.getX()).add(rInner.q2.multiply(rOuter.getY())).add(rInner.q3.multiply(rOuter.getZ()))).negate(),
+                                    rInner.q0.multiply(rOuter.getX()).add(rInner.q2.multiply(rOuter.getZ()).subtract(rInner.q3.multiply(rOuter.getY()))).subtract(rInner.q1.multiply(rOuter.getW())),
+                                    rInner.q0.multiply(rOuter.getY()).add(rInner.q3.multiply(rOuter.getX()).subtract(rInner.q1.multiply(rOuter.getZ()))).subtract(rInner.q2.multiply(rOuter.getW())),
+                                    rInner.q0.multiply(rOuter.getZ()).add(rInner.q1.multiply(rOuter.getY()).subtract(rInner.q2.multiply(rOuter.getX()))).subtract(rInner.q3.multiply(rOuter.getW())),
                                     false);
     }
 
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
index 6543e00..74d4d6f 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
@@ -20,6 +20,7 @@ package org.apache.commons.math4.geometry.euclidean.threed;
 import java.io.Serializable;
 import java.text.NumberFormat;
 
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math4.RealFieldElement;
 import org.apache.commons.math4.exception.DimensionMismatchException;
 import org.apache.commons.math4.exception.MathArithmeticException;
@@ -28,7 +29,7 @@ import org.apache.commons.math4.util.FastMath;
 import org.apache.commons.math4.util.MathArrays;
 
 /**
- * This class is a re-implementation of {@link Cartesian3D} using {@link RealFieldElement}.
+ * This class is a re-implementation of {@link Vector3D} using {@link RealFieldElement}.
  * <p>Instance of this class are guaranteed to be immutable.</p>
  * @param <T> the type of the field elements
  * @since 3.2
@@ -110,7 +111,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param a scale factor
      * @param u base (unscaled) vector
      */
-    public FieldVector3D(final T a, final Cartesian3D u) {
+    public FieldVector3D(final T a, final Vector3D u) {
         this.x = a.multiply(u.getX());
         this.y = a.multiply(u.getY());
         this.z = a.multiply(u.getZ());
@@ -152,8 +153,8 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param a2 second scale factor
      * @param u2 second base (unscaled) vector
      */
-    public FieldVector3D(final T a1, final Cartesian3D u1,
-                         final T a2, final Cartesian3D u2) {
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2) {
         final T prototype = a1;
         this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2);
         this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2);
@@ -205,9 +206,9 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param a3 third scale factor
      * @param u3 third base (unscaled) vector
      */
-    public FieldVector3D(final T a1, final Cartesian3D u1,
-                         final T a2, final Cartesian3D u2,
-                         final T a3, final Cartesian3D u3) {
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2,
+                         final T a3, final Vector3D u3) {
         final T prototype = a1;
         this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2, u3.getX(), a3);
         this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2, u3.getY(), a3);
@@ -267,10 +268,10 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param a4 fourth scale factor
      * @param u4 fourth base (unscaled) vector
      */
-    public FieldVector3D(final T a1, final Cartesian3D u1,
-                         final T a2, final Cartesian3D u2,
-                         final T a3, final Cartesian3D u3,
-                         final T a4, final Cartesian3D u4) {
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2,
+                         final T a3, final Vector3D u3,
+                         final T a4, final Vector3D u4) {
         final T prototype = a1;
         this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2, u3.getX(), a3, u4.getX(), a4);
         this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2, u3.getY(), a3, u4.getY(), a4);
@@ -338,8 +339,8 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
     /** Convert to a constant vector without derivatives.
      * @return a constant vector
      */
-    public Cartesian3D toVector3D() {
-        return new Cartesian3D(x.getReal(), y.getReal(), z.getReal());
+    public Vector3D toVector3D() {
+        return Vector3D.of(x.getReal(), y.getReal(), z.getReal());
     }
 
     /** Get the L<sub>1</sub> norm for the vector.
@@ -415,7 +416,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to add
      * @return a new vector
      */
-    public FieldVector3D<T> add(final Cartesian3D v) {
+    public FieldVector3D<T> add(final Vector3D v) {
         return new FieldVector3D<>(x.add(v.getX()), y.add(v.getY()), z.add(v.getZ()));
     }
 
@@ -433,7 +434,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to add
      * @return a new vector
      */
-    public FieldVector3D<T> add(final T factor, final Cartesian3D v) {
+    public FieldVector3D<T> add(final T factor, final Vector3D v) {
         return new FieldVector3D<>(x.add(factor.multiply(v.getX())),
                                     y.add(factor.multiply(v.getY())),
                                     z.add(factor.multiply(v.getZ())));
@@ -453,7 +454,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to add
      * @return a new vector
      */
-    public FieldVector3D<T> add(final double factor, final Cartesian3D v) {
+    public FieldVector3D<T> add(final double factor, final Vector3D v) {
         return new FieldVector3D<>(x.add(factor * v.getX()),
                                     y.add(factor * v.getY()),
                                     z.add(factor * v.getZ()));
@@ -471,7 +472,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to subtract
      * @return a new vector
      */
-    public FieldVector3D<T> subtract(final Cartesian3D v) {
+    public FieldVector3D<T> subtract(final Vector3D v) {
         return new FieldVector3D<>(x.subtract(v.getX()), y.subtract(v.getY()), z.subtract(v.getZ()));
     }
 
@@ -489,7 +490,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to subtract
      * @return a new vector
      */
-    public FieldVector3D<T> subtract(final T factor, final Cartesian3D v) {
+    public FieldVector3D<T> subtract(final T factor, final Vector3D v) {
         return new FieldVector3D<>(x.subtract(factor.multiply(v.getX())),
                                     y.subtract(factor.multiply(v.getY())),
                                     z.subtract(factor.multiply(v.getZ())));
@@ -509,7 +510,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v vector to subtract
      * @return a new vector
      */
-    public FieldVector3D<T> subtract(final double factor, final Cartesian3D v) {
+    public FieldVector3D<T> subtract(final double factor, final Vector3D v) {
         return new FieldVector3D<>(x.subtract(factor * v.getX()),
                                     y.subtract(factor * v.getY()),
                                     z.subtract(factor * v.getZ()));
@@ -535,9 +536,9 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * following example shows how to build a frame having the k axis
      * aligned with the known vector u :
      * <pre><code>
-     *   Cartesian3D k = u.normalize();
-     *   Cartesian3D i = k.orthogonal();
-     *   Cartesian3D j = Cartesian3D.crossProduct(k, i);
+     *   Vector3D k = u.normalize();
+     *   Vector3D i = k.orthogonal();
+     *   Vector3D j = Vector3D.crossProduct(k, i);
      * </code></pre>
      * @return a new normalized vector orthogonal to the instance
      * @exception MathArithmeticException if the norm of the instance is null
@@ -610,10 +611,10 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return angular separation between v1 and v2
      * @exception MathArithmeticException if either vector has a null norm
      */
-    public static <T extends RealFieldElement<T>> T angle(final FieldVector3D<T> v1, final Cartesian3D v2)
+    public static <T extends RealFieldElement<T>> T angle(final FieldVector3D<T> v1, final Vector3D v2)
         throws MathArithmeticException {
 
-        final T normProduct = v1.getNorm().multiply(v2.getNorm());
+        final T normProduct = v1.getNorm().multiply(v2.norm());
         if (normProduct.getReal() == 0) {
             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
         }
@@ -646,7 +647,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return angular separation between v1 and v2
      * @exception MathArithmeticException if either vector has a null norm
      */
-    public static <T extends RealFieldElement<T>> T angle(final Cartesian3D v1, final FieldVector3D<T> v2)
+    public static <T extends RealFieldElement<T>> T angle(final Vector3D v1, final FieldVector3D<T> v2)
         throws MathArithmeticException {
         return angle(v2, v1);
     }
@@ -770,7 +771,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v second vector
      * @return the dot product this.v
      */
-    public T dotProduct(final Cartesian3D v) {
+    public T dotProduct(final Vector3D v) {
         return x.linearCombination(v.getX(), x, v.getY(), y, v.getZ(), z);
     }
 
@@ -788,7 +789,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v other vector
      * @return the cross product this ^ v as a new FieldVector3D
      */
-    public FieldVector3D<T> crossProduct(final Cartesian3D v) {
+    public FieldVector3D<T> crossProduct(final Vector3D v) {
         return new FieldVector3D<>(x.linearCombination(v.getZ(), y, -v.getY(), z),
                                     y.linearCombination(v.getX(), z, -v.getZ(), x),
                                     z.linearCombination(v.getY(), x, -v.getX(), y));
@@ -815,7 +816,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v second vector
      * @return the distance between the instance and p according to the L<sub>1</sub> norm
      */
-    public T distance1(final Cartesian3D v) {
+    public T distance1(final Vector3D v) {
         final T dx = x.subtract(v.getX()).abs();
         final T dy = y.subtract(v.getY()).abs();
         final T dz = z.subtract(v.getZ()).abs();
@@ -843,7 +844,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v second vector
      * @return the distance between the instance and p according to the L<sub>2</sub> norm
      */
-    public T distance(final Cartesian3D v) {
+    public T distance(final Vector3D v) {
         final T dx = x.subtract(v.getX());
         final T dy = y.subtract(v.getY());
         final T dz = z.subtract(v.getZ());
@@ -883,7 +884,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v second vector
      * @return the distance between the instance and p according to the L<sub>&infin;</sub> norm
      */
-    public T distanceInf(final Cartesian3D v) {
+    public T distanceInf(final Vector3D v) {
         final T dx = x.subtract(v.getX()).abs();
         final T dy = y.subtract(v.getY()).abs();
         final T dz = z.subtract(v.getZ()).abs();
@@ -923,7 +924,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param v second vector
      * @return the square of the distance between the instance and p
      */
-    public T distanceSq(final Cartesian3D v) {
+    public T distanceSq(final Vector3D v) {
         final T dx = x.subtract(v.getX());
         final T dy = y.subtract(v.getY());
         final T dz = z.subtract(v.getZ());
@@ -948,7 +949,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the dot product v1.v2
      */
     public static <T extends RealFieldElement<T>> T dotProduct(final FieldVector3D<T> v1,
-                                                                   final Cartesian3D v2) {
+                                                                   final Vector3D v2) {
         return v1.dotProduct(v2);
     }
 
@@ -958,7 +959,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the dot product v1.v2
      */
-    public static <T extends RealFieldElement<T>> T dotProduct(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> T dotProduct(final Vector3D v1,
                                                                    final FieldVector3D<T> v2) {
         return v2.dotProduct(v1);
     }
@@ -981,7 +982,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the cross product v1 ^ v2 as a new Vector
      */
     public static <T extends RealFieldElement<T>> FieldVector3D<T> crossProduct(final FieldVector3D<T> v1,
-                                                                                    final Cartesian3D v2) {
+                                                                                    final Vector3D v2) {
         return v1.crossProduct(v2);
     }
 
@@ -991,7 +992,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the cross product v1 ^ v2 as a new Vector
      */
-    public static <T extends RealFieldElement<T>> FieldVector3D<T> crossProduct(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> FieldVector3D<T> crossProduct(final Vector3D v1,
                                                                                     final FieldVector3D<T> v2) {
         return new FieldVector3D<>(v2.x.linearCombination(v1.getY(), v2.z, -v1.getZ(), v2.y),
                                     v2.y.linearCombination(v1.getZ(), v2.x, -v1.getX(), v2.z),
@@ -1022,7 +1023,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the distance between v1 and v2 according to the L<sub>1</sub> norm
      */
     public static <T extends RealFieldElement<T>> T distance1(final FieldVector3D<T> v1,
-                                                                  final Cartesian3D v2) {
+                                                                  final Vector3D v2) {
         return v1.distance1(v2);
     }
 
@@ -1035,7 +1036,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the distance between v1 and v2 according to the L<sub>1</sub> norm
      */
-    public static <T extends RealFieldElement<T>> T distance1(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> T distance1(final Vector3D v1,
                                                                   final FieldVector3D<T> v2) {
         return v2.distance1(v1);
     }
@@ -1064,7 +1065,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
      */
     public static <T extends RealFieldElement<T>> T distance(final FieldVector3D<T> v1,
-                                                                 final Cartesian3D v2) {
+                                                                 final Vector3D v2) {
         return v1.distance(v2);
     }
 
@@ -1077,7 +1078,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
      */
-    public static <T extends RealFieldElement<T>> T distance(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> T distance(final Vector3D v1,
                                                                  final FieldVector3D<T> v2) {
         return v2.distance(v1);
     }
@@ -1106,7 +1107,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the distance between v1 and v2 according to the L<sub>&infin;</sub> norm
      */
     public static <T extends RealFieldElement<T>> T distanceInf(final FieldVector3D<T> v1,
-                                                                    final Cartesian3D v2) {
+                                                                    final Vector3D v2) {
         return v1.distanceInf(v2);
     }
 
@@ -1119,7 +1120,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the distance between v1 and v2 according to the L<sub>&infin;</sub> norm
      */
-    public static <T extends RealFieldElement<T>> T distanceInf(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> T distanceInf(final Vector3D v1,
                                                                     final FieldVector3D<T> v2) {
         return v2.distanceInf(v1);
     }
@@ -1148,7 +1149,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @return the square of the distance between v1 and v2
      */
     public static <T extends RealFieldElement<T>> T distanceSq(final FieldVector3D<T> v1,
-                                                                   final Cartesian3D v2) {
+                                                                   final Vector3D v2) {
         return v1.distanceSq(v2);
     }
 
@@ -1161,7 +1162,7 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      * @param <T> the type of the field elements
      * @return the square of the distance between v1 and v2
      */
-    public static <T extends RealFieldElement<T>> T distanceSq(final Cartesian3D v1,
+    public static <T extends RealFieldElement<T>> T distanceSq(final Vector3D v1,
                                                                    final FieldVector3D<T> v2) {
         return v2.distanceSq(v1);
     }
@@ -1171,15 +1172,6 @@ public class FieldVector3D<T extends RealFieldElement<T>> implements Serializabl
      */
     @Override
     public String toString() {
-        return Vector3DFormat.getInstance().format(toVector3D());
+        return toVector3D().toString();
     }
-
-    /** Get a string representation of this vector.
-     * @param format the custom format for components
-     * @return a string representation of this vector
-     */
-    public String toString(final NumberFormat format) {
-        return new Vector3DFormat(format).format(toVector3D());
-    }
-
 }
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
deleted file mode 100644
index 6b467fc..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
+++ /dev/null
@@ -1,281 +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 org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
-import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
-import org.apache.commons.math4.geometry.partitioning.Embedding;
-import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.numbers.core.Precision;
-
-/** The class represent lines in a three dimensional space.
-
- * <p>Each oriented line is intrinsically associated with an abscissa
- * which is a coordinate on the line. The point at abscissa 0 is the
- * orthogonal projection of the origin on the line, another equivalent
- * way to express this is to say that it is the point of the line
- * which is closest to the origin. Abscissa increases in the line
- * direction.</p>
-
- * @since 3.0
- */
-public class Line implements Embedding<Euclidean3D, Euclidean1D> {
-
-    /** Line direction. */
-    private Cartesian3D direction;
-
-    /** Line point closest to the origin. */
-    private Cartesian3D zero;
-
-    /** Tolerance below which points are considered identical. */
-    private final double tolerance;
-
-    /** Build a line from two points.
-     * @param p1 first point belonging to the line (this can be any point)
-     * @param p2 second point belonging to the line (this can be any point, different from p1)
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathIllegalArgumentException if the points are equal
-     * @since 3.3
-     */
-    public Line(final Cartesian3D p1, final Cartesian3D p2, final double tolerance)
-        throws MathIllegalArgumentException {
-        reset(p1, p2);
-        this.tolerance = tolerance;
-    }
-
-    /** Copy constructor.
-     * <p>The created instance is completely independent from the
-     * original instance, it is a deep copy.</p>
-     * @param line line to copy
-     */
-    public Line(final Line line) {
-        this.direction = line.direction;
-        this.zero      = line.zero;
-        this.tolerance = line.tolerance;
-    }
-
-    /** Reset the instance as if built from two points.
-     * @param p1 first point belonging to the line (this can be any point)
-     * @param p2 second point belonging to the line (this can be any point, different from p1)
-     * @exception MathIllegalArgumentException if the points are equal
-     */
-    public void reset(final Cartesian3D p1, final Cartesian3D p2) throws MathIllegalArgumentException {
-        final Cartesian3D delta = p2.subtract(p1);
-        final double norm2 = delta.getNormSq();
-        if (norm2 == 0.0) {
-            throw new MathIllegalArgumentException(LocalizedFormats.ZERO_NORM);
-        }
-        this.direction = new Cartesian3D(1.0 / FastMath.sqrt(norm2), delta);
-        zero = new Cartesian3D(1.0, p1, -p1.dotProduct(delta) / norm2, delta);
-    }
-
-    /** Get the tolerance below which points are considered identical.
-     * @return tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public double getTolerance() {
-        return tolerance;
-    }
-
-    /** Get a line with reversed direction.
-     * @return a new instance, with reversed direction
-     */
-    public Line revert() {
-        final Line reverted = new Line(this);
-        reverted.direction = reverted.direction.negate();
-        return reverted;
-    }
-
-    /** Get the normalized direction vector.
-     * @return normalized direction vector
-     */
-    public Cartesian3D getDirection() {
-        return direction;
-    }
-
-    /** Get the line point closest to the origin.
-     * @return line point closest to the origin
-     */
-    public Cartesian3D getOrigin() {
-        return zero;
-    }
-
-    /** Get the abscissa of a point with respect to the line.
-     * <p>The abscissa is 0 if the projection of the point and the
-     * projection of the frame origin on the line are the same
-     * point.</p>
-     * @param point point to check
-     * @return abscissa of the point
-     */
-    public double getAbscissa(final Cartesian3D point) {
-        return point.subtract(zero).dotProduct(direction);
-    }
-
-    /** Get one point from the line.
-     * @param abscissa desired abscissa for the point
-     * @return one point belonging to the line, at specified abscissa
-     */
-    public Cartesian3D pointAt(final double abscissa) {
-        return new Cartesian3D(1.0, zero, abscissa, direction);
-    }
-
-    /** Transform a space point into a sub-space point.
-     * @param vector n-dimension point of the space
-     * @return (n-1)-dimension point of the sub-space corresponding to
-     * the specified space point
-     */
-    public Cartesian1D toSubSpace(Vector<Euclidean3D> vector) {
-        return toSubSpace((Point<Euclidean3D>) vector);
-    }
-
-    /** Transform a sub-space point into a space point.
-     * @param vector (n-1)-dimension point of the sub-space
-     * @return n-dimension point of the space corresponding to the
-     * specified sub-space point
-     */
-    public Cartesian3D toSpace(Vector<Euclidean1D> vector) {
-        return toSpace((Point<Euclidean1D>) vector);
-    }
-
-    /** {@inheritDoc}
-     * @see #getAbscissa(Cartesian3D)
-     */
-    @Override
-    public Cartesian1D toSubSpace(final Point<Euclidean3D> point) {
-        return toSubSpace((Cartesian3D) point);
-    }
-
-    /** {@inheritDoc}
-     * @see #pointAt(double)
-     */
-    @Override
-    public Cartesian3D toSpace(final Point<Euclidean1D> point) {
-        return toSpace((Cartesian1D) point);
-    }
-
-    /** Transform a space point into a sub-space point.
-     * @param point n-dimension point of the space
-     * @return (n-1)-dimension point of the sub-space corresponding to
-     * the specified space point
-     */
-    public Cartesian1D toSubSpace(final Cartesian3D point) {
-        return new Cartesian1D(getAbscissa(point));
-    }
-
-    /** Transform a sub-space point into a space point.
-     * @param point (n-1)-dimension point of the sub-space
-     * @return n-dimension point of the space corresponding to the
-     * specified sub-space point
-     */
-    public Cartesian3D toSpace(final Cartesian1D point) {
-        return pointAt(point.getX());
-    }
-
-    /** Check if the instance is similar to another line.
-     * <p>Lines are considered similar if they contain the same
-     * points. This does not mean they are equal since they can have
-     * opposite directions.</p>
-     * @param line line to which instance should be compared
-     * @return true if the lines are similar
-     */
-    public boolean isSimilarTo(final Line line) {
-        final double angle = Cartesian3D.angle(direction, line.direction);
-        return ((angle < tolerance) || (angle > (FastMath.PI - tolerance))) && contains(line.zero);
-    }
-
-    /** Check if the instance contains a point.
-     * @param p point to check
-     * @return true if p belongs to the line
-     */
-    public boolean contains(final Cartesian3D p) {
-        return distance(p) < tolerance;
-    }
-
-    /** Compute the distance between the instance and a point.
-     * @param p to check
-     * @return distance between the instance and the point
-     */
-    public double distance(final Cartesian3D p) {
-        final Cartesian3D d = p.subtract(zero);
-        final Cartesian3D n = new Cartesian3D(1.0, d, -d.dotProduct(direction), direction);
-        return n.getNorm();
-    }
-
-    /** Compute the shortest distance between the instance and another line.
-     * @param line line to check against the instance
-     * @return shortest distance between the instance and the line
-     */
-    public double distance(final Line line) {
-
-        final Cartesian3D normal = Cartesian3D.crossProduct(direction, line.direction);
-        final double n = normal.getNorm();
-        if (n < Precision.SAFE_MIN) {
-            // lines are parallel
-            return distance(line.zero);
-        }
-
-        // signed separation of the two parallel planes that contains the lines
-        final double offset = line.zero.subtract(zero).dotProduct(normal) / n;
-
-        return FastMath.abs(offset);
-
-    }
-
-    /** Compute the point of the instance closest to another line.
-     * @param line line to check against the instance
-     * @return point of the instance closest to another line
-     */
-    public Cartesian3D closestPoint(final Line line) {
-
-        final double cos = direction.dotProduct(line.direction);
-        final double n = 1 - cos * cos;
-        if (n < Precision.EPSILON) {
-            // the lines are parallel
-            return zero;
-        }
-
-        final Cartesian3D delta0 = line.zero.subtract(zero);
-        final double a        = delta0.dotProduct(direction);
-        final double b        = delta0.dotProduct(line.direction);
-
-        return new Cartesian3D(1, zero, (a - b * cos) / n, direction);
-
-    }
-
-    /** Get the intersection point of the instance and another line.
-     * @param line other line
-     * @return intersection point of the instance and the other line
-     * or null if there are no intersection points
-     */
-    public Cartesian3D intersection(final Line line) {
-        final Cartesian3D closest = closestPoint(line);
-        return line.contains(closest) ? closest : null;
-    }
-
-    /** Build a sub-line covering the whole line.
-     * @return a sub-line covering the whole line
-     */
-    public SubLine wholeLine() {
-        return new SubLine(this, new IntervalsSet(tolerance));
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/OutlineExtractor.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/OutlineExtractor.java
deleted file mode 100644
index 71657e2..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/OutlineExtractor.java
+++ /dev/null
@@ -1,266 +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.util.ArrayList;
-
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-import org.apache.commons.math4.geometry.euclidean.twod.PolygonsSet;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
-import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
-import org.apache.commons.math4.geometry.partitioning.BSPTree;
-import org.apache.commons.math4.geometry.partitioning.BSPTreeVisitor;
-import org.apache.commons.math4.geometry.partitioning.BoundaryAttribute;
-import org.apache.commons.math4.geometry.partitioning.RegionFactory;
-import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
-import org.apache.commons.math4.util.FastMath;
-
-/** Extractor for {@link PolygonsSet polyhedrons sets} outlines.
- * <p>This class extracts the 2D outlines from {{@link PolygonsSet
- * polyhedrons sets} in a specified projection plane.</p>
- * @since 3.0
- */
-public class OutlineExtractor {
-
-    /** Abscissa axis of the projection plane. */
-    private final Cartesian3D u;
-
-    /** Ordinate axis of the projection plane. */
-    private final Cartesian3D v;
-
-    /** Normal of the projection plane (viewing direction). */
-    private final Cartesian3D w;
-
-    /** Build an extractor for a specific projection plane.
-     * @param u abscissa axis of the projection point
-     * @param v ordinate axis of the projection point
-     */
-    public OutlineExtractor(final Cartesian3D u, final Cartesian3D v) {
-        this.u = u;
-        this.v = v;
-        w = Cartesian3D.crossProduct(u, v);
-    }
-
-    /** Extract the outline of a polyhedrons set.
-     * @param polyhedronsSet polyhedrons set whose outline must be extracted
-     * @return an outline, as an array of loops.
-     */
-    public Cartesian2D[][] getOutline(final PolyhedronsSet polyhedronsSet) {
-
-        // project all boundary facets into one polygons set
-        final BoundaryProjector projector = new BoundaryProjector(polyhedronsSet.getTolerance());
-        polyhedronsSet.getTree(true).visit(projector);
-        final PolygonsSet projected = projector.getProjected();
-
-        // Remove the spurious intermediate vertices from the outline
-        final Cartesian2D[][] outline = projected.getVertices();
-        for (int i = 0; i < outline.length; ++i) {
-            final Cartesian2D[] rawLoop = outline[i];
-            int end = rawLoop.length;
-            int j = 0;
-            while (j < end) {
-                if (pointIsBetween(rawLoop, end, j)) {
-                    // the point should be removed
-                    for (int k = j; k < (end - 1); ++k) {
-                        rawLoop[k] = rawLoop[k + 1];
-                    }
-                    --end;
-                } else {
-                    // the point remains in the loop
-                    ++j;
-                }
-            }
-            if (end != rawLoop.length) {
-                // resize the array
-                outline[i] = new Cartesian2D[end];
-                System.arraycopy(rawLoop, 0, outline[i], 0, end);
-            }
-        }
-
-        return outline;
-
-    }
-
-    /** Check if a point is geometrically between its neighbor in an array.
-     * <p>The neighbors are computed considering the array is a loop
-     * (i.e. point at index (n-1) is before point at index 0)</p>
-     * @param loop points array
-     * @param n number of points to consider in the array
-     * @param i index of the point to check (must be between 0 and n-1)
-     * @return true if the point is exactly between its neighbors
-     */
-    private boolean pointIsBetween(final Cartesian2D[] loop, final int n, final int i) {
-        final Cartesian2D previous = loop[(i + n - 1) % n];
-        final Cartesian2D current  = loop[i];
-        final Cartesian2D next     = loop[(i + 1) % n];
-        final double dx1       = current.getX() - previous.getX();
-        final double dy1       = current.getY() - previous.getY();
-        final double dx2       = next.getX()    - current.getX();
-        final double dy2       = next.getY()    - current.getY();
-        final double cross     = dx1 * dy2 - dx2 * dy1;
-        final double dot       = dx1 * dx2 + dy1 * dy2;
-        final double d1d2      = FastMath.sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2));
-        return (FastMath.abs(cross) <= (1.0e-6 * d1d2)) && (dot >= 0.0);
-    }
-
-    /** Visitor projecting the boundary facets on a plane. */
-    private class BoundaryProjector implements BSPTreeVisitor<Euclidean3D> {
-
-        /** Projection of the polyhedrons set on the plane. */
-        private PolygonsSet projected;
-
-        /** Tolerance below which points are considered identical. */
-        private final double tolerance;
-
-        /** Simple constructor.
-         * @param tolerance tolerance below which points are considered identical
-         */
-        BoundaryProjector(final double tolerance) {
-            this.projected = new PolygonsSet(new BSPTree<Euclidean2D>(Boolean.FALSE), tolerance);
-            this.tolerance = tolerance;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Order visitOrder(final BSPTree<Euclidean3D> node) {
-            return Order.MINUS_SUB_PLUS;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitInternalNode(final BSPTree<Euclidean3D> node) {
-            @SuppressWarnings("unchecked")
-            final BoundaryAttribute<Euclidean3D> attribute =
-                (BoundaryAttribute<Euclidean3D>) node.getAttribute();
-            if (attribute.getPlusOutside() != null) {
-                addContribution(attribute.getPlusOutside(), false);
-            }
-            if (attribute.getPlusInside() != null) {
-                addContribution(attribute.getPlusInside(), true);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitLeafNode(final BSPTree<Euclidean3D> node) {
-        }
-
-        /** Add he contribution of a boundary facet.
-         * @param facet boundary facet
-         * @param reversed if true, the facet has the inside on its plus side
-         */
-        private void addContribution(final SubHyperplane<Euclidean3D> facet, final boolean reversed) {
-
-            // extract the vertices of the facet
-            @SuppressWarnings("unchecked")
-            final AbstractSubHyperplane<Euclidean3D, Euclidean2D> absFacet =
-                (AbstractSubHyperplane<Euclidean3D, Euclidean2D>) facet;
-            final Plane plane    = (Plane) facet.getHyperplane();
-
-            final double scal = plane.getNormal().dotProduct(w);
-            if (FastMath.abs(scal) > 1.0e-3) {
-                Cartesian2D[][] vertices =
-                    ((PolygonsSet) absFacet.getRemainingRegion()).getVertices();
-
-                if ((scal < 0) ^ reversed) {
-                    // the facet is seen from the inside,
-                    // we need to invert its boundary orientation
-                    final Cartesian2D[][] newVertices = new Cartesian2D[vertices.length][];
-                    for (int i = 0; i < vertices.length; ++i) {
-                        final Cartesian2D[] loop = vertices[i];
-                        final Cartesian2D[] newLoop = new Cartesian2D[loop.length];
-                        if (loop[0] == null) {
-                            newLoop[0] = null;
-                            for (int j = 1; j < loop.length; ++j) {
-                                newLoop[j] = loop[loop.length - j];
-                            }
-                        } else {
-                            for (int j = 0; j < loop.length; ++j) {
-                                newLoop[j] = loop[loop.length - (j + 1)];
-                            }
-                        }
-                        newVertices[i] = newLoop;
-                    }
-
-                    // use the reverted vertices
-                    vertices = newVertices;
-
-                }
-
-                // compute the projection of the facet in the outline plane
-                final ArrayList<SubHyperplane<Euclidean2D>> edges = new ArrayList<>();
-                for (Cartesian2D[] loop : vertices) {
-                    final boolean closed = loop[0] != null;
-                    int previous         = closed ? (loop.length - 1) : 1;
-                    Cartesian3D previous3D  = plane.toSpace(loop[previous]);
-                    int current          = (previous + 1) % loop.length;
-                    Cartesian2D pPoint       = new Cartesian2D(previous3D.dotProduct(u),
-                                                         previous3D.dotProduct(v));
-                    while (current < loop.length) {
-
-                        final Cartesian3D current3D = plane.toSpace((Point<Euclidean2D>) loop[current]);
-                        final Cartesian2D  cPoint    = new Cartesian2D(current3D.dotProduct(u),
-                                                                 current3D.dotProduct(v));
-                        final org.apache.commons.math4.geometry.euclidean.twod.Line line =
-                            new org.apache.commons.math4.geometry.euclidean.twod.Line(pPoint, cPoint, tolerance);
-                        SubHyperplane<Euclidean2D> edge = line.wholeHyperplane();
-
-                        if (closed || (previous != 1)) {
-                            // the previous point is a real vertex
-                            // it defines one bounding point of the edge
-                            final double angle = line.getAngle() + 0.5 * FastMath.PI;
-                            final org.apache.commons.math4.geometry.euclidean.twod.Line l =
-                                new org.apache.commons.math4.geometry.euclidean.twod.Line(pPoint, angle, tolerance);
-                            edge = edge.split(l).getPlus();
-                        }
-
-                        if (closed || (current != (loop.length - 1))) {
-                            // the current point is a real vertex
-                            // it defines one bounding point of the edge
-                            final double angle = line.getAngle() + 0.5 * FastMath.PI;
-                            final org.apache.commons.math4.geometry.euclidean.twod.Line l =
-                                new org.apache.commons.math4.geometry.euclidean.twod.Line(cPoint, angle, tolerance);
-                            edge = edge.split(l).getMinus();
-                        }
-
-                        edges.add(edge);
-
-                        previous   = current++;
-                        previous3D = current3D;
-                        pPoint     = cPoint;
-
-                    }
-                }
-                final PolygonsSet projectedFacet = new PolygonsSet(edges, tolerance);
-
-                // add the contribution of the facet to the global outline
-                projected = (PolygonsSet) new RegionFactory<Euclidean2D>().union(projected, projectedFacet);
-
-            }
-        }
-
-        /** Get the projection of the polyhedrons set on the plane.
-         * @return projection of the polyhedrons set on the plane
-         */
-        public PolygonsSet getProjected() {
-            return projected;
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java
deleted file mode 100644
index 7bcc4e3..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java
+++ /dev/null
@@ -1,509 +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 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.Vector;
-import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-import org.apache.commons.math4.geometry.euclidean.twod.PolygonsSet;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
-import org.apache.commons.math4.geometry.partitioning.Embedding;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-import org.apache.commons.math4.util.FastMath;
-
-/** The class represent planes in a three dimensional space.
- * @since 3.0
- */
-public class Plane implements Hyperplane<Euclidean3D>, Embedding<Euclidean3D, Euclidean2D> {
-
-    /** Offset of the origin with respect to the plane. */
-    private double originOffset;
-
-    /** Origin of the plane frame. */
-    private Cartesian3D origin;
-
-    /** First vector of the plane frame (in plane). */
-    private Cartesian3D u;
-
-    /** Second vector of the plane frame (in plane). */
-    private Cartesian3D v;
-
-    /** Third vector of the plane frame (plane normal). */
-    private Cartesian3D w;
-
-    /** Tolerance below which points are considered identical. */
-    private final double tolerance;
-
-    /** Build a plane normal to a given direction and containing the origin.
-     * @param normal normal direction to the plane
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathArithmeticException if the normal norm is too small
-     * @since 3.3
-     */
-    public Plane(final Cartesian3D normal, final double tolerance)
-        throws MathArithmeticException {
-        setNormal(normal);
-        this.tolerance = tolerance;
-        originOffset = 0;
-        setFrame();
-    }
-
-    /** Build a plane from a point and a normal.
-     * @param p point belonging to the plane
-     * @param normal normal direction to the plane
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathArithmeticException if the normal norm is too small
-     * @since 3.3
-     */
-    public Plane(final Cartesian3D p, final Cartesian3D normal, final double tolerance)
-        throws MathArithmeticException {
-        setNormal(normal);
-        this.tolerance = tolerance;
-        originOffset = -p.dotProduct(w);
-        setFrame();
-    }
-
-    /** Build a plane from three points.
-     * <p>The plane is oriented in the direction of
-     * {@code (p2-p1) ^ (p3-p1)}</p>
-     * @param p1 first point belonging to the plane
-     * @param p2 second point belonging to the plane
-     * @param p3 third point belonging to the plane
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathArithmeticException if the points do not constitute a plane
-     * @since 3.3
-     */
-    public Plane(final Cartesian3D p1, final Cartesian3D p2, final Cartesian3D p3, final double tolerance)
-        throws MathArithmeticException {
-        this(p1, p2.subtract(p1).crossProduct(p3.subtract(p1)), tolerance);
-    }
-
-    /** Copy constructor.
-     * <p>The instance created is completely independent of the original
-     * one. A deep copy is used, none of the underlying object are
-     * shared.</p>
-     * @param plane plane to copy
-     */
-    public Plane(final Plane plane) {
-        originOffset = plane.originOffset;
-        origin       = plane.origin;
-        u            = plane.u;
-        v            = plane.v;
-        w            = plane.w;
-        tolerance    = plane.tolerance;
-    }
-
-    /** Copy the instance.
-     * <p>The instance created is completely independant of the original
-     * one. A deep copy is used, none of the underlying objects are
-     * shared (except for immutable objects).</p>
-     * @return a new hyperplane, copy of the instance
-     */
-    @Override
-    public Plane copySelf() {
-        return new Plane(this);
-    }
-
-    /** Reset the instance as if built from a point and a normal.
-     * @param p point belonging to the plane
-     * @param normal normal direction to the plane
-     * @exception MathArithmeticException if the normal norm is too small
-     */
-    public void reset(final Cartesian3D p, final Cartesian3D normal) throws MathArithmeticException {
-        setNormal(normal);
-        originOffset = -p.dotProduct(w);
-        setFrame();
-    }
-
-    /** Reset the instance from another one.
-     * <p>The updated instance is completely independant of the original
-     * one. A deep reset is used none of the underlying object is
-     * shared.</p>
-     * @param original plane to reset from
-     */
-    public void reset(final Plane original) {
-        originOffset = original.originOffset;
-        origin       = original.origin;
-        u            = original.u;
-        v            = original.v;
-        w            = original.w;
-    }
-
-    /** Set the normal vactor.
-     * @param normal normal direction to the plane (will be copied)
-     * @exception MathArithmeticException if the normal norm is too small
-     */
-    private void setNormal(final Cartesian3D normal) throws MathArithmeticException {
-        final double norm = normal.getNorm();
-        if (norm < 1.0e-10) {
-            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
-        }
-        w = new Cartesian3D(1.0 / norm, normal);
-    }
-
-    /** Reset the plane frame.
-     */
-    private void setFrame() {
-        origin = new Cartesian3D(-originOffset, w);
-        u = w.orthogonal();
-        v = Cartesian3D.crossProduct(w, u);
-    }
-
-    /** Get the origin point of the plane frame.
-     * <p>The point returned is the orthogonal projection of the
-     * 3D-space origin in the plane.</p>
-     * @return the origin point of the plane frame (point closest to the
-     * 3D-space origin)
-     */
-    public Cartesian3D getOrigin() {
-        return origin;
-    }
-
-    /** Get the normalized normal vector.
-     * <p>The frame defined by ({@link #getU getU}, {@link #getV getV},
-     * {@link #getNormal getNormal}) is a rigth-handed orthonormalized
-     * frame).</p>
-     * @return normalized normal vector
-     * @see #getU
-     * @see #getV
-     */
-    public Cartesian3D getNormal() {
-        return w;
-    }
-
-    /** Get the plane first canonical vector.
-     * <p>The frame defined by ({@link #getU getU}, {@link #getV getV},
-     * {@link #getNormal getNormal}) is a rigth-handed orthonormalized
-     * frame).</p>
-     * @return normalized first canonical vector
-     * @see #getV
-     * @see #getNormal
-     */
-    public Cartesian3D getU() {
-        return u;
-    }
-
-    /** Get the plane second canonical vector.
-     * <p>The frame defined by ({@link #getU getU}, {@link #getV getV},
-     * {@link #getNormal getNormal}) is a rigth-handed orthonormalized
-     * frame).</p>
-     * @return normalized second canonical vector
-     * @see #getU
-     * @see #getNormal
-     */
-    public Cartesian3D getV() {
-        return v;
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public Point<Euclidean3D> project(Point<Euclidean3D> point) {
-        return toSpace(toSubSpace(point));
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public double getTolerance() {
-        return tolerance;
-    }
-
-    /** Revert the plane.
-     * <p>Replace the instance by a similar plane with opposite orientation.</p>
-     * <p>The new plane frame is chosen in such a way that a 3D point that had
-     * {@code (x, y)} in-plane coordinates and {@code z} offset with
-     * respect to the plane and is unaffected by the change will have
-     * {@code (y, x)} in-plane coordinates and {@code -z} offset with
-     * respect to the new plane. This means that the {@code u} and {@code v}
-     * vectors returned by the {@link #getU} and {@link #getV} methods are exchanged,
-     * and the {@code w} vector returned by the {@link #getNormal} method is
-     * reversed.</p>
-     */
-    public void revertSelf() {
-        final Cartesian3D tmp = u;
-        u = v;
-        v = tmp;
-        w = w.negate();
-        originOffset = -originOffset;
-    }
-
-    /** Transform a space vector into a sub-space vector.
-     * @param vector n-dimension vector of the space
-     * @return (n-1)-dimension vector of the sub-space corresponding to
-     * the specified space vector
-     */
-    public Cartesian2D toSubSpace(Vector<Euclidean3D> vector) {
-        return toSubSpace((Cartesian3D) vector);
-    }
-
-    /** Transform a sub-space point into a space point.
-     * @param vector (n-1)-dimension point of the sub-space
-     * @return n-dimension point of the space corresponding to the
-     * specified sub-space point
-     */
-    public Cartesian3D toSpace(Vector<Euclidean2D> vector) {
-        return toSpace((Cartesian2D) vector);
-    }
-
-    /** Transform a 3D space point into an in-plane point.
-     * @param point point of the space (must be a {@link Cartesian3D} instance)
-     * @return in-plane point
-     * @see #toSpace
-     */
-    @Override
-    public Cartesian2D toSubSpace(final Point<Euclidean3D> point) {
-        return toSubSpace((Cartesian3D) point);
-    }
-
-    /** Transform an in-plane point into a 3D space point.
-     * @param point in-plane point (must be a {@link Cartesian2D} instance)
-     * @return 3D space point
-     * @see #toSubSpace
-     */
-    @Override
-    public Cartesian3D toSpace(final Point<Euclidean2D> point) {
-        return toSpace((Cartesian2D) point);
-    }
-
-    /** Transform a 3D space point into an in-plane point.
-     * @param point point of the space
-     * @return in-plane point
-     * @see #toSpace
-     */
-    public Cartesian2D toSubSpace(final Cartesian3D point) {
-        return new Cartesian2D(point.dotProduct(u), point.dotProduct(v));
-    }
-
-    /** Transform an in-plane point into a 3D space point.
-     * @param point in-plane point
-     * @return 3D space point
-     * @see #toSubSpace
-     */
-    public Cartesian3D toSpace(final Cartesian2D point) {
-        return new Cartesian3D(point.getX(), u, point.getY(), v, -originOffset, w);
-    }
-
-    /** Get one point from the 3D-space.
-     * @param inPlane desired in-plane coordinates for the point in the
-     * plane
-     * @param offset desired offset for the point
-     * @return one point in the 3D-space, with given coordinates and offset
-     * relative to the plane
-     */
-    public Cartesian3D getPointAt(final Cartesian2D inPlane, final double offset) {
-        return new Cartesian3D(inPlane.getX(), u, inPlane.getY(), v, offset - originOffset, w);
-    }
-
-    /** Check if the instance is similar to another plane.
-     * <p>Planes are considered similar if they contain the same
-     * points. This does not mean they are equal since they can have
-     * opposite normals.</p>
-     * @param plane plane to which the instance is compared
-     * @return true if the planes are similar
-     */
-    public boolean isSimilarTo(final Plane plane) {
-        final double angle = Cartesian3D.angle(w, plane.w);
-        return ((angle < 1.0e-10) && (FastMath.abs(originOffset - plane.originOffset) < tolerance)) ||
-               ((angle > (FastMath.PI - 1.0e-10)) && (FastMath.abs(originOffset + plane.originOffset) < tolerance));
-    }
-
-    /** Rotate the plane around the specified point.
-     * <p>The instance is not modified, a new instance is created.</p>
-     * @param center rotation center
-     * @param rotation vectorial rotation operator
-     * @return a new plane
-     */
-    public Plane rotate(final Cartesian3D center, final Rotation rotation) {
-
-        final Cartesian3D delta = origin.subtract(center);
-        final Plane plane = new Plane(center.add(rotation.applyTo(delta)),
-                                      rotation.applyTo(w), tolerance);
-
-        // make sure the frame is transformed as desired
-        plane.u = rotation.applyTo(u);
-        plane.v = rotation.applyTo(v);
-
-        return plane;
-
-    }
-
-    /** Translate the plane by the specified amount.
-     * <p>The instance is not modified, a new instance is created.</p>
-     * @param translation translation to apply
-     * @return a new plane
-     */
-    public Plane translate(final Cartesian3D translation) {
-
-        final Plane plane = new Plane(origin.add(translation), w, tolerance);
-
-        // make sure the frame is transformed as desired
-        plane.u = u;
-        plane.v = v;
-
-        return plane;
-
-    }
-
-    /** Get the intersection of a line with the instance.
-     * @param line line intersecting the instance
-     * @return intersection point between between the line and the
-     * instance (null if the line is parallel to the instance)
-     */
-    public Cartesian3D intersection(final Line line) {
-        final Cartesian3D direction = line.getDirection();
-        final double   dot       = w.dotProduct(direction);
-        if (FastMath.abs(dot) < 1.0e-10) {
-            return null;
-        }
-        final Cartesian3D point = line.toSpace(Cartesian1D.ZERO);
-        final double   k     = -(originOffset + w.dotProduct(point)) / dot;
-        return new Cartesian3D(1.0, point, k, direction);
-    }
-
-    /** Build the line shared by the instance and another plane.
-     * @param other other plane
-     * @return line at the intersection of the instance and the
-     * other plane (really a {@link Line Line} instance)
-     */
-    public Line intersection(final Plane other) {
-        final Cartesian3D direction = Cartesian3D.crossProduct(w, other.w);
-        if (direction.getNorm() < tolerance) {
-            return null;
-        }
-        final Cartesian3D point = intersection(this, other, new Plane(direction, tolerance));
-        return new Line(point, point.add(direction), tolerance);
-    }
-
-    /** Get the intersection point of three planes.
-     * @param plane1 first plane1
-     * @param plane2 second plane2
-     * @param plane3 third plane2
-     * @return intersection point of three planes, null if some planes are parallel
-     */
-    public static Cartesian3D intersection(final Plane plane1, final Plane plane2, final Plane plane3) {
-
-        // coefficients of the three planes linear equations
-        final double a1 = plane1.w.getX();
-        final double b1 = plane1.w.getY();
-        final double c1 = plane1.w.getZ();
-        final double d1 = plane1.originOffset;
-
-        final double a2 = plane2.w.getX();
-        final double b2 = plane2.w.getY();
-        final double c2 = plane2.w.getZ();
-        final double d2 = plane2.originOffset;
-
-        final double a3 = plane3.w.getX();
-        final double b3 = plane3.w.getY();
-        final double c3 = plane3.w.getZ();
-        final double d3 = plane3.originOffset;
-
-        // direct Cramer resolution of the linear system
-        // (this is still feasible for a 3x3 system)
-        final double a23         = b2 * c3 - b3 * c2;
-        final double b23         = c2 * a3 - c3 * a2;
-        final double c23         = a2 * b3 - a3 * b2;
-        final double determinant = a1 * a23 + b1 * b23 + c1 * c23;
-        if (FastMath.abs(determinant) < 1.0e-10) {
-            return null;
-        }
-
-        final double r = 1.0 / determinant;
-        return new Cartesian3D(
-                            (-a23 * d1 - (c1 * b3 - c3 * b1) * d2 - (c2 * b1 - c1 * b2) * d3) * r,
-                            (-b23 * d1 - (c3 * a1 - c1 * a3) * d2 - (c1 * a2 - c2 * a1) * d3) * r,
-                            (-c23 * d1 - (b1 * a3 - b3 * a1) * d2 - (b2 * a1 - b1 * a2) * d3) * r);
-
-    }
-
-    /** Build a region covering the whole hyperplane.
-     * @return a region covering the whole hyperplane
-     */
-    @Override
-    public SubPlane wholeHyperplane() {
-        return new SubPlane(this, new PolygonsSet(tolerance));
-    }
-
-    /** Build a region covering the whole space.
-     * @return a region containing the instance (really a {@link
-     * PolyhedronsSet PolyhedronsSet} instance)
-     */
-    @Override
-    public PolyhedronsSet wholeSpace() {
-        return new PolyhedronsSet(tolerance);
-    }
-
-    /** Check if the instance contains a point.
-     * @param p point to check
-     * @return true if p belongs to the plane
-     */
-    public boolean contains(final Cartesian3D p) {
-        return FastMath.abs(getOffset(p)) < tolerance;
-    }
-
-    /** Get the offset (oriented distance) of a parallel plane.
-     * <p>This method should be called only for parallel planes otherwise
-     * the result is not meaningful.</p>
-     * <p>The offset is 0 if both planes are the same, it is
-     * positive if the plane is on the plus side of the instance and
-     * negative if it is on the minus side, according to its natural
-     * orientation.</p>
-     * @param plane plane to check
-     * @return offset of the plane
-     */
-    public double getOffset(final Plane plane) {
-        return originOffset + (sameOrientationAs(plane) ? -plane.originOffset : plane.originOffset);
-    }
-
-    /** Get the offset (oriented distance) of a vector.
-     * @param vector vector to check
-     * @return offset of the vector
-     */
-//    public double getOffset(Vector<Euclidean3D> vector) {
-//        return getOffset((Point<Euclidean3D>) vector);
-//    }
-
-    /** Get the offset (oriented distance) of a point.
-     * <p>The offset is 0 if the point is on the underlying hyperplane,
-     * it is positive if the point is on one particular side of the
-     * hyperplane, and it is negative if the point is on the other side,
-     * according to the hyperplane natural orientation.</p>
-     * @param point point to check
-     * @return offset of the point
-     */
-    @Override
-    public double getOffset(final Point<Euclidean3D> point) {
-        return ((Cartesian3D) point).dotProduct(w) + originOffset;
-    }
-
-    /** Check if the instance has the same orientation as another hyperplane.
-     * @param other other hyperplane to check against the instance
-     * @return true if the instance and the other hyperplane have
-     * the same orientation
-     */
-    @Override
-    public boolean sameOrientationAs(final Hyperplane<Euclidean3D> other) {
-        return (((Plane) other).w).dotProduct(w) > 0.0;
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSet.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSet.java
deleted file mode 100644
index cfd9f7c..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSet.java
+++ /dev/null
@@ -1,725 +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.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.exception.NumberIsTooSmallException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-import org.apache.commons.math4.geometry.euclidean.twod.PolygonsSet;
-import org.apache.commons.math4.geometry.euclidean.twod.SubLine;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
-import org.apache.commons.math4.geometry.partitioning.AbstractRegion;
-import org.apache.commons.math4.geometry.partitioning.BSPTree;
-import org.apache.commons.math4.geometry.partitioning.BSPTreeVisitor;
-import org.apache.commons.math4.geometry.partitioning.BoundaryAttribute;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.RegionFactory;
-import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
-import org.apache.commons.math4.geometry.partitioning.Transform;
-import org.apache.commons.math4.util.FastMath;
-
-/** This class represents a 3D region: a set of polyhedrons.
- * @since 3.0
- */
-public class PolyhedronsSet extends AbstractRegion<Euclidean3D, Euclidean2D> {
-
-    /** Build a polyhedrons set representing the whole real line.
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public PolyhedronsSet(final double tolerance) {
-        super(tolerance);
-    }
-
-    /** Build a polyhedrons set from a BSP tree.
-     * <p>The leaf nodes of the BSP tree <em>must</em> have a
-     * {@code Boolean} attribute representing the inside status of
-     * the corresponding cell (true for inside cells, false for outside
-     * cells). In order to avoid building too many small objects, it is
-     * recommended to use the predefined constants
-     * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p>
-     * <p>
-     * This constructor is aimed at expert use, as building the tree may
-     * be a difficult task. It is not intended for general use and for
-     * performances reasons does not check thoroughly its input, as this would
-     * require walking the full tree each time. Failing to provide a tree with
-     * the proper attributes, <em>will</em> therefore generate problems like
-     * {@link NullPointerException} or {@link ClassCastException} only later on.
-     * This limitation is known and explains why this constructor is for expert
-     * use only. The caller does have the responsibility to provided correct arguments.
-     * </p>
-     * @param tree inside/outside BSP tree representing the region
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public PolyhedronsSet(final BSPTree<Euclidean3D> tree, final double tolerance) {
-        super(tree, tolerance);
-    }
-
-    /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by sub-hyperplanes.
-     * <p>The boundary is provided as a collection of {@link
-     * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the
-     * interior part of the region on its minus side and the exterior on
-     * its plus side.</p>
-     * <p>The boundary elements can be in any order, and can form
-     * several non-connected sets (like for example polyhedrons with holes
-     * or a set of disjoint polyhedrons considered as a whole). In
-     * fact, the elements do not even need to be connected together
-     * (their topological connections are not used here). However, if the
-     * boundary does not really separate an inside open from an outside
-     * open (open having here its topological meaning), then subsequent
-     * calls to the {@link Region#checkPoint(Point) checkPoint} method will
-     * not be meaningful anymore.</p>
-     * <p>If the boundary is empty, the region will represent the whole
-     * space.</p>
-     * @param boundary collection of boundary elements, as a
-     * collection of {@link SubHyperplane SubHyperplane} objects
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public PolyhedronsSet(final Collection<SubHyperplane<Euclidean3D>> boundary,
-                          final double tolerance) {
-        super(boundary, tolerance);
-    }
-
-    /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by connected vertices.
-     * <p>
-     * The boundary is provided as a list of vertices and a list of facets.
-     * Each facet is specified as an integer array containing the arrays vertices
-     * indices in the vertices list. Each facet normal is oriented by right hand
-     * rule to the facet vertices list.
-     * </p>
-     * <p>
-     * Some basic sanity checks are performed but not everything is thoroughly
-     * assessed, so it remains under caller responsibility to ensure the vertices
-     * and facets are consistent and properly define a polyhedrons set.
-     * </p>
-     * @param vertices list of polyhedrons set vertices
-     * @param facets list of facets, as vertices indices in the vertices list
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathIllegalArgumentException if some basic sanity checks fail
-     * @since 3.5
-     */
-    public PolyhedronsSet(final List<Cartesian3D> vertices, final List<int[]> facets,
-                          final double tolerance) {
-        super(buildBoundary(vertices, facets, tolerance), tolerance);
-    }
-
-    /** Build a parallellepipedic box.
-     * @param xMin low bound along the x direction
-     * @param xMax high bound along the x direction
-     * @param yMin low bound along the y direction
-     * @param yMax high bound along the y direction
-     * @param zMin low bound along the z direction
-     * @param zMax high bound along the z direction
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public PolyhedronsSet(final double xMin, final double xMax,
-                          final double yMin, final double yMax,
-                          final double zMin, final double zMax,
-                          final double tolerance) {
-        super(buildBoundary(xMin, xMax, yMin, yMax, zMin, zMax, tolerance), tolerance);
-    }
-
-    /** Build a parallellepipedic box boundary.
-     * @param xMin low bound along the x direction
-     * @param xMax high bound along the x direction
-     * @param yMin low bound along the y direction
-     * @param yMax high bound along the y direction
-     * @param zMin low bound along the z direction
-     * @param zMax high bound along the z direction
-     * @param tolerance tolerance below which points are considered identical
-     * @return boundary tree
-     * @since 3.3
-     */
-    private static BSPTree<Euclidean3D> buildBoundary(final double xMin, final double xMax,
-                                                      final double yMin, final double yMax,
-                                                      final double zMin, final double zMax,
-                                                      final double tolerance) {
-        if ((xMin >= xMax - tolerance) || (yMin >= yMax - tolerance) || (zMin >= zMax - tolerance)) {
-            // too thin box, build an empty polygons set
-            return new BSPTree<>(Boolean.FALSE);
-        }
-        final Plane pxMin = new Plane(new Cartesian3D(xMin, 0,    0),   Cartesian3D.MINUS_I, tolerance);
-        final Plane pxMax = new Plane(new Cartesian3D(xMax, 0,    0),   Cartesian3D.PLUS_I,  tolerance);
-        final Plane pyMin = new Plane(new Cartesian3D(0,    yMin, 0),   Cartesian3D.MINUS_J, tolerance);
-        final Plane pyMax = new Plane(new Cartesian3D(0,    yMax, 0),   Cartesian3D.PLUS_J,  tolerance);
-        final Plane pzMin = new Plane(new Cartesian3D(0,    0,   zMin), Cartesian3D.MINUS_K, tolerance);
-        final Plane pzMax = new Plane(new Cartesian3D(0,    0,   zMax), Cartesian3D.PLUS_K,  tolerance);
-        final Region<Euclidean3D> boundary =
-        new RegionFactory<Euclidean3D>().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax);
-        return boundary.getTree(false);
-    }
-
-    /** Build boundary from vertices and facets.
-     * @param vertices list of polyhedrons set vertices
-     * @param facets list of facets, as vertices indices in the vertices list
-     * @param tolerance tolerance below which points are considered identical
-     * @return boundary as a list of sub-hyperplanes
-     * @exception MathIllegalArgumentException if some basic sanity checks fail
-     * @since 3.5
-     */
-    private static List<SubHyperplane<Euclidean3D>> buildBoundary(final List<Cartesian3D> vertices,
-                                                                  final List<int[]> facets,
-                                                                  final double tolerance) {
-
-        // check vertices distances
-        for (int i = 0; i < vertices.size() - 1; ++i) {
-            final Cartesian3D vi = vertices.get(i);
-            for (int j = i + 1; j < vertices.size(); ++j) {
-                if (Cartesian3D.distance(vi, vertices.get(j)) <= tolerance) {
-                    throw new MathIllegalArgumentException(LocalizedFormats.CLOSE_VERTICES,
-                                                           vi.getX(), vi.getY(), vi.getZ());
-                }
-            }
-        }
-
-        // find how vertices are referenced by facets
-        final int[][] references = findReferences(vertices, facets);
-
-        // find how vertices are linked together by edges along the facets they belong to
-        final int[][] successors = successors(vertices, facets, references);
-
-        // check edges orientations
-        for (int vA = 0; vA < vertices.size(); ++vA) {
-            for (final int vB : successors[vA]) {
-
-                if (vB >= 0) {
-                    // when facets are properly oriented, if vB is the successor of vA on facet f1,
-                    // then there must be an adjacent facet f2 where vA is the successor of vB
-                    boolean found = false;
-                    for (final int v : successors[vB]) {
-                        found = found || (v == vA);
-                    }
-                    if (!found) {
-                        final Cartesian3D start = vertices.get(vA);
-                        final Cartesian3D end   = vertices.get(vB);
-                        throw new MathIllegalArgumentException(LocalizedFormats.EDGE_CONNECTED_TO_ONE_FACET,
-                                                               start.getX(), start.getY(), start.getZ(),
-                                                               end.getX(),   end.getY(),   end.getZ());
-                    }
-                }
-            }
-        }
-
-        final List<SubHyperplane<Euclidean3D>> boundary = new ArrayList<>();
-
-        for (final int[] facet : facets) {
-
-            // define facet plane from the first 3 points
-            Plane plane = new Plane(vertices.get(facet[0]), vertices.get(facet[1]), vertices.get(facet[2]),
-                                    tolerance);
-
-            // check all points are in the plane
-            final Cartesian2D[] two2Points = new Cartesian2D[facet.length];
-            for (int i = 0 ; i < facet.length; ++i) {
-                final Cartesian3D v = vertices.get(facet[i]);
-                if (!plane.contains(v)) {
-                    throw new MathIllegalArgumentException(LocalizedFormats.OUT_OF_PLANE,
-                                                           v.getX(), v.getY(), v.getZ());
-                }
-                two2Points[i] = plane.toSubSpace(v);
-            }
-
-            // create the polygonal facet
-            boundary.add(new SubPlane(plane, new PolygonsSet(tolerance, two2Points)));
-
-        }
-
-        return boundary;
-
-    }
-
-    /** Find the facets that reference each edges.
-     * @param vertices list of polyhedrons set vertices
-     * @param facets list of facets, as vertices indices in the vertices list
-     * @return references array such that r[v][k] = f for some k if facet f contains vertex v
-     * @exception MathIllegalArgumentException if some facets have fewer than 3 vertices
-     * @since 3.5
-     */
-    private static int[][] findReferences(final List<Cartesian3D> vertices, final List<int[]> facets) {
-
-        // find the maximum number of facets a vertex belongs to
-        final int[] nbFacets = new int[vertices.size()];
-        int maxFacets  = 0;
-        for (final int[] facet : facets) {
-            if (facet.length < 3) {
-                throw new NumberIsTooSmallException(LocalizedFormats.WRONG_NUMBER_OF_POINTS,
-                                                    3, facet.length, true);
-            }
-            for (final int index : facet) {
-                maxFacets = FastMath.max(maxFacets, ++nbFacets[index]);
-            }
-        }
-
-        // set up the references array
-        final int[][] references = new int[vertices.size()][maxFacets];
-        for (int[] r : references) {
-            Arrays.fill(r, -1);
-        }
-        for (int f = 0; f < facets.size(); ++f) {
-            for (final int v : facets.get(f)) {
-                // vertex v is referenced by facet f
-                int k = 0;
-                while (k < maxFacets && references[v][k] >= 0) {
-                    ++k;
-                }
-                references[v][k] = f;
-            }
-        }
-
-        return references;
-
-    }
-
-    /** Find the successors of all vertices among all facets they belong to.
-     * @param vertices list of polyhedrons set vertices
-     * @param facets list of facets, as vertices indices in the vertices list
-     * @param references facets references array
-     * @return indices of vertices that follow vertex v in some facet (the array
-     * may contain extra entries at the end, set to negative indices)
-     * @exception MathIllegalArgumentException if the same vertex appears more than
-     * once in the successors list (which means one facet orientation is wrong)
-     * @since 3.5
-     */
-    private static int[][] successors(final List<Cartesian3D> vertices, final List<int[]> facets,
-                                      final int[][] references) {
-
-        // create an array large enough
-        final int[][] successors = new int[vertices.size()][references[0].length];
-        for (final int[] s : successors) {
-            Arrays.fill(s, -1);
-        }
-
-        for (int v = 0; v < vertices.size(); ++v) {
-            for (int k = 0; k < successors[v].length && references[v][k] >= 0; ++k) {
-
-                // look for vertex v
-                final int[] facet = facets.get(references[v][k]);
-                int i = 0;
-                while (i < facet.length && facet[i] != v) {
-                    ++i;
-                }
-
-                // we have found vertex v, we deduce its successor on current facet
-                successors[v][k] = facet[(i + 1) % facet.length];
-                for (int l = 0; l < k; ++l) {
-                    if (successors[v][l] == successors[v][k]) {
-                        final Cartesian3D start = vertices.get(v);
-                        final Cartesian3D end   = vertices.get(successors[v][k]);
-                        throw new MathIllegalArgumentException(LocalizedFormats.FACET_ORIENTATION_MISMATCH,
-                                                               start.getX(), start.getY(), start.getZ(),
-                                                               end.getX(),   end.getY(),   end.getZ());
-                    }
-                }
-
-            }
-        }
-
-        return successors;
-
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public PolyhedronsSet buildNew(final BSPTree<Euclidean3D> tree) {
-        return new PolyhedronsSet(tree, getTolerance());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void computeGeometricalProperties() {
-        // check simple cases first
-        if (isEmpty()) {
-            setSize(0.0);
-            setBarycenter((Point<Euclidean3D>) Cartesian3D.NaN);
-        }
-        else if (isFull()) {
-            setSize(Double.POSITIVE_INFINITY);
-            setBarycenter((Point<Euclidean3D>) Cartesian3D.NaN);
-        }
-        else {
-            // not empty or full; compute the contribution of all boundary facets
-            final FacetsContributionVisitor contributionVisitor = new FacetsContributionVisitor();
-            getTree(true).visit(contributionVisitor);
-
-            final double size = contributionVisitor.getSize();
-            final Cartesian3D barycenter = contributionVisitor.getBarycenter();
-
-            if (size < 0) {
-                // the polyhedrons set is a finite outside surrounded by an infinite inside
-                setSize(Double.POSITIVE_INFINITY);
-                setBarycenter((Point<Euclidean3D>) Cartesian3D.NaN);
-            } else {
-                // the polyhedrons set is finite
-                setSize(size);
-                setBarycenter((Point<Euclidean3D>) barycenter);
-            }
-        }
-    }
-
-    /** Visitor computing polyhedron geometrical properties.
-     *  The volume of the polyhedron is computed using the equation
-     *  <code>V = (1/3)*&Sigma;<sub>F</sub>[(C<sub>F</sub>&sdot;N<sub>F</sub>)*area(F)]</code>,
-     *  where <code>F</code> represents each face in the polyhedron, <code>C<sub>F</sub></code>
-     *  represents the barycenter of the face, and <code>N<sub>F</sub></code> represents the
-     *  normal of the face. (More details can be found in the article
-     *  <a href="https://en.wikipedia.org/wiki/Polyhedron#Volume">here</a>.)
-     *  This essentially splits up the polyhedron into pyramids with a polyhedron
-     *  face forming the base of each pyramid.
-     *  The barycenter is computed in a similar way. The barycenter of each pyramid
-     *  is calculated using the fact that it is located 3/4 of the way along the
-     *  line from the apex to the base. The polyhedron barycenter then becomes
-     *  the volume-weighted average of these pyramid centers.
-     */
-    private static class FacetsContributionVisitor implements BSPTreeVisitor<Euclidean3D> {
-
-        /** Accumulator for facet volume contributions. */
-        private double volumeSum;
-
-        /** Accumulator for barycenter contributions. */
-        private Cartesian3D barycenterSum = Cartesian3D.ZERO;
-
-        /** Returns the total computed size (ie, volume) of the polyhedron.
-         * This value will be negative if the polyhedron is "inside-out", meaning
-         * that it has a finite outside surrounded by an infinite inside.
-         * @return the volume.
-         */
-        public double getSize() {
-            // apply the 1/3 pyramid volume scaling factor
-            return volumeSum / 3.0;
-        }
-
-        /** Returns the computed barycenter. This is the volume-weighted average
-         * of contributions from all facets. All coordinates will be NaN if the
-         * region is infinite.
-         * @return the barycenter.
-         */
-        public Cartesian3D getBarycenter() {
-            // Since the volume we used when adding together the facet contributions
-            // was 3x the actual pyramid size, we'll multiply by 1/4 here instead
-            // of 3/4 to adjust for the actual barycenter position in each pyramid.
-            return new Cartesian3D(1.0 / (4 * getSize()), barycenterSum);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Order visitOrder(final BSPTree<Euclidean3D> node) {
-            return Order.MINUS_SUB_PLUS;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitInternalNode(final BSPTree<Euclidean3D> node) {
-            @SuppressWarnings("unchecked")
-            final BoundaryAttribute<Euclidean3D> attribute =
-                (BoundaryAttribute<Euclidean3D>) node.getAttribute();
-            if (attribute.getPlusOutside() != null) {
-                addContribution(attribute.getPlusOutside(), false);
-            }
-            if (attribute.getPlusInside() != null) {
-                addContribution(attribute.getPlusInside(), true);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitLeafNode(final BSPTree<Euclidean3D> node) {
-        }
-
-        /** Add the contribution of a boundary facet.
-         * @param facet boundary facet
-         * @param reversed if true, the facet has the inside on its plus side
-         */
-        private void addContribution(final SubHyperplane<Euclidean3D> facet, final boolean reversed) {
-
-            final Region<Euclidean2D> polygon = ((SubPlane) facet).getRemainingRegion();
-            final double area = polygon.getSize();
-
-            if (Double.isInfinite(area)) {
-                volumeSum = Double.POSITIVE_INFINITY;
-                barycenterSum = Cartesian3D.NaN;
-            } else {
-                final Plane plane = (Plane) facet.getHyperplane();
-                final Cartesian3D facetBarycenter = plane.toSpace(polygon.getBarycenter());
-
-                // the volume here is actually 3x the actual pyramid volume; we'll apply
-                // the final scaling all at once at the end
-                double scaledVolume = area * facetBarycenter.dotProduct(plane.getNormal());
-                if (reversed) {
-                    scaledVolume = -scaledVolume;
-                }
-
-                volumeSum += scaledVolume;
-                barycenterSum = new Cartesian3D(1.0, barycenterSum, scaledVolume, facetBarycenter);
-            }
-        }
-    }
-
-    /** Get the first sub-hyperplane crossed by a semi-infinite line.
-     * @param point start point of the part of the line considered
-     * @param line line to consider (contains point)
-     * @return the first sub-hyperplane crossed by the line after the
-     * given point, or null if the line does not intersect any
-     * sub-hyperplane
-     */
-    public SubHyperplane<Euclidean3D> firstIntersection(final Cartesian3D point, final Line line) {
-        return recurseFirstIntersection(getTree(true), point, line);
-    }
-
-    /** Get the first sub-hyperplane crossed by a semi-infinite line.
-     * @param node current node
-     * @param point start point of the part of the line considered
-     * @param line line to consider (contains point)
-     * @return the first sub-hyperplane crossed by the line after the
-     * given point, or null if the line does not intersect any
-     * sub-hyperplane
-     */
-    private SubHyperplane<Euclidean3D> recurseFirstIntersection(final BSPTree<Euclidean3D> node,
-                                                                final Cartesian3D point,
-                                                                final Line line) {
-
-        final SubHyperplane<Euclidean3D> cut = node.getCut();
-        if (cut == null) {
-            return null;
-        }
-        final BSPTree<Euclidean3D> minus = node.getMinus();
-        final BSPTree<Euclidean3D> plus  = node.getPlus();
-        final Plane                plane = (Plane) cut.getHyperplane();
-
-        // establish search order
-        final double offset = plane.getOffset(point);
-        final boolean in    = FastMath.abs(offset) < getTolerance();
-        final BSPTree<Euclidean3D> near;
-        final BSPTree<Euclidean3D> far;
-        if (offset < 0) {
-            near = minus;
-            far  = plus;
-        } else {
-            near = plus;
-            far  = minus;
-        }
-
-        if (in) {
-            // search in the cut hyperplane
-            final SubHyperplane<Euclidean3D> facet = boundaryFacet(point, node);
-            if (facet != null) {
-                return facet;
-            }
-        }
-
-        // search in the near branch
-        final SubHyperplane<Euclidean3D> crossed = recurseFirstIntersection(near, point, line);
-        if (crossed != null) {
-            return crossed;
-        }
-
-        if (!in) {
-            // search in the cut hyperplane
-            final Cartesian3D hit3D = plane.intersection(line);
-            if (hit3D != null && line.getAbscissa(hit3D) > line.getAbscissa(point)) {
-                final SubHyperplane<Euclidean3D> facet = boundaryFacet(hit3D, node);
-                if (facet != null) {
-                    return facet;
-                }
-            }
-        }
-
-        // search in the far branch
-        return recurseFirstIntersection(far, point, line);
-
-    }
-
-    /** Check if a point belongs to the boundary part of a node.
-     * @param point point to check
-     * @param node node containing the boundary facet to check
-     * @return the boundary facet this points belongs to (or null if it
-     * does not belong to any boundary facet)
-     */
-    private SubHyperplane<Euclidean3D> boundaryFacet(final Cartesian3D point,
-                                                     final BSPTree<Euclidean3D> node) {
-        final Cartesian2D point2D = ((Plane) node.getCut().getHyperplane()).toSubSpace(point);
-        @SuppressWarnings("unchecked")
-        final BoundaryAttribute<Euclidean3D> attribute =
-            (BoundaryAttribute<Euclidean3D>) node.getAttribute();
-        if ((attribute.getPlusOutside() != null) &&
-            (((SubPlane) attribute.getPlusOutside()).getRemainingRegion().checkPoint(point2D) == Location.INSIDE)) {
-            return attribute.getPlusOutside();
-        }
-        if ((attribute.getPlusInside() != null) &&
-            (((SubPlane) attribute.getPlusInside()).getRemainingRegion().checkPoint(point2D) == Location.INSIDE)) {
-            return attribute.getPlusInside();
-        }
-        return null;
-    }
-
-    /** Rotate the region around the specified point.
-     * <p>The instance is not modified, a new instance is created.</p>
-     * @param center rotation center
-     * @param rotation vectorial rotation operator
-     * @return a new instance representing the rotated region
-     */
-    public PolyhedronsSet rotate(final Cartesian3D center, final Rotation rotation) {
-        return (PolyhedronsSet) applyTransform(new RotationTransform(center, rotation));
-    }
-
-    /** 3D rotation as a Transform. */
-    private static class RotationTransform implements Transform<Euclidean3D, Euclidean2D> {
-
-        /** Center point of the rotation. */
-        private final Cartesian3D   center;
-
-        /** Vectorial rotation. */
-        private final Rotation   rotation;
-
-        /** Cached original hyperplane. */
-        private Plane cachedOriginal;
-
-        /** Cached 2D transform valid inside the cached original hyperplane. */
-        private Transform<Euclidean2D, Euclidean1D>  cachedTransform;
-
-        /** Build a rotation transform.
-         * @param center center point of the rotation
-         * @param rotation vectorial rotation
-         */
-        RotationTransform(final Cartesian3D center, final Rotation rotation) {
-            this.center   = center;
-            this.rotation = rotation;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Cartesian3D apply(final Point<Euclidean3D> point) {
-            final Cartesian3D delta = ((Cartesian3D) point).subtract(center);
-            return new Cartesian3D(1.0, center, 1.0, rotation.applyTo(delta));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Plane apply(final Hyperplane<Euclidean3D> hyperplane) {
-            return ((Plane) hyperplane).rotate(center, rotation);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public SubHyperplane<Euclidean2D> apply(final SubHyperplane<Euclidean2D> sub,
-                                                final Hyperplane<Euclidean3D> original,
-                                                final Hyperplane<Euclidean3D> transformed) {
-            if (original != cachedOriginal) {
-                // we have changed hyperplane, reset the in-hyperplane transform
-
-                final Plane    oPlane = (Plane) original;
-                final Plane    tPlane = (Plane) transformed;
-                final Cartesian3D p00    = oPlane.getOrigin();
-                final Cartesian3D p10    = oPlane.toSpace(new Cartesian2D(1.0, 0.0));
-                final Cartesian3D p01    = oPlane.toSpace(new Cartesian2D(0.0, 1.0));
-                final Cartesian2D tP00   = tPlane.toSubSpace(apply(p00));
-                final Cartesian2D tP10   = tPlane.toSubSpace(apply(p10));
-                final Cartesian2D tP01   = tPlane.toSubSpace(apply(p01));
-
-                cachedOriginal  = (Plane) original;
-                cachedTransform =
-                        org.apache.commons.math4.geometry.euclidean.twod.Line.getTransform(tP10.getX() - tP00.getX(),
-                                                                                           tP10.getY() - tP00.getY(),
-                                                                                           tP01.getX() - tP00.getX(),
-                                                                                           tP01.getY() - tP00.getY(),
-                                                                                           tP00.getX(),
-                                                                                           tP00.getY());
-
-            }
-            return ((SubLine) sub).applyTransform(cachedTransform);
-        }
-
-    }
-
-    /** Translate the region by the specified amount.
-     * <p>The instance is not modified, a new instance is created.</p>
-     * @param translation translation to apply
-     * @return a new instance representing the translated region
-     */
-    public PolyhedronsSet translate(final Cartesian3D translation) {
-        return (PolyhedronsSet) applyTransform(new TranslationTransform(translation));
-    }
-
-    /** 3D translation as a transform. */
-    private static class TranslationTransform implements Transform<Euclidean3D, Euclidean2D> {
-
-        /** Translation vector. */
-        private final Cartesian3D   translation;
-
-        /** Cached original hyperplane. */
-        private Plane cachedOriginal;
-
-        /** Cached 2D transform valid inside the cached original hyperplane. */
-        private Transform<Euclidean2D, Euclidean1D>  cachedTransform;
-
-        /** Build a translation transform.
-         * @param translation translation vector
-         */
-        TranslationTransform(final Cartesian3D translation) {
-            this.translation = translation;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Cartesian3D apply(final Point<Euclidean3D> point) {
-            return new Cartesian3D(1.0, (Cartesian3D) point, 1.0, translation);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Plane apply(final Hyperplane<Euclidean3D> hyperplane) {
-            return ((Plane) hyperplane).translate(translation);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public SubHyperplane<Euclidean2D> apply(final SubHyperplane<Euclidean2D> sub,
-                                                final Hyperplane<Euclidean3D> original,
-                                                final Hyperplane<Euclidean3D> transformed) {
-            if (original != cachedOriginal) {
-                // we have changed hyperplane, reset the in-hyperplane transform
-
-                final Plane   oPlane = (Plane) original;
-                final Plane   tPlane = (Plane) transformed;
-                final Cartesian2D shift  = tPlane.toSubSpace(apply(oPlane.getOrigin()));
-
-                cachedOriginal  = (Plane) original;
-                cachedTransform =
-                        org.apache.commons.math4.geometry.euclidean.twod.Line.getTransform(1, 0, 0, 1,
-                                                                                           shift.getX(),
-                                                                                           shift.getY());
-
-            }
-
-            return ((SubLine) sub).applyTransform(cachedTransform);
-
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Rotation.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Rotation.java
deleted file mode 100644
index 4d18e52..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Rotation.java
+++ /dev/null
@@ -1,1424 +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 org.apache.commons.numbers.arrays.LinearCombination;
-import org.apache.commons.math4.exception.MathArithmeticException;
-import org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.util.FastMath;
-
-/**
- * This class implements rotations in a three-dimensional space.
- *
- * <p>Rotations can be represented by several different mathematical
- * entities (matrices, axe and angle, Cardan or Euler angles,
- * quaternions). This class presents an higher level abstraction, more
- * user-oriented and hiding this implementation details. Well, for the
- * curious, we use quaternions for the internal representation. The
- * user can build a rotation from any of these representations, and
- * any of these representations can be retrieved from a
- * <code>Rotation</code> instance (see the various constructors and
- * getters). In addition, a rotation can also be built implicitly
- * from a set of vectors and their image.</p>
- * <p>This implies that this class can be used to convert from one
- * representation to another one. For example, converting a rotation
- * matrix into a set of Cardan angles from can be done using the
- * following single line of code:</p>
- * <pre>
- * double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ);
- * </pre>
- * <p>Focus is oriented on what a rotation <em>do</em> rather than on its
- * underlying representation. Once it has been built, and regardless of its
- * internal representation, a rotation is an <em>operator</em> which basically
- * transforms three dimensional {@link Cartesian3D vectors} into other three
- * dimensional {@link Cartesian3D vectors}. Depending on the application, the
- * meaning of these vectors may vary and the semantics of the rotation also.</p>
- * <p>For example in an spacecraft attitude simulation tool, users will often
- * consider the vectors are fixed (say the Earth direction for example) and the
- * frames change. The rotation transforms the coordinates of the vector in inertial
- * frame into the coordinates of the same vector in satellite frame. In this
- * case, the rotation implicitly defines the relation between the two frames.</p>
- * <p>Another example could be a telescope control application, where the rotation
- * would transform the sighting direction at rest into the desired observing
- * direction when the telescope is pointed towards an object of interest. In this
- * case the rotation transforms the direction at rest in a topocentric frame
- * into the sighting direction in the same topocentric frame. This implies in this
- * case the frame is fixed and the vector moves.</p>
- * <p>In many case, both approaches will be combined. In our telescope example,
- * we will probably also need to transform the observing direction in the topocentric
- * frame into the observing direction in inertial frame taking into account the observatory
- * location and the Earth rotation, which would essentially be an application of the
- * first approach.</p>
- *
- * <p>These examples show that a rotation is what the user wants it to be. This
- * class does not push the user towards one specific definition and hence does not
- * provide methods like <code>projectVectorIntoDestinationFrame</code> or
- * <code>computeTransformedDirection</code>. It provides simpler and more generic
- * methods: {@link #applyTo(Cartesian3D) applyTo(Cartesian3D)} and {@link
- * #applyInverseTo(Cartesian3D) applyInverseTo(Cartesian3D)}.</p>
- *
- * <p>Since a rotation is basically a vectorial operator, several rotations can be
- * composed together and the composite operation <code>r = r<sub>1</sub> o
- * r<sub>2</sub></code> (which means that for each vector <code>u</code>,
- * <code>r(u) = r<sub>1</sub>(r<sub>2</sub>(u))</code>) is also a rotation. Hence
- * we can consider that in addition to vectors, a rotation can be applied to other
- * rotations as well (or to itself). With our previous notations, we would say we
- * can apply <code>r<sub>1</sub></code> to <code>r<sub>2</sub></code> and the result
- * we get is <code>r = r<sub>1</sub> o r<sub>2</sub></code>. For this purpose, the
- * class provides the methods: {@link #applyTo(Rotation) applyTo(Rotation)} and
- * {@link #applyInverseTo(Rotation) applyInverseTo(Rotation)}.</p>
- *
- * <p>Rotations are guaranteed to be immutable objects.</p>
- *
- * @see Cartesian3D
- * @see RotationOrder
- * @since 1.2
- */
-
-public class Rotation implements Serializable {
-
-  /** Identity rotation. */
-  public static final Rotation IDENTITY = new Rotation(1.0, 0.0, 0.0, 0.0, false);
-
-  /** Serializable version identifier */
-  private static final long serialVersionUID = -2153622329907944313L;
-
-  /** Scalar coordinate of the quaternion. */
-  private final double q0;
-
-  /** First coordinate of the vectorial part of the quaternion. */
-  private final double q1;
-
-  /** Second coordinate of the vectorial part of the quaternion. */
-  private final double q2;
-
-  /** Third coordinate of the vectorial part of the quaternion. */
-  private final double q3;
-
-  /** Build a rotation from the quaternion coordinates.
-   * <p>A rotation can be built from a <em>normalized</em> quaternion,
-   * i.e. a quaternion for which q<sub>0</sub><sup>2</sup> +
-   * q<sub>1</sub><sup>2</sup> + q<sub>2</sub><sup>2</sup> +
-   * q<sub>3</sub><sup>2</sup> = 1. If the quaternion is not normalized,
-   * the constructor can normalize it in a preprocessing step.</p>
-   * <p>Note that some conventions put the scalar part of the quaternion
-   * as the 4<sup>th</sup> component and the vector part as the first three
-   * components. This is <em>not</em> our convention. We put the scalar part
-   * as the first component.</p>
-   * @param q0 scalar part of the quaternion
-   * @param q1 first coordinate of the vectorial part of the quaternion
-   * @param q2 second coordinate of the vectorial part of the quaternion
-   * @param q3 third coordinate of the vectorial part of the quaternion
-   * @param needsNormalization if true, the coordinates are considered
-   * not to be normalized, a normalization preprocessing step is performed
-   * before using them
-   */
-  public Rotation(double q0, double q1, double q2, double q3,
-                  boolean needsNormalization) {
-
-    if (needsNormalization) {
-      // normalization preprocessing
-      double inv = 1.0 / FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
-      q0 *= inv;
-      q1 *= inv;
-      q2 *= inv;
-      q3 *= inv;
-    }
-
-    this.q0 = q0;
-    this.q1 = q1;
-    this.q2 = q2;
-    this.q3 = q3;
-
-  }
-
-  /** Build a rotation from an axis and an angle.
-   * <p>
-   * Calling this constructor is equivalent to call
-   * {@link #Rotation(Cartesian3D, double, RotationConvention)
-   * new Rotation(axis, angle, RotationConvention.VECTOR_OPERATOR)}
-   * </p>
-   * @param axis axis around which to rotate
-   * @param angle rotation angle.
-   * @exception MathIllegalArgumentException if the axis norm is zero
-   * @deprecated as of 3.6, replaced with {@link #Rotation(Cartesian3D, double, RotationConvention)}
-   */
-  @Deprecated
-  public Rotation(Cartesian3D axis, double angle) throws MathIllegalArgumentException {
-      this(axis, angle, RotationConvention.VECTOR_OPERATOR);
-  }
-
-  /** Build a rotation from an axis and an angle.
-   * @param axis axis around which to rotate
-   * @param angle rotation angle
-   * @param convention convention to use for the semantics of the angle
-   * @exception MathIllegalArgumentException if the axis norm is zero
-   * @since 3.6
-   */
-  public Rotation(final Cartesian3D axis, final double angle, final RotationConvention convention)
-      throws MathIllegalArgumentException {
-
-    double norm = axis.getNorm();
-    if (norm == 0) {
-      throw new MathIllegalArgumentException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_AXIS);
-    }
-
-    double halfAngle = convention == RotationConvention.VECTOR_OPERATOR ? -0.5 * angle : +0.5 * angle;
-    double coeff = FastMath.sin(halfAngle) / norm;
-
-    q0 = FastMath.cos (halfAngle);
-    q1 = coeff * axis.getX();
-    q2 = coeff * axis.getY();
-    q3 = coeff * axis.getZ();
-
-  }
-
-  /** Build a rotation from a 3X3 matrix.
-
-   * <p>Rotation matrices are orthogonal matrices, i.e. unit matrices
-   * (which are matrices for which m.m<sup>T</sup> = I) with real
-   * coefficients. The module of the determinant of unit matrices is
-   * 1, among the orthogonal 3X3 matrices, only the ones having a
-   * positive determinant (+1) are rotation matrices.</p>
-
-   * <p>When a rotation is defined by a matrix with truncated values
-   * (typically when it is extracted from a technical sheet where only
-   * four to five significant digits are available), the matrix is not
-   * orthogonal anymore. This constructor handles this case
-   * transparently by using a copy of the given matrix and applying a
-   * correction to the copy in order to perfect its orthogonality. If
-   * the Frobenius norm of the correction needed is above the given
-   * threshold, then the matrix is considered to be too far from a
-   * true rotation matrix and an exception is thrown.<p>
-
-   * @param m rotation matrix
-   * @param threshold convergence threshold for the iterative
-   * orthogonality correction (convergence is reached when the
-   * difference between two steps of the Frobenius norm of the
-   * correction is below this threshold)
-
-   * @exception NotARotationMatrixException if the matrix is not a 3X3
-   * matrix, or if it cannot be transformed into an orthogonal matrix
-   * with the given threshold, or if the determinant of the resulting
-   * orthogonal matrix is negative
-
-   */
-  public Rotation(double[][] m, double threshold)
-    throws NotARotationMatrixException {
-
-    // dimension check
-    if ((m.length != 3) || (m[0].length != 3) ||
-        (m[1].length != 3) || (m[2].length != 3)) {
-      throw new NotARotationMatrixException(
-              LocalizedFormats.ROTATION_MATRIX_DIMENSIONS,
-              m.length, m[0].length);
-    }
-
-    // compute a "close" orthogonal matrix
-    double[][] ort = orthogonalizeMatrix(m, threshold);
-
-    // check the sign of the determinant
-    double det = ort[0][0] * (ort[1][1] * ort[2][2] - ort[2][1] * ort[1][2]) -
-                 ort[1][0] * (ort[0][1] * ort[2][2] - ort[2][1] * ort[0][2]) +
-                 ort[2][0] * (ort[0][1] * ort[1][2] - ort[1][1] * ort[0][2]);
-    if (det < 0.0) {
-      throw new NotARotationMatrixException(
-              LocalizedFormats.CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT,
-              det);
-    }
-
-    double[] quat = mat2quat(ort);
-    q0 = quat[0];
-    q1 = quat[1];
-    q2 = quat[2];
-    q3 = quat[3];
-
-  }
-
-  /** Build the rotation that transforms a pair of vectors into another pair.
-
-   * <p>Except for possible scale factors, if the instance were applied to
-   * the pair (u<sub>1</sub>, u<sub>2</sub>) it will produce the pair
-   * (v<sub>1</sub>, v<sub>2</sub>).</p>
-
-   * <p>If the angular separation between u<sub>1</sub> and u<sub>2</sub> is
-   * not the same as the angular separation between v<sub>1</sub> and
-   * v<sub>2</sub>, then a corrected v'<sub>2</sub> will be used rather than
-   * v<sub>2</sub>, the corrected vector will be in the (&plusmn;v<sub>1</sub>,
-   * +v<sub>2</sub>) half-plane.</p>
-
-   * @param u1 first vector of the origin pair
-   * @param u2 second vector of the origin pair
-   * @param v1 desired image of u1 by the rotation
-   * @param v2 desired image of u2 by the rotation
-   * @exception MathArithmeticException if the norm of one of the vectors is zero,
-   * or if one of the pair is degenerated (i.e. the vectors of the pair are collinear)
-   */
-  public Rotation(Cartesian3D u1, Cartesian3D u2, Cartesian3D v1, Cartesian3D v2)
-      throws MathArithmeticException {
-
-      // build orthonormalized base from u1, u2
-      // this fails when vectors are null or collinear, which is forbidden to define a rotation
-      final Cartesian3D u3 = u1.crossProduct(u2).normalize();
-      u2 = u3.crossProduct(u1).normalize();
-      u1 = u1.normalize();
-
-      // build an orthonormalized base from v1, v2
-      // this fails when vectors are null or collinear, which is forbidden to define a rotation
-      final Cartesian3D v3 = v1.crossProduct(v2).normalize();
-      v2 = v3.crossProduct(v1).normalize();
-      v1 = v1.normalize();
-
-      // buid a matrix transforming the first base into the second one
-      final double[][] m = new double[][] {
-          {
-              LinearCombination.value(u1.getX(), v1.getX(), u2.getX(), v2.getX(), u3.getX(), v3.getX()),
-              LinearCombination.value(u1.getY(), v1.getX(), u2.getY(), v2.getX(), u3.getY(), v3.getX()),
-              LinearCombination.value(u1.getZ(), v1.getX(), u2.getZ(), v2.getX(), u3.getZ(), v3.getX())
-          },
-          {
-              LinearCombination.value(u1.getX(), v1.getY(), u2.getX(), v2.getY(), u3.getX(), v3.getY()),
-              LinearCombination.value(u1.getY(), v1.getY(), u2.getY(), v2.getY(), u3.getY(), v3.getY()),
-              LinearCombination.value(u1.getZ(), v1.getY(), u2.getZ(), v2.getY(), u3.getZ(), v3.getY())
-          },
-          {
-              LinearCombination.value(u1.getX(), v1.getZ(), u2.getX(), v2.getZ(), u3.getX(), v3.getZ()),
-              LinearCombination.value(u1.getY(), v1.getZ(), u2.getY(), v2.getZ(), u3.getY(), v3.getZ()),
-              LinearCombination.value(u1.getZ(), v1.getZ(), u2.getZ(), v2.getZ(), u3.getZ(), v3.getZ())
-          }
-      };
-
-      double[] quat = mat2quat(m);
-      q0 = quat[0];
-      q1 = quat[1];
-      q2 = quat[2];
-      q3 = quat[3];
-
-  }
-
-  /** Build one of the rotations that transform one vector into another one.
-
-   * <p>Except for a possible scale factor, if the instance were
-   * applied to the vector u it will produce the vector v. There is an
-   * infinite number of such rotations, this constructor choose the
-   * one with the smallest associated angle (i.e. the one whose axis
-   * is orthogonal to the (u, v) plane). If u and v are collinear, an
-   * arbitrary rotation axis is chosen.</p>
-
-   * @param u origin vector
-   * @param v desired image of u by the rotation
-   * @exception MathArithmeticException if the norm of one of the vectors is zero
-   */
-  public Rotation(Cartesian3D u, Cartesian3D v) throws MathArithmeticException {
-
-    double normProduct = u.getNorm() * v.getNorm();
-    if (normProduct == 0) {
-        throw new MathArithmeticException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR);
-    }
-
-    double dot = u.dotProduct(v);
-
-    if (dot < ((2.0e-15 - 1.0) * normProduct)) {
-      // special case u = -v: we select a PI angle rotation around
-      // an arbitrary vector orthogonal to u
-      Cartesian3D w = u.orthogonal();
-      q0 = 0.0;
-      q1 = -w.getX();
-      q2 = -w.getY();
-      q3 = -w.getZ();
-    } else {
-      // general case: (u, v) defines a plane, we select
-      // the shortest possible rotation: axis orthogonal to this plane
-      q0 = FastMath.sqrt(0.5 * (1.0 + dot / normProduct));
-      double coeff = 1.0 / (2.0 * q0 * normProduct);
-      Cartesian3D q = v.crossProduct(u);
-      q1 = coeff * q.getX();
-      q2 = coeff * q.getY();
-      q3 = coeff * q.getZ();
-    }
-
-  }
-
-  /** Build a rotation from three Cardan or Euler elementary rotations.
-
-   * <p>
-   * Calling this constructor is equivalent to call
-   * {@link #Rotation(RotationOrder, RotationConvention, double, double, double)
-   * new Rotation(order, RotationConvention.VECTOR_OPERATOR, alpha1, alpha2, alpha3)}
-   * </p>
-
-   * @param order order of rotations to use
-   * @param alpha1 angle of the first elementary rotation
-   * @param alpha2 angle of the second elementary rotation
-   * @param alpha3 angle of the third elementary rotation
-   * @deprecated as of 3.6, replaced with {@link
-   * #Rotation(RotationOrder, RotationConvention, double, double, double)}
-   */
-  @Deprecated
-  public Rotation(RotationOrder order,
-                  double alpha1, double alpha2, double alpha3) {
-      this(order, RotationConvention.VECTOR_OPERATOR, alpha1, alpha2, alpha3);
-  }
-
-  /** Build a rotation from three Cardan or Euler elementary rotations.
-
-   * <p>Cardan rotations are three successive rotations around the
-   * canonical axes X, Y and Z, each axis being used once. There are
-   * 6 such sets of rotations (XYZ, XZY, YXZ, YZX, ZXY and ZYX). Euler
-   * rotations are three successive rotations around the canonical
-   * axes X, Y and Z, the first and last rotations being around the
-   * same axis. There are 6 such sets of rotations (XYX, XZX, YXY,
-   * YZY, ZXZ and ZYZ), the most popular one being ZXZ.</p>
-   * <p>Beware that many people routinely use the term Euler angles even
-   * for what really are Cardan angles (this confusion is especially
-   * widespread in the aerospace business where Roll, Pitch and Yaw angles
-   * are often wrongly tagged as Euler angles).</p>
-
-   * @param order order of rotations to compose, from left to right
-   * (i.e. we will use {@code r1.compose(r2.compose(r3, convention), convention)})
-   * @param convention convention to use for the semantics of the angle
-   * @param alpha1 angle of the first elementary rotation
-   * @param alpha2 angle of the second elementary rotation
-   * @param alpha3 angle of the third elementary rotation
-   * @since 3.6
-   */
-  public Rotation(RotationOrder order, RotationConvention convention,
-                  double alpha1, double alpha2, double alpha3) {
-      Rotation r1 = new Rotation(order.getA1(), alpha1, convention);
-      Rotation r2 = new Rotation(order.getA2(), alpha2, convention);
-      Rotation r3 = new Rotation(order.getA3(), alpha3, convention);
-      Rotation composed = r1.compose(r2.compose(r3, convention), convention);
-      q0 = composed.q0;
-      q1 = composed.q1;
-      q2 = composed.q2;
-      q3 = composed.q3;
-  }
-
-  /** Convert an orthogonal rotation matrix to a quaternion.
-   * @param ort orthogonal rotation matrix
-   * @return quaternion corresponding to the matrix
-   */
-  private static double[] mat2quat(final double[][] ort) {
-
-      final double[] quat = new double[4];
-
-      // There are different ways to compute the quaternions elements
-      // from the matrix. They all involve computing one element from
-      // the diagonal of the matrix, and computing the three other ones
-      // using a formula involving a division by the first element,
-      // which unfortunately can be zero. Since the norm of the
-      // quaternion is 1, we know at least one element has an absolute
-      // value greater or equal to 0.5, so it is always possible to
-      // select the right formula and avoid division by zero and even
-      // numerical inaccuracy. Checking the elements in turn and using
-      // the first one greater than 0.45 is safe (this leads to a simple
-      // test since qi = 0.45 implies 4 qi^2 - 1 = -0.19)
-      double s = ort[0][0] + ort[1][1] + ort[2][2];
-      if (s > -0.19) {
-          // compute q0 and deduce q1, q2 and q3
-          quat[0] = 0.5 * FastMath.sqrt(s + 1.0);
-          double inv = 0.25 / quat[0];
-          quat[1] = inv * (ort[1][2] - ort[2][1]);
-          quat[2] = inv * (ort[2][0] - ort[0][2]);
-          quat[3] = inv * (ort[0][1] - ort[1][0]);
-      } else {
-          s = ort[0][0] - ort[1][1] - ort[2][2];
-          if (s > -0.19) {
-              // compute q1 and deduce q0, q2 and q3
-              quat[1] = 0.5 * FastMath.sqrt(s + 1.0);
-              double inv = 0.25 / quat[1];
-              quat[0] = inv * (ort[1][2] - ort[2][1]);
-              quat[2] = inv * (ort[0][1] + ort[1][0]);
-              quat[3] = inv * (ort[0][2] + ort[2][0]);
-          } else {
-              s = ort[1][1] - ort[0][0] - ort[2][2];
-              if (s > -0.19) {
-                  // compute q2 and deduce q0, q1 and q3
-                  quat[2] = 0.5 * FastMath.sqrt(s + 1.0);
-                  double inv = 0.25 / quat[2];
-                  quat[0] = inv * (ort[2][0] - ort[0][2]);
-                  quat[1] = inv * (ort[0][1] + ort[1][0]);
-                  quat[3] = inv * (ort[2][1] + ort[1][2]);
-              } else {
-                  // compute q3 and deduce q0, q1 and q2
-                  s = ort[2][2] - ort[0][0] - ort[1][1];
-                  quat[3] = 0.5 * FastMath.sqrt(s + 1.0);
-                  double inv = 0.25 / quat[3];
-                  quat[0] = inv * (ort[0][1] - ort[1][0]);
-                  quat[1] = inv * (ort[0][2] + ort[2][0]);
-                  quat[2] = inv * (ort[2][1] + ort[1][2]);
-              }
-          }
-      }
-
-      return quat;
-
-  }
-
-  /** Revert a rotation.
-   * Build a rotation which reverse the effect of another
-   * rotation. This means that if r(u) = v, then r.revert(v) = u. The
-   * instance is not changed.
-   * @return a new rotation whose effect is the reverse of the effect
-   * of the instance
-   */
-  public Rotation revert() {
-    return new Rotation(-q0, q1, q2, q3, false);
-  }
-
-  /** Get the scalar coordinate of the quaternion.
-   * @return scalar coordinate of the quaternion
-   */
-  public double getQ0() {
-    return q0;
-  }
-
-  /** Get the first coordinate of the vectorial part of the quaternion.
-   * @return first coordinate of the vectorial part of the quaternion
-   */
-  public double getQ1() {
-    return q1;
-  }
-
-  /** Get the second coordinate of the vectorial part of the quaternion.
-   * @return second coordinate of the vectorial part of the quaternion
-   */
-  public double getQ2() {
-    return q2;
-  }
-
-  /** Get the third coordinate of the vectorial part of the quaternion.
-   * @return third coordinate of the vectorial part of the quaternion
-   */
-  public double getQ3() {
-    return q3;
-  }
-
-  /** Get the normalized axis of the rotation.
-   * <p>
-   * Calling this method is equivalent to call
-   * {@link #getAxis(RotationConvention) getAxis(RotationConvention.VECTOR_OPERATOR)}
-   * </p>
-   * @return normalized axis of the rotation
-   * @see #Rotation(Cartesian3D, double, RotationConvention)
-   * @deprecated as of 3.6, replaced with {@link #getAxis(RotationConvention)}
-   */
-  @Deprecated
-  public Cartesian3D getAxis() {
-    return getAxis(RotationConvention.VECTOR_OPERATOR);
-  }
-
-  /** Get the normalized axis of the rotation.
-   * <p>
-   * Note that as {@link #getAngle()} always returns an angle
-   * between 0 and &pi;, changing the convention changes the
-   * direction of the axis, not the sign of the angle.
-   * </p>
-   * @param convention convention to use for the semantics of the angle
-   * @return normalized axis of the rotation
-   * @see #Rotation(Cartesian3D, double, RotationConvention)
-   * @since 3.6
-   */
-  public Cartesian3D getAxis(final RotationConvention convention) {
-    final double squaredSine = q1 * q1 + q2 * q2 + q3 * q3;
-    if (squaredSine == 0) {
-      return convention == RotationConvention.VECTOR_OPERATOR ? Cartesian3D.PLUS_I : Cartesian3D.MINUS_I;
-    } else {
-        final double sgn = convention == RotationConvention.VECTOR_OPERATOR ? +1 : -1;
-        if (q0 < 0) {
-            final double inverse = sgn / FastMath.sqrt(squaredSine);
-            return new Cartesian3D(q1 * inverse, q2 * inverse, q3 * inverse);
-        }
-        final double inverse = -sgn / FastMath.sqrt(squaredSine);
-        return new Cartesian3D(q1 * inverse, q2 * inverse, q3 * inverse);
-    }
-  }
-
-  /** Get the angle of the rotation.
-   * @return angle of the rotation (between 0 and &pi;)
-   * @see #Rotation(Cartesian3D, double)
-   */
-  public double getAngle() {
-    if ((q0 < -0.1) || (q0 > 0.1)) {
-      return 2 * FastMath.asin(FastMath.sqrt(q1 * q1 + q2 * q2 + q3 * q3));
-    } else if (q0 < 0) {
-      return 2 * FastMath.acos(-q0);
-    }
-    return 2 * FastMath.acos(q0);
-  }
-
-  /** Get the Cardan or Euler angles corresponding to the instance.
-
-   * <p>
-   * Calling this method is equivalent to call
-   * {@link #getAngles(RotationOrder, RotationConvention)
-   * getAngles(order, RotationConvention.VECTOR_OPERATOR)}
-   * </p>
-
-   * @param order rotation order to use
-   * @return an array of three angles, in the order specified by the set
-   * @exception CardanEulerSingularityException if the rotation is
-   * singular with respect to the angles set specified
-   * @deprecated as of 3.6, replaced with {@link #getAngles(RotationOrder, RotationConvention)}
-   */
-  @Deprecated
-  public double[] getAngles(RotationOrder order)
-      throws CardanEulerSingularityException {
-      return getAngles(order, RotationConvention.VECTOR_OPERATOR);
-  }
-
-  /** Get the Cardan or Euler angles corresponding to the instance.
-
-   * <p>The equations show that each rotation can be defined by two
-   * different values of the Cardan or Euler angles set. For example
-   * if Cardan angles are used, the rotation defined by the angles
-   * a<sub>1</sub>, a<sub>2</sub> and a<sub>3</sub> is the same as
-   * the rotation defined by the angles &pi; + a<sub>1</sub>, &pi;
-   * - a<sub>2</sub> and &pi; + a<sub>3</sub>. This method implements
-   * the following arbitrary choices:</p>
-   * <ul>
-   *   <li>for Cardan angles, the chosen set is the one for which the
-   *   second angle is between -&pi;/2 and &pi;/2 (i.e its cosine is
-   *   positive),</li>
-   *   <li>for Euler angles, the chosen set is the one for which the
-   *   second angle is between 0 and &pi; (i.e its sine is positive).</li>
-   * </ul>
-
-   * <p>Cardan and Euler angle have a very disappointing drawback: all
-   * of them have singularities. This means that if the instance is
-   * too close to the singularities corresponding to the given
-   * rotation order, it will be impossible to retrieve the angles. For
-   * Cardan angles, this is often called gimbal lock. There is
-   * <em>nothing</em> to do to prevent this, it is an intrinsic problem
-   * with Cardan and Euler representation (but not a problem with the
-   * rotation itself, which is perfectly well defined). For Cardan
-   * angles, singularities occur when the second angle is close to
-   * -&pi;/2 or +&pi;/2, for Euler angle singularities occur when the
-   * second angle is close to 0 or &pi;, this implies that the identity
-   * rotation is always singular for Euler angles!</p>
-
-   * @param order rotation order to use
-   * @param convention convention to use for the semantics of the angle
-   * @return an array of three angles, in the order specified by the set
-   * @exception CardanEulerSingularityException if the rotation is
-   * singular with respect to the angles set specified
-   * @since 3.6
-   */
-  public double[] getAngles(RotationOrder order, RotationConvention convention)
-      throws CardanEulerSingularityException {
-
-      if (convention == RotationConvention.VECTOR_OPERATOR) {
-          if (order == RotationOrder.XYZ) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  sin (theta), -cos (theta) sin (phi), cos (theta) cos (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if  ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-(v1.getY()), v1.getZ()),
-                  FastMath.asin(v2.getZ()),
-                  FastMath.atan2(-(v2.getY()), v2.getX())
-              };
-
-          } else if (order == RotationOrder.XZY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // -sin (psi), cos (psi) cos (phi), cos (psi) sin (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getZ(), v1.getY()),
-                 -FastMath.asin(v2.getY()),
-                  FastMath.atan2(v2.getZ(), v2.getX())
-              };
-
-          } else if (order == RotationOrder.YXZ) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  cos (phi) sin (theta), -sin (phi), cos (phi) cos (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getX(), v1.getZ()),
-                 -FastMath.asin(v2.getZ()),
-                  FastMath.atan2(v2.getX(), v2.getY())
-              };
-
-          } else if (order == RotationOrder.YZX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              // cos (psi) cos (theta), sin (psi), -cos (psi) sin (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-(v1.getZ()), v1.getX()),
-                  FastMath.asin(v2.getX()),
-                  FastMath.atan2(-(v2.getZ()), v2.getY())
-              };
-
-          } else if (order == RotationOrder.ZXY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // -cos (phi) sin (psi), cos (phi) cos (psi), sin (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-(v1.getX()), v1.getY()),
-                  FastMath.asin(v2.getY()),
-                  FastMath.atan2(-(v2.getX()), v2.getZ())
-              };
-
-          } else if (order == RotationOrder.ZYX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (theta) cos (psi), cos (theta) sin (psi), -sin (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getY(), v1.getX()),
-                 -FastMath.asin(v2.getX()),
-                  FastMath.atan2(v2.getY(), v2.getZ())
-              };
-
-          } else if (order == RotationOrder.XYX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (theta), sin (phi1) sin (theta), -cos (phi1) sin (theta)
-              // (-r) (Cartesian3D.plusI) coordinates are :
-              // cos (theta), sin (theta) sin (phi2), sin (theta) cos (phi2)
-              // and we can choose to have theta in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getY(), -v1.getZ()),
-                  FastMath.acos(v2.getX()),
-                  FastMath.atan2(v2.getY(), v2.getZ())
-              };
-
-          } else if (order == RotationOrder.XZX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (psi), cos (phi1) sin (psi), sin (phi1) sin (psi)
-              // (-r) (Cartesian3D.plusI) coordinates are :
-              // cos (psi), -sin (psi) cos (phi2), sin (psi) sin (phi2)
-              // and we can choose to have psi in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getZ(), v1.getY()),
-                  FastMath.acos(v2.getX()),
-                  FastMath.atan2(v2.getZ(), -v2.getY())
-              };
-
-          } else if (order == RotationOrder.YXY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              //  sin (theta1) sin (phi), cos (phi), cos (theta1) sin (phi)
-              // (-r) (Cartesian3D.plusJ) coordinates are :
-              // sin (phi) sin (theta2), cos (phi), -sin (phi) cos (theta2)
-              // and we can choose to have phi in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getX(), v1.getZ()),
-                  FastMath.acos(v2.getY()),
-                  FastMath.atan2(v2.getX(), -v2.getZ())
-              };
-
-          } else if (order == RotationOrder.YZY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              //  -cos (theta1) sin (psi), cos (psi), sin (theta1) sin (psi)
-              // (-r) (Cartesian3D.plusJ) coordinates are :
-              // sin (psi) cos (theta2), cos (psi), sin (psi) sin (theta2)
-              // and we can choose to have psi in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getZ(), -v1.getX()),
-                  FastMath.acos(v2.getY()),
-                  FastMath.atan2(v2.getZ(), v2.getX())
-              };
-
-          } else if (order == RotationOrder.ZXZ) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  sin (psi1) sin (phi), -cos (psi1) sin (phi), cos (phi)
-              // (-r) (Cartesian3D.plusK) coordinates are :
-              // sin (phi) sin (psi2), sin (phi) cos (psi2), cos (phi)
-              // and we can choose to have phi in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getX(), -v1.getY()),
-                  FastMath.acos(v2.getZ()),
-                  FastMath.atan2(v2.getX(), v2.getY())
-              };
-
-          } else { // last possibility is ZYZ
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  cos (psi1) sin (theta), sin (psi1) sin (theta), cos (theta)
-              // (-r) (Cartesian3D.plusK) coordinates are :
-              // -sin (theta) cos (psi2), sin (theta) sin (psi2), cos (theta)
-              // and we can choose to have theta in the interval [0 ; PI]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v1.getY(), v1.getX()),
-                  FastMath.acos(v2.getZ()),
-                  FastMath.atan2(v2.getY(), -v2.getX())
-              };
-
-          }
-      } else {
-          if (order == RotationOrder.XYZ) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (theta) cos (psi), -cos (theta) sin (psi), sin (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-v2.getY(), v2.getZ()),
-                  FastMath.asin(v2.getX()),
-                  FastMath.atan2(-v1.getY(), v1.getX())
-              };
-
-          } else if (order == RotationOrder.XZY) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              // cos (psi) cos (theta), -sin (psi), cos (psi) sin (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getZ(), v2.getY()),
-                 -FastMath.asin(v2.getX()),
-                  FastMath.atan2(v1.getZ(), v1.getX())
-              };
-
-          } else if (order == RotationOrder.YXZ) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // cos (phi) sin (psi), cos (phi) cos (psi), -sin (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getX(), v2.getZ()),
-                 -FastMath.asin(v2.getY()),
-                  FastMath.atan2(v1.getX(), v1.getY())
-              };
-
-          } else if (order == RotationOrder.YZX) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // sin (psi), cos (psi) cos (phi), -cos (psi) sin (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-v2.getZ(), v2.getX()),
-                  FastMath.asin(v2.getY()),
-                  FastMath.atan2(-v1.getZ(), v1.getY())
-              };
-
-          } else if (order == RotationOrder.ZXY) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  -cos (phi) sin (theta), sin (phi), cos (phi) cos (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(-v2.getX(), v2.getY()),
-                  FastMath.asin(v2.getZ()),
-                  FastMath.atan2(-v1.getX(), v1.getZ())
-              };
-
-          } else if (order == RotationOrder.ZYX) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              //  -sin (theta), cos (theta) sin (phi), cos (theta) cos (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if  ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(true);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getY(), v2.getX()),
-                 -FastMath.asin(v2.getZ()),
-                  FastMath.atan2(v1.getY(), v1.getZ())
-              };
-
-          } else if (order == RotationOrder.XYX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (theta), sin (phi2) sin (theta), cos (phi2) sin (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getY(), -v2.getZ()),
-                  FastMath.acos(v2.getX()),
-                  FastMath.atan2(v1.getY(), v1.getZ())
-              };
-
-          } else if (order == RotationOrder.XZX) {
-
-              // r (Cartesian3D.plusI) coordinates are :
-              //  cos (psi), -cos (phi2) sin (psi), sin (phi2) sin (psi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_I);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_I);
-              if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getZ(), v2.getY()),
-                  FastMath.acos(v2.getX()),
-                  FastMath.atan2(v1.getZ(), -v1.getY())
-              };
-
-          } else if (order == RotationOrder.YXY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // sin (phi) sin (theta2), cos (phi), -sin (phi) cos (theta2)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getX(), v2.getZ()),
-                  FastMath.acos(v2.getY()),
-                  FastMath.atan2(v1.getX(), -v1.getZ())
-              };
-
-          } else if (order == RotationOrder.YZY) {
-
-              // r (Cartesian3D.plusJ) coordinates are :
-              // sin (psi) cos (theta2), cos (psi), sin (psi) sin (theta2)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_J);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_J);
-              if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getZ(), -v2.getX()),
-                  FastMath.acos(v2.getY()),
-                  FastMath.atan2(v1.getZ(), v1.getX())
-              };
-
-          } else if (order == RotationOrder.ZXZ) {
-
-              // r (Cartesian3D.plusK) coordinates are :
-              // sin (phi) sin (psi2), sin (phi) cos (psi2), cos (phi)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getX(), -v2.getY()),
-                  FastMath.acos(v2.getZ()),
-                  FastMath.atan2(v1.getX(), v1.getY())
-              };
-
-          } else { // last possibility is ZYZ
-
-              // r (Cartesian3D.plusK) coordinates are :
-              // -sin (theta) cos (psi2), sin (theta) sin (psi2), cos (theta)
-              // (-r) (Cartesian3D.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]
-              Cartesian3D v1 = applyTo(Cartesian3D.PLUS_K);
-              Cartesian3D v2 = applyInverseTo(Cartesian3D.PLUS_K);
-              if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
-                  throw new CardanEulerSingularityException(false);
-              }
-              return new double[] {
-                  FastMath.atan2(v2.getY(), v2.getX()),
-                  FastMath.acos(v2.getZ()),
-                  FastMath.atan2(v1.getY(), -v1.getX())
-              };
-
-          }
-      }
-
-  }
-
-  /** Get the 3X3 matrix corresponding to the instance
-   * @return the matrix corresponding to the instance
-   */
-  public double[][] getMatrix() {
-
-    // products
-    double q0q0  = q0 * q0;
-    double q0q1  = q0 * q1;
-    double q0q2  = q0 * q2;
-    double q0q3  = q0 * q3;
-    double q1q1  = q1 * q1;
-    double q1q2  = q1 * q2;
-    double q1q3  = q1 * q3;
-    double q2q2  = q2 * q2;
-    double q2q3  = q2 * q3;
-    double q3q3  = q3 * q3;
-
-    // create the matrix
-    double[][] m = new double[3][];
-    m[0] = new double[3];
-    m[1] = new double[3];
-    m[2] = new double[3];
-
-    m [0][0] = 2.0 * (q0q0 + q1q1) - 1.0;
-    m [1][0] = 2.0 * (q1q2 - q0q3);
-    m [2][0] = 2.0 * (q1q3 + q0q2);
-
-    m [0][1] = 2.0 * (q1q2 + q0q3);
-    m [1][1] = 2.0 * (q0q0 + q2q2) - 1.0;
-    m [2][1] = 2.0 * (q2q3 - q0q1);
-
-    m [0][2] = 2.0 * (q1q3 - q0q2);
-    m [1][2] = 2.0 * (q2q3 + q0q1);
-    m [2][2] = 2.0 * (q0q0 + q3q3) - 1.0;
-
-    return m;
-
-  }
-
-  /** Apply the rotation to a vector.
-   * @param u vector to apply the rotation to
-   * @return a new vector which is the image of u by the rotation
-   */
-  public Cartesian3D applyTo(Cartesian3D u) {
-
-    double x = u.getX();
-    double y = u.getY();
-    double z = u.getZ();
-
-    double s = q1 * x + q2 * y + q3 * z;
-
-    return new Cartesian3D(2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x,
-                        2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y,
-                        2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z);
-
-  }
-
-  /** Apply the rotation to a vector stored in an array.
-   * @param in an array with three items which stores vector to rotate
-   * @param out an array with three items to put result to (it can be the same
-   * array as in)
-   */
-  public void applyTo(final double[] in, final double[] out) {
-
-      final double x = in[0];
-      final double y = in[1];
-      final double z = in[2];
-
-      final double s = q1 * x + q2 * y + q3 * z;
-
-      out[0] = 2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x;
-      out[1] = 2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y;
-      out[2] = 2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z;
-
-  }
-
-  /** Apply the inverse of the rotation to a vector.
-   * @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 Cartesian3D applyInverseTo(Cartesian3D u) {
-
-    double x = u.getX();
-    double y = u.getY();
-    double z = u.getZ();
-
-    double s = q1 * x + q2 * y + q3 * z;
-    double m0 = -q0;
-
-    return new Cartesian3D(2 * (m0 * (x * m0 - (q2 * z - q3 * y)) + s * q1) - x,
-                        2 * (m0 * (y * m0 - (q3 * x - q1 * z)) + s * q2) - y,
-                        2 * (m0 * (z * m0 - (q1 * y - q2 * x)) + s * q3) - z);
-
-  }
-
-  /** Apply the inverse of the rotation to a vector stored in an array.
-   * @param in an array with three items which stores vector to rotate
-   * @param out an array with three items to put result to (it can be the same
-   * array as in)
-   */
-  public void applyInverseTo(final double[] in, final double[] out) {
-
-      final double x = in[0];
-      final double y = in[1];
-      final double z = in[2];
-
-      final double s = q1 * x + q2 * y + q3 * z;
-      final double m0 = -q0;
-
-      out[0] = 2 * (m0 * (x * m0 - (q2 * z - q3 * y)) + s * q1) - x;
-      out[1] = 2 * (m0 * (y * m0 - (q3 * x - q1 * z)) + s * q2) - y;
-      out[2] = 2 * (m0 * (z * m0 - (q1 * y - q2 * x)) + s * q3) - z;
-
-  }
-
-  /** Apply the instance to another rotation.
-   * <p>
-   * Calling this method is equivalent to call
-   * {@link #compose(Rotation, RotationConvention)
-   * compose(r, RotationConvention.VECTOR_OPERATOR)}.
-   * </p>
-   * @param r rotation to apply the rotation to
-   * @return a new rotation which is the composition of r by the instance
-   */
-  public Rotation applyTo(Rotation r) {
-    return compose(r, RotationConvention.VECTOR_OPERATOR);
-  }
-
-  /** Compose the instance with another rotation.
-   * <p>
-   * If the semantics of the rotations composition corresponds to a
-   * {@link RotationConvention#VECTOR_OPERATOR vector operator} convention,
-   * applying the instance to a rotation is computing the composition
-   * in an order compliant with the following rule : let {@code u} be any
-   * vector and {@code v} its image by {@code r1} (i.e.
-   * {@code r1.applyTo(u) = v}). Let {@code w} be the image of {@code v} by
-   * rotation {@code r2} (i.e. {@code r2.applyTo(v) = w}). Then
-   * {@code w = comp.applyTo(u)}, where
-   * {@code comp = r2.compose(r1, RotationConvention.VECTOR_OPERATOR)}.
-   * </p>
-   * <p>
-   * If the semantics of the rotations composition corresponds to a
-   * {@link RotationConvention#FRAME_TRANSFORM frame transform} convention,
-   * the application order will be reversed. So keeping the exact same
-   * meaning of all {@code r1}, {@code r2}, {@code u}, {@code v}, {@code w}
-   * and  {@code comp} as above, {@code comp} could also be computed as
-   * {@code comp = r1.compose(r2, RotationConvention.FRAME_TRANSFORM)}.
-   * </p>
-   * @param r rotation to apply the rotation to
-   * @param convention convention to use for the semantics of the angle
-   * @return a new rotation which is the composition of r by the instance
-   */
-  public Rotation compose(final Rotation r, final RotationConvention convention) {
-    return convention == RotationConvention.VECTOR_OPERATOR ?
-           composeInternal(r) : r.composeInternal(this);
-  }
-
-  /** Compose the instance with another rotation using vector operator convention.
-   * @param r rotation to apply the rotation to
-   * @return a new rotation which is the composition of r by the instance
-   * using vector operator convention
-   */
-  private Rotation composeInternal(final Rotation r) {
-    return new Rotation(r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3),
-                        r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2),
-                        r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3),
-                        r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1),
-                        false);
-  }
-
-  /** Apply the inverse of the instance to another rotation.
-   * <p>
-   * Calling this method is equivalent to call
-   * {@link #composeInverse(Rotation, RotationConvention)
-   * composeInverse(r, RotationConvention.VECTOR_OPERATOR)}.
-   * </p>
-   * @param r rotation to apply the rotation to
-   * @return a new rotation which is the composition of r by the inverse
-   * of the instance
-   */
-  public Rotation applyInverseTo(Rotation r) {
-    return composeInverse(r, RotationConvention.VECTOR_OPERATOR);
-  }
-
-  /** Compose the inverse of the instance with another rotation.
-   * <p>
-   * If the semantics of the rotations composition corresponds to a
-   * {@link RotationConvention#VECTOR_OPERATOR vector operator} convention,
-   * applying the inverse of the instance to a rotation is computing
-   * the composition in an order compliant with the following rule :
-   * let {@code u} be any vector and {@code v} its image by {@code r1}
-   * (i.e. {@code r1.applyTo(u) = v}). Let {@code w} be the inverse image
-   * of {@code v} by {@code r2} (i.e. {@code r2.applyInverseTo(v) = w}).
-   * Then {@code w = comp.applyTo(u)}, where
-   * {@code comp = r2.composeInverse(r1)}.
-   * </p>
-   * <p>
-   * If the semantics of the rotations composition corresponds to a
-   * {@link RotationConvention#FRAME_TRANSFORM frame transform} convention,
-   * the application order will be reversed, which means it is the
-   * <em>innermost</em> rotation that will be reversed. So keeping the exact same
-   * meaning of all {@code r1}, {@code r2}, {@code u}, {@code v}, {@code w}
-   * and  {@code comp} as above, {@code comp} could also be computed as
-   * {@code comp = r1.revert().composeInverse(r2.revert(), RotationConvention.FRAME_TRANSFORM)}.
-   * </p>
-   * @param r rotation to apply the rotation to
-   * @param convention convention to use for the semantics of the angle
-   * @return a new rotation which is the composition of r by the inverse
-   * of the instance
-   */
-  public Rotation composeInverse(final Rotation r, final RotationConvention convention) {
-    return convention == RotationConvention.VECTOR_OPERATOR ?
-           composeInverseInternal(r) : r.composeInternal(revert());
-  }
-
-  /** Compose the inverse of the instance with another rotation
-   * using vector operator convention.
-   * @param r rotation to apply the rotation to
-   * @return a new rotation which is the composition of r by the inverse
-   * of the instance using vector operator convention
-   */
-  private Rotation composeInverseInternal(Rotation r) {
-    return new Rotation(-r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3),
-                        -r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2),
-                        -r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3),
-                        -r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1),
-                        false);
-  }
-
-  /** Perfect orthogonality on a 3X3 matrix.
-   * @param m initial matrix (not exactly orthogonal)
-   * @param threshold convergence threshold for the iterative
-   * orthogonality correction (convergence is reached when the
-   * difference between two steps of the Frobenius norm of the
-   * correction is below this threshold)
-   * @return an orthogonal matrix close to m
-   * @exception NotARotationMatrixException if the matrix cannot be
-   * orthogonalized with the given threshold after 10 iterations
-   */
-  private double[][] orthogonalizeMatrix(double[][] m, double threshold)
-    throws NotARotationMatrixException {
-    double[] m0 = m[0];
-    double[] m1 = m[1];
-    double[] m2 = m[2];
-    double x00 = m0[0];
-    double x01 = m0[1];
-    double x02 = m0[2];
-    double x10 = m1[0];
-    double x11 = m1[1];
-    double x12 = m1[2];
-    double x20 = m2[0];
-    double x21 = m2[1];
-    double x22 = m2[2];
-    double fn = 0;
-    double fn1;
-
-    double[][] o = new double[3][3];
-    double[] o0 = o[0];
-    double[] o1 = o[1];
-    double[] o2 = o[2];
-
-    // iterative correction: Xn+1 = Xn - 0.5 * (Xn.Mt.Xn - M)
-    int i = 0;
-    while (++i < 11) {
-
-      // Mt.Xn
-      double mx00 = m0[0] * x00 + m1[0] * x10 + m2[0] * x20;
-      double mx10 = m0[1] * x00 + m1[1] * x10 + m2[1] * x20;
-      double mx20 = m0[2] * x00 + m1[2] * x10 + m2[2] * x20;
-      double mx01 = m0[0] * x01 + m1[0] * x11 + m2[0] * x21;
-      double mx11 = m0[1] * x01 + m1[1] * x11 + m2[1] * x21;
-      double mx21 = m0[2] * x01 + m1[2] * x11 + m2[2] * x21;
-      double mx02 = m0[0] * x02 + m1[0] * x12 + m2[0] * x22;
-      double mx12 = m0[1] * x02 + m1[1] * x12 + m2[1] * x22;
-      double mx22 = m0[2] * x02 + m1[2] * x12 + m2[2] * x22;
-
-      // Xn+1
-      o0[0] = x00 - 0.5 * (x00 * mx00 + x01 * mx10 + x02 * mx20 - m0[0]);
-      o0[1] = x01 - 0.5 * (x00 * mx01 + x01 * mx11 + x02 * mx21 - m0[1]);
-      o0[2] = x02 - 0.5 * (x00 * mx02 + x01 * mx12 + x02 * mx22 - m0[2]);
-      o1[0] = x10 - 0.5 * (x10 * mx00 + x11 * mx10 + x12 * mx20 - m1[0]);
-      o1[1] = x11 - 0.5 * (x10 * mx01 + x11 * mx11 + x12 * mx21 - m1[1]);
-      o1[2] = x12 - 0.5 * (x10 * mx02 + x11 * mx12 + x12 * mx22 - m1[2]);
-      o2[0] = x20 - 0.5 * (x20 * mx00 + x21 * mx10 + x22 * mx20 - m2[0]);
-      o2[1] = x21 - 0.5 * (x20 * mx01 + x21 * mx11 + x22 * mx21 - m2[1]);
-      o2[2] = x22 - 0.5 * (x20 * mx02 + x21 * mx12 + x22 * mx22 - m2[2]);
-
-      // correction on each elements
-      double corr00 = o0[0] - m0[0];
-      double corr01 = o0[1] - m0[1];
-      double corr02 = o0[2] - m0[2];
-      double corr10 = o1[0] - m1[0];
-      double corr11 = o1[1] - m1[1];
-      double corr12 = o1[2] - m1[2];
-      double corr20 = o2[0] - m2[0];
-      double corr21 = o2[1] - m2[1];
-      double corr22 = o2[2] - m2[2];
-
-      // Frobenius norm of the correction
-      fn1 = corr00 * corr00 + corr01 * corr01 + corr02 * corr02 +
-            corr10 * corr10 + corr11 * corr11 + corr12 * corr12 +
-            corr20 * corr20 + corr21 * corr21 + corr22 * corr22;
-
-      // convergence test
-      if (FastMath.abs(fn1 - fn) <= threshold) {
-          return o;
-      }
-
-      // prepare next iteration
-      x00 = o0[0];
-      x01 = o0[1];
-      x02 = o0[2];
-      x10 = o1[0];
-      x11 = o1[1];
-      x12 = o1[2];
-      x20 = o2[0];
-      x21 = o2[1];
-      x22 = o2[2];
-      fn  = fn1;
-
-    }
-
-    // the algorithm did not converge after 10 iterations
-    throw new NotARotationMatrixException(
-            LocalizedFormats.UNABLE_TO_ORTHOGONOLIZE_MATRIX,
-            i - 1);
-  }
-
-  /** Compute the <i>distance</i> between two rotations.
-   * <p>The <i>distance</i> is intended here as a way to check if two
-   * rotations are almost similar (i.e. they transform vectors the same way)
-   * or very different. It is mathematically defined as the angle of
-   * the rotation r that prepended to one of the rotations gives the other
-   * one:</p>
-   * <div style="white-space: pre"><code>
-   *        r<sub>1</sub>(r) = r<sub>2</sub>
-   * </code></div>
-   * <p>This distance is an angle between 0 and &pi;. Its value is the smallest
-   * possible upper bound of the angle in radians between r<sub>1</sub>(v)
-   * and r<sub>2</sub>(v) for all possible vectors v. This upper bound is
-   * reached for some v. The distance is equal to 0 if and only if the two
-   * rotations are identical.</p>
-   * <p>Comparing two rotations should always be done using this value rather
-   * than for example comparing the components of the quaternions. It is much
-   * more stable, and has a geometric meaning. Also comparing quaternions
-   * components is error prone since for example quaternions (0.36, 0.48, -0.48, -0.64)
-   * and (-0.36, -0.48, 0.48, 0.64) represent exactly the same rotation despite
-   * their components are different (they are exact opposites).</p>
-   * @param r1 first rotation
-   * @param r2 second rotation
-   * @return <i>distance</i> between r1 and r2
-   */
-  public static double distance(Rotation r1, Rotation r2) {
-      return r1.composeInverseInternal(r2).getAngle();
-  }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/RotationOrder.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/RotationOrder.java
index 020de0e..9fae622 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/RotationOrder.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/RotationOrder.java
@@ -17,6 +17,8 @@
 
 package org.apache.commons.math4.geometry.euclidean.threed;
 
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
+
 /**
  * This class is a utility representing a rotation order specification
  * for Cardan or Euler angles specification.
@@ -35,96 +37,96 @@ public final class RotationOrder {
      * around Z
      */
     public static final RotationOrder XYZ =
-      new RotationOrder("XYZ", Cartesian3D.PLUS_I, Cartesian3D.PLUS_J, Cartesian3D.PLUS_K);
+      new RotationOrder("XYZ", Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z);
 
     /** Set of Cardan angles.
      * this ordered set of rotations is around X, then around Z, then
      * around Y
      */
     public static final RotationOrder XZY =
-      new RotationOrder("XZY", Cartesian3D.PLUS_I, Cartesian3D.PLUS_K, Cartesian3D.PLUS_J);
+      new RotationOrder("XZY", Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_Y);
 
     /** Set of Cardan angles.
      * this ordered set of rotations is around Y, then around X, then
      * around Z
      */
     public static final RotationOrder YXZ =
-      new RotationOrder("YXZ", Cartesian3D.PLUS_J, Cartesian3D.PLUS_I, Cartesian3D.PLUS_K);
+      new RotationOrder("YXZ", Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Z);
 
     /** Set of Cardan angles.
      * this ordered set of rotations is around Y, then around Z, then
      * around X
      */
     public static final RotationOrder YZX =
-      new RotationOrder("YZX", Cartesian3D.PLUS_J, Cartesian3D.PLUS_K, Cartesian3D.PLUS_I);
+      new RotationOrder("YZX", Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_X);
 
     /** Set of Cardan angles.
      * this ordered set of rotations is around Z, then around X, then
      * around Y
      */
     public static final RotationOrder ZXY =
-      new RotationOrder("ZXY", Cartesian3D.PLUS_K, Cartesian3D.PLUS_I, Cartesian3D.PLUS_J);
+      new RotationOrder("ZXY", Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y);
 
     /** Set of Cardan angles.
      * this ordered set of rotations is around Z, then around Y, then
      * around X
      */
     public static final RotationOrder ZYX =
-      new RotationOrder("ZYX", Cartesian3D.PLUS_K, Cartesian3D.PLUS_J, Cartesian3D.PLUS_I);
+      new RotationOrder("ZYX", Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around X, then around Y, then
      * around X
      */
     public static final RotationOrder XYX =
-      new RotationOrder("XYX", Cartesian3D.PLUS_I, Cartesian3D.PLUS_J, Cartesian3D.PLUS_I);
+      new RotationOrder("XYX", Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around X, then around Z, then
      * around X
      */
     public static final RotationOrder XZX =
-      new RotationOrder("XZX", Cartesian3D.PLUS_I, Cartesian3D.PLUS_K, Cartesian3D.PLUS_I);
+      new RotationOrder("XZX", Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_X);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around Y, then around X, then
      * around Y
      */
     public static final RotationOrder YXY =
-      new RotationOrder("YXY", Cartesian3D.PLUS_J, Cartesian3D.PLUS_I, Cartesian3D.PLUS_J);
+      new RotationOrder("YXY", Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around Y, then around Z, then
      * around Y
      */
     public static final RotationOrder YZY =
-      new RotationOrder("YZY", Cartesian3D.PLUS_J, Cartesian3D.PLUS_K, Cartesian3D.PLUS_J);
+      new RotationOrder("YZY", Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_Y);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around Z, then around X, then
      * around Z
      */
     public static final RotationOrder ZXZ =
-      new RotationOrder("ZXZ", Cartesian3D.PLUS_K, Cartesian3D.PLUS_I, Cartesian3D.PLUS_K);
+      new RotationOrder("ZXZ", Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Z);
 
     /** Set of Euler angles.
      * this ordered set of rotations is around Z, then around Y, then
      * around Z
      */
     public static final RotationOrder ZYZ =
-      new RotationOrder("ZYZ", Cartesian3D.PLUS_K, Cartesian3D.PLUS_J, Cartesian3D.PLUS_K);
+      new RotationOrder("ZYZ", Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z);
 
     /** Name of the rotations order. */
     private final String name;
 
     /** Axis of the first rotation. */
-    private final Cartesian3D a1;
+    private final Vector3D a1;
 
     /** Axis of the second rotation. */
-    private final Cartesian3D a2;
+    private final Vector3D a2;
 
     /** Axis of the third rotation. */
-    private final Cartesian3D a3;
+    private final Vector3D a3;
 
     /** Private constructor.
      * This is a utility class that cannot be instantiated by the user,
@@ -135,7 +137,7 @@ public final class RotationOrder {
      * @param a3 axis of the third rotation
      */
     private RotationOrder(final String name,
-                          final Cartesian3D a1, final Cartesian3D a2, final Cartesian3D a3) {
+                          final Vector3D a1, final Vector3D a2, final Vector3D a3) {
         this.name = name;
         this.a1   = a1;
         this.a2   = a2;
@@ -153,21 +155,21 @@ public final class RotationOrder {
     /** Get the axis of the first rotation.
      * @return axis of the first rotation
      */
-    public Cartesian3D getA1() {
+    public Vector3D getA1() {
         return a1;
     }
 
     /** Get the axis of the second rotation.
      * @return axis of the second rotation
      */
-    public Cartesian3D getA2() {
+    public Vector3D getA2() {
         return a2;
     }
 
     /** Get the axis of the second rotation.
      * @return axis of the second rotation
      */
-    public Cartesian3D getA3() {
+    public Vector3D getA3() {
         return a3;
     }
 
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Segment.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Segment.java
deleted file mode 100644
index 6ced496..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Segment.java
+++ /dev/null
@@ -1,66 +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;
-
-
-/** Simple container for a two-points segment.
- * @since 3.0
- */
-public class Segment {
-
-    /** Start point of the segment. */
-    private final Cartesian3D start;
-
-    /** End point of the segments. */
-    private final Cartesian3D end;
-
-    /** Line containing the segment. */
-    private final Line     line;
-
-    /** Build a segment.
-     * @param start start point of the segment
-     * @param end end point of the segment
-     * @param line line containing the segment
-     */
-    public Segment(final Cartesian3D start, final Cartesian3D end, final Line line) {
-        this.start  = start;
-        this.end    = end;
-        this.line   = line;
-    }
-
-    /** Get the start point of the segment.
-     * @return start point of the segment
-     */
-    public Cartesian3D getStart() {
-        return start;
-    }
-
-    /** Get the end point of the segment.
-     * @return end point of the segment
-     */
-    public Cartesian3D getEnd() {
-        return end;
-    }
-
-    /** Get the line containing the segment.
-     * @return line containing the segment
-     */
-    public Line getLine() {
-        return line;
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphereGenerator.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphereGenerator.java
deleted file mode 100644
index 8ed5a6a..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphereGenerator.java
+++ /dev/null
@@ -1,153 +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.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.math4.fraction.BigFraction;
-import org.apache.commons.math4.geometry.enclosing.EnclosingBall;
-import org.apache.commons.math4.geometry.enclosing.SupportBallGenerator;
-import org.apache.commons.math4.geometry.euclidean.twod.DiskGenerator;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
-import org.apache.commons.math4.util.FastMath;
-
-/** Class generating an enclosing ball from its support points.
- * @since 3.3
- */
-public class SphereGenerator implements SupportBallGenerator<Euclidean3D, Cartesian3D> {
-
-    /** {@inheritDoc} */
-    @Override
-    public EnclosingBall<Euclidean3D, Cartesian3D> ballOnSupport(final List<Cartesian3D> support) {
-
-        if (support.size() < 1) {
-            return new EnclosingBall<>(Cartesian3D.ZERO, Double.NEGATIVE_INFINITY);
-        } else {
-            final Cartesian3D vA = support.get(0);
-            if (support.size() < 2) {
-                return new EnclosingBall<>(vA, 0, vA);
-            } else {
-                final Cartesian3D vB = support.get(1);
-                if (support.size() < 3) {
-                    return new EnclosingBall<>(new Cartesian3D(0.5, vA, 0.5, vB),
-                                                                    0.5 * vA.distance(vB),
-                                                                    vA, vB);
-                } else {
-                    final Cartesian3D vC = support.get(2);
-                    if (support.size() < 4) {
-
-                        // delegate to 2D disk generator
-                        final Plane p = new Plane(vA, vB, vC,
-                                                  1.0e-10 * (vA.getNorm1() + vB.getNorm1() + vC.getNorm1()));
-                        final EnclosingBall<Euclidean2D, Cartesian2D> disk =
-                                new DiskGenerator().ballOnSupport(Arrays.asList(p.toSubSpace(vA),
-                                                                                p.toSubSpace(vB),
-                                                                                p.toSubSpace(vC)));
-
-                        // convert back to 3D
-                        return new EnclosingBall<>(p.toSpace(disk.getCenter()),
-                                                                        disk.getRadius(), vA, vB, vC);
-
-                    } else {
-                        final Cartesian3D vD = support.get(3);
-                        // a sphere is 3D can be defined as:
-                        // (1)   (x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 = r^2
-                        // which can be written:
-                        // (2)   (x^2 + y^2 + z^2) - 2 x_0 x - 2 y_0 y - 2 z_0 z + (x_0^2 + y_0^2 + z_0^2 - r^2) = 0
-                        // or simply:
-                        // (3)   (x^2 + y^2 + z^2) + a x + b y + c z + d = 0
-                        // with sphere center coordinates -a/2, -b/2, -c/2
-                        // If the sphere exists, a b, c and d are a non zero solution to
-                        // [ (x^2  + y^2  + z^2)    x    y   z    1 ]   [ 1 ]   [ 0 ]
-                        // [ (xA^2 + yA^2 + zA^2)   xA   yA  zA   1 ]   [ a ]   [ 0 ]
-                        // [ (xB^2 + yB^2 + zB^2)   xB   yB  zB   1 ] * [ b ] = [ 0 ]
-                        // [ (xC^2 + yC^2 + zC^2)   xC   yC  zC   1 ]   [ c ]   [ 0 ]
-                        // [ (xD^2 + yD^2 + zD^2)   xD   yD  zD   1 ]   [ d ]   [ 0 ]
-                        // So the determinant of the matrix is zero. Computing this determinant
-                        // by expanding it using the minors m_ij of first row leads to
-                        // (4)   m_11 (x^2 + y^2 + z^2) - m_12 x + m_13 y - m_14 z + m_15 = 0
-                        // So by identifying equations (2) and (4) we get the coordinates
-                        // of center as:
-                        //      x_0 = +m_12 / (2 m_11)
-                        //      y_0 = -m_13 / (2 m_11)
-                        //      z_0 = +m_14 / (2 m_11)
-                        // Note that the minors m_11, m_12, m_13 and m_14 all have the last column
-                        // filled with 1.0, hence simplifying the computation
-                        final BigFraction[] c2 = new BigFraction[] {
-                            new BigFraction(vA.getX()), new BigFraction(vB.getX()),
-                            new BigFraction(vC.getX()), new BigFraction(vD.getX())
-                        };
-                        final BigFraction[] c3 = new BigFraction[] {
-                            new BigFraction(vA.getY()), new BigFraction(vB.getY()),
-                            new BigFraction(vC.getY()), new BigFraction(vD.getY())
-                        };
-                        final BigFraction[] c4 = new BigFraction[] {
-                            new BigFraction(vA.getZ()), new BigFraction(vB.getZ()),
-                            new BigFraction(vC.getZ()), new BigFraction(vD.getZ())
-                        };
-                        final BigFraction[] c1 = new BigFraction[] {
-                            c2[0].multiply(c2[0]).add(c3[0].multiply(c3[0])).add(c4[0].multiply(c4[0])),
-                            c2[1].multiply(c2[1]).add(c3[1].multiply(c3[1])).add(c4[1].multiply(c4[1])),
-                            c2[2].multiply(c2[2]).add(c3[2].multiply(c3[2])).add(c4[2].multiply(c4[2])),
-                            c2[3].multiply(c2[3]).add(c3[3].multiply(c3[3])).add(c4[3].multiply(c4[3]))
-                        };
-                        final BigFraction twoM11  = minor(c2, c3, c4).multiply(2);
-                        final BigFraction m12     = minor(c1, c3, c4);
-                        final BigFraction m13     = minor(c1, c2, c4);
-                        final BigFraction m14     = minor(c1, c2, c3);
-                        final BigFraction centerX = m12.divide(twoM11);
-                        final BigFraction centerY = m13.divide(twoM11).negate();
-                        final BigFraction centerZ = m14.divide(twoM11);
-                        final BigFraction dx      = c2[0].subtract(centerX);
-                        final BigFraction dy      = c3[0].subtract(centerY);
-                        final BigFraction dz      = c4[0].subtract(centerZ);
-                        final BigFraction r2      = dx.multiply(dx).add(dy.multiply(dy)).add(dz.multiply(dz));
-                        return new EnclosingBall<>(new Cartesian3D(centerX.doubleValue(),
-                                                                                     centerY.doubleValue(),
-                                                                                     centerZ.doubleValue()),
-                                                                        FastMath.sqrt(r2.doubleValue()),
-                                                                        vA, vB, vC, vD);
-                    }
-                }
-            }
-        }
-    }
-
-    /** Compute a dimension 4 minor, when 4<sup>th</sup> column is known to be filled with 1.0.
-     * @param c1 first column
-     * @param c2 second column
-     * @param c3 third column
-     * @return value of the minor computed has an exact fraction
-     */
-    private BigFraction minor(final BigFraction[] c1, final BigFraction[] c2, final BigFraction[] c3) {
-        return      c2[0].multiply(c3[1]).multiply(c1[2].subtract(c1[3])).
-                add(c2[0].multiply(c3[2]).multiply(c1[3].subtract(c1[1]))).
-                add(c2[0].multiply(c3[3]).multiply(c1[1].subtract(c1[2]))).
-                add(c2[1].multiply(c3[0]).multiply(c1[3].subtract(c1[2]))).
-                add(c2[1].multiply(c3[2]).multiply(c1[0].subtract(c1[3]))).
-                add(c2[1].multiply(c3[3]).multiply(c1[2].subtract(c1[0]))).
-                add(c2[2].multiply(c3[0]).multiply(c1[1].subtract(c1[3]))).
-                add(c2[2].multiply(c3[1]).multiply(c1[3].subtract(c1[0]))).
-                add(c2[2].multiply(c3[3]).multiply(c1[0].subtract(c1[1]))).
-                add(c2[3].multiply(c3[0]).multiply(c1[2].subtract(c1[1]))).
-                add(c2[3].multiply(c3[1]).multiply(c1[0].subtract(c1[2]))).
-                add(c2[3].multiply(c3[2]).multiply(c1[1].subtract(c1[0])));
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphericalCoordinates.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphericalCoordinates.java
deleted file mode 100644
index 5f07644..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SphericalCoordinates.java
+++ /dev/null
@@ -1,395 +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 org.apache.commons.math4.util.FastMath;
-
-/** This class provides conversions related to <a
- * href="http://mathworld.wolfram.com/SphericalCoordinates.html">spherical coordinates</a>.
- * <p>
- * The conventions used here are the mathematical ones, i.e. spherical coordinates are
- * related to Cartesian coordinates as follows:
- * </p>
- * <ul>
- *   <li>x = r cos(&theta;) sin(&Phi;)</li>
- *   <li>y = r sin(&theta;) sin(&Phi;)</li>
- *   <li>z = r cos(&Phi;)</li>
- * </ul>
- * <ul>
- *   <li>r       = &radic;(x<sup>2</sup>+y<sup>2</sup>+z<sup>2</sup>)</li>
- *   <li>&theta; = atan2(y, x)</li>
- *   <li>&Phi;   = acos(z/r)</li>
- * </ul>
- * <p>
- * r is the radius, &theta; is the azimuthal angle in the x-y plane and &Phi; is the polar
- * (co-latitude) angle. These conventions are <em>different</em> from the conventions used
- * in physics (and in particular in spherical harmonics) where the meanings of &theta; and
- * &Phi; are reversed.
- * </p>
- * <p>
- * This class provides conversion of coordinates and also of gradient and Hessian
- * between spherical and Cartesian coordinates.
- * </p>
- * @since 3.2
- */
-public class SphericalCoordinates implements Serializable {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20130206L;
-
-    /** Cartesian coordinates. */
-    private final Cartesian3D v;
-
-    /** Radius. */
-    private final double r;
-
-    /** Azimuthal angle in the x-y plane &theta;. */
-    private final double theta;
-
-    /** Polar angle (co-latitude) &Phi;. */
-    private final double phi;
-
-    /** Jacobian of (r, &theta; &Phi;). */
-    private double[][] jacobian;
-
-    /** Hessian of radius. */
-    private double[][] rHessian;
-
-    /** Hessian of azimuthal angle in the x-y plane &theta;. */
-    private double[][] thetaHessian;
-
-    /** Hessian of polar (co-latitude) angle &Phi;. */
-    private double[][] phiHessian;
-
-    /** Build a spherical coordinates transformer from Cartesian coordinates.
-     * @param v Cartesian coordinates
-     */
-    public SphericalCoordinates(final Cartesian3D v) {
-
-        // Cartesian coordinates
-        this.v = v;
-
-        // remaining spherical coordinates
-        this.r     = v.getNorm();
-        this.theta = v.getAlpha();
-        this.phi   = FastMath.acos(v.getZ() / r);
-
-    }
-
-    /** Build a spherical coordinates transformer from spherical coordinates.
-     * @param r radius
-     * @param theta azimuthal angle in x-y plane
-     * @param phi polar (co-latitude) angle
-     */
-    public SphericalCoordinates(final double r, final double theta, final double phi) {
-
-        final double cosTheta = FastMath.cos(theta);
-        final double sinTheta = FastMath.sin(theta);
-        final double cosPhi   = FastMath.cos(phi);
-        final double sinPhi   = FastMath.sin(phi);
-
-        // spherical coordinates
-        this.r     = r;
-        this.theta = theta;
-        this.phi   = phi;
-
-        // Cartesian coordinates
-        this.v  = new Cartesian3D(r * cosTheta * sinPhi,
-                               r * sinTheta * sinPhi,
-                               r * cosPhi);
-
-    }
-
-    /** Get the Cartesian coordinates.
-     * @return Cartesian coordinates
-     */
-    public Cartesian3D getCartesian() {
-        return v;
-    }
-
-    /** Get the radius.
-     * @return radius r
-     * @see #getTheta()
-     * @see #getPhi()
-     */
-    public double getR() {
-        return r;
-    }
-
-    /** Get the azimuthal angle in x-y plane.
-     * @return azimuthal angle in x-y plane &theta;
-     * @see #getR()
-     * @see #getPhi()
-     */
-    public double getTheta() {
-        return theta;
-    }
-
-    /** Get the polar (co-latitude) angle.
-     * @return polar (co-latitude) angle &Phi;
-     * @see #getR()
-     * @see #getTheta()
-     */
-    public double getPhi() {
-        return phi;
-    }
-
-    /** Convert a gradient with respect to spherical coordinates into a gradient
-     * with respect to Cartesian coordinates.
-     * @param sGradient gradient with respect to spherical coordinates
-     * {df/dr, df/d&theta;, df/d&Phi;}
-     * @return gradient with respect to Cartesian coordinates
-     * {df/dx, df/dy, df/dz}
-     */
-    public double[] toCartesianGradient(final double[] sGradient) {
-
-        // lazy evaluation of Jacobian
-        computeJacobian();
-
-        // compose derivatives as gradient^T . J
-        // the expressions have been simplified since we know jacobian[1][2] = dTheta/dZ = 0
-        return new double[] {
-            sGradient[0] * jacobian[0][0] + sGradient[1] * jacobian[1][0] + sGradient[2] * jacobian[2][0],
-            sGradient[0] * jacobian[0][1] + sGradient[1] * jacobian[1][1] + sGradient[2] * jacobian[2][1],
-            sGradient[0] * jacobian[0][2]                                 + sGradient[2] * jacobian[2][2]
-        };
-
-    }
-
-    /** Convert a Hessian with respect to spherical coordinates into a Hessian
-     * with respect to Cartesian coordinates.
-     * <p>
-     * As Hessian are always symmetric, we use only the lower left part of the provided
-     * spherical Hessian, so the upper part may not be initialized. However, we still
-     * do fill up the complete array we create, with guaranteed symmetry.
-     * </p>
-     * @param sHessian Hessian with respect to spherical coordinates
-     * {{d<sup>2</sup>f/dr<sup>2</sup>, d<sup>2</sup>f/drd&theta;, d<sup>2</sup>f/drd&Phi;},
-     *  {d<sup>2</sup>f/drd&theta;, d<sup>2</sup>f/d&theta;<sup>2</sup>, d<sup>2</sup>f/d&theta;d&Phi;},
-     *  {d<sup>2</sup>f/drd&Phi;, d<sup>2</sup>f/d&theta;d&Phi;, d<sup>2</sup>f/d&Phi;<sup>2</sup>}
-     * @param sGradient gradient with respect to spherical coordinates
-     * {df/dr, df/d&theta;, df/d&Phi;}
-     * @return Hessian with respect to Cartesian coordinates
-     * {{d<sup>2</sup>f/dx<sup>2</sup>, d<sup>2</sup>f/dxdy, d<sup>2</sup>f/dxdz},
-     *  {d<sup>2</sup>f/dxdy, d<sup>2</sup>f/dy<sup>2</sup>, d<sup>2</sup>f/dydz},
-     *  {d<sup>2</sup>f/dxdz, d<sup>2</sup>f/dydz, d<sup>2</sup>f/dz<sup>2</sup>}}
-     */
-    public double[][] toCartesianHessian(final double[][] sHessian, final double[] sGradient) {
-
-        computeJacobian();
-        computeHessians();
-
-        // compose derivative as J^T . H_f . J + df/dr H_r + df/dtheta H_theta + df/dphi H_phi
-        // the expressions have been simplified since we know jacobian[1][2] = dTheta/dZ = 0
-        // and H_theta is only a 2x2 matrix as it does not depend on z
-        final double[][] hj = new double[3][3];
-        final double[][] cHessian = new double[3][3];
-
-        // compute H_f . J
-        // beware we use ONLY the lower-left part of sHessian
-        hj[0][0] = sHessian[0][0] * jacobian[0][0] + sHessian[1][0] * jacobian[1][0] + sHessian[2][0] * jacobian[2][0];
-        hj[0][1] = sHessian[0][0] * jacobian[0][1] + sHessian[1][0] * jacobian[1][1] + sHessian[2][0] * jacobian[2][1];
-        hj[0][2] = sHessian[0][0] * jacobian[0][2]                                   + sHessian[2][0] * jacobian[2][2];
-        hj[1][0] = sHessian[1][0] * jacobian[0][0] + sHessian[1][1] * jacobian[1][0] + sHessian[2][1] * jacobian[2][0];
-        hj[1][1] = sHessian[1][0] * jacobian[0][1] + sHessian[1][1] * jacobian[1][1] + sHessian[2][1] * jacobian[2][1];
-        // don't compute hj[1][2] as it is not used below
-        hj[2][0] = sHessian[2][0] * jacobian[0][0] + sHessian[2][1] * jacobian[1][0] + sHessian[2][2] * jacobian[2][0];
-        hj[2][1] = sHessian[2][0] * jacobian[0][1] + sHessian[2][1] * jacobian[1][1] + sHessian[2][2] * jacobian[2][1];
-        hj[2][2] = sHessian[2][0] * jacobian[0][2]                                   + sHessian[2][2] * jacobian[2][2];
-
-        // compute lower-left part of J^T . H_f . J
-        cHessian[0][0] = jacobian[0][0] * hj[0][0] + jacobian[1][0] * hj[1][0] + jacobian[2][0] * hj[2][0];
-        cHessian[1][0] = jacobian[0][1] * hj[0][0] + jacobian[1][1] * hj[1][0] + jacobian[2][1] * hj[2][0];
-        cHessian[2][0] = jacobian[0][2] * hj[0][0]                             + jacobian[2][2] * hj[2][0];
-        cHessian[1][1] = jacobian[0][1] * hj[0][1] + jacobian[1][1] * hj[1][1] + jacobian[2][1] * hj[2][1];
-        cHessian[2][1] = jacobian[0][2] * hj[0][1]                             + jacobian[2][2] * hj[2][1];
-        cHessian[2][2] = jacobian[0][2] * hj[0][2]                             + jacobian[2][2] * hj[2][2];
-
-        // add gradient contribution
-        cHessian[0][0] += sGradient[0] * rHessian[0][0] + sGradient[1] * thetaHessian[0][0] + sGradient[2] * phiHessian[0][0];
-        cHessian[1][0] += sGradient[0] * rHessian[1][0] + sGradient[1] * thetaHessian[1][0] + sGradient[2] * phiHessian[1][0];
-        cHessian[2][0] += sGradient[0] * rHessian[2][0]                                     + sGradient[2] * phiHessian[2][0];
-        cHessian[1][1] += sGradient[0] * rHessian[1][1] + sGradient[1] * thetaHessian[1][1] + sGradient[2] * phiHessian[1][1];
-        cHessian[2][1] += sGradient[0] * rHessian[2][1]                                     + sGradient[2] * phiHessian[2][1];
-        cHessian[2][2] += sGradient[0] * rHessian[2][2]                                     + sGradient[2] * phiHessian[2][2];
-
-        // ensure symmetry
-        cHessian[0][1] = cHessian[1][0];
-        cHessian[0][2] = cHessian[2][0];
-        cHessian[1][2] = cHessian[2][1];
-
-        return cHessian;
-
-    }
-
-    /** Lazy evaluation of (r, &theta;, &phi;) Jacobian.
-     */
-    private void computeJacobian() {
-        if (jacobian == null) {
-
-            // intermediate variables
-            final double x    = v.getX();
-            final double y    = v.getY();
-            final double z    = v.getZ();
-            final double rho2 = x * x + y * y;
-            final double rho  = FastMath.sqrt(rho2);
-            final double r2   = rho2 + z * z;
-
-            jacobian = new double[3][3];
-
-            // row representing the gradient of r
-            jacobian[0][0] = x / r;
-            jacobian[0][1] = y / r;
-            jacobian[0][2] = z / r;
-
-            // row representing the gradient of theta
-            jacobian[1][0] = -y / rho2;
-            jacobian[1][1] =  x / rho2;
-            // jacobian[1][2] is already set to 0 at allocation time
-
-            // row representing the gradient of phi
-            jacobian[2][0] = x * z / (rho * r2);
-            jacobian[2][1] = y * z / (rho * r2);
-            jacobian[2][2] = -rho / r2;
-
-        }
-    }
-
-    /** Lazy evaluation of Hessians.
-     */
-    private void computeHessians() {
-
-        if (rHessian == null) {
-
-            // intermediate variables
-            final double x      = v.getX();
-            final double y      = v.getY();
-            final double z      = v.getZ();
-            final double x2     = x * x;
-            final double y2     = y * y;
-            final double z2     = z * z;
-            final double rho2   = x2 + y2;
-            final double rho    = FastMath.sqrt(rho2);
-            final double r2     = rho2 + z2;
-            final double xOr    = x / r;
-            final double yOr    = y / r;
-            final double zOr    = z / r;
-            final double xOrho2 = x / rho2;
-            final double yOrho2 = y / rho2;
-            final double xOr3   = xOr / r2;
-            final double yOr3   = yOr / r2;
-            final double zOr3   = zOr / r2;
-
-            // lower-left part of Hessian of r
-            rHessian = new double[3][3];
-            rHessian[0][0] = y * yOr3 + z * zOr3;
-            rHessian[1][0] = -x * yOr3;
-            rHessian[2][0] = -z * xOr3;
-            rHessian[1][1] = x * xOr3 + z * zOr3;
-            rHessian[2][1] = -y * zOr3;
-            rHessian[2][2] = x * xOr3 + y * yOr3;
-
-            // upper-right part is symmetric
-            rHessian[0][1] = rHessian[1][0];
-            rHessian[0][2] = rHessian[2][0];
-            rHessian[1][2] = rHessian[2][1];
-
-            // lower-left part of Hessian of azimuthal angle theta
-            thetaHessian = new double[2][2];
-            thetaHessian[0][0] = 2 * xOrho2 * yOrho2;
-            thetaHessian[1][0] = yOrho2 * yOrho2 - xOrho2 * xOrho2;
-            thetaHessian[1][1] = -2 * xOrho2 * yOrho2;
-
-            // upper-right part is symmetric
-            thetaHessian[0][1] = thetaHessian[1][0];
-
-            // lower-left part of Hessian of polar (co-latitude) angle phi
-            final double rhor2       = rho * r2;
-            final double rho2r2      = rho * rhor2;
-            final double rhor4       = rhor2 * r2;
-            final double rho3r4      = rhor4 * rho2;
-            final double r2P2rho2    = 3 * rho2 + z2;
-            phiHessian = new double[3][3];
-            phiHessian[0][0] = z * (rho2r2 - x2 * r2P2rho2) / rho3r4;
-            phiHessian[1][0] = -x * y * z * r2P2rho2 / rho3r4;
-            phiHessian[2][0] = x * (rho2 - z2) / rhor4;
-            phiHessian[1][1] = z * (rho2r2 - y2 * r2P2rho2) / rho3r4;
-            phiHessian[2][1] = y * (rho2 - z2) / rhor4;
-            phiHessian[2][2] = 2 * rho * zOr3 / r;
-
-            // upper-right part is symmetric
-            phiHessian[0][1] = phiHessian[1][0];
-            phiHessian[0][2] = phiHessian[2][0];
-            phiHessian[1][2] = phiHessian[2][1];
-
-        }
-
-    }
-
-    /**
-     * Replace the instance with a data transfer object for serialization.
-     * @return data transfer object that will be serialized
-     */
-    private Object writeReplace() {
-        return new DataTransferObject(v.getX(), v.getY(), v.getZ());
-    }
-
-    /** Internal class used only for serialization. */
-    private static class DataTransferObject implements Serializable {
-
-        /** Serializable UID. */
-        private static final long serialVersionUID = 20130206L;
-
-        /** Abscissa.
-         * @serial
-         */
-        private final double x;
-
-        /** Ordinate.
-         * @serial
-         */
-        private final double y;
-
-        /** Height.
-         * @serial
-         */
-        private final double z;
-
-        /** Simple constructor.
-         * @param x abscissa
-         * @param y ordinate
-         * @param z height
-         */
-        DataTransferObject(final double x, final double y, final double z) {
-            this.x = x;
-            this.y = y;
-            this.z = z;
-        }
-
-        /** Replace the deserialized data transfer object with a {@link SphericalCoordinates}.
-         * @return replacement {@link SphericalCoordinates}
-         */
-        private Object readResolve() {
-            return new SphericalCoordinates(new Cartesian3D(x, y, z));
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubLine.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubLine.java
deleted file mode 100644
index 8eab249..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubLine.java
+++ /dev/null
@@ -1,151 +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.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
-import org.apache.commons.math4.geometry.euclidean.oned.Interval;
-import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
-import org.apache.commons.math4.geometry.partitioning.Region.Location;
-
-/** This class represents a subset of a {@link Line}.
- * @since 3.0
- */
-public class SubLine {
-
-    /** Underlying line. */
-    private final Line line;
-
-    /** Remaining region of the hyperplane. */
-    private final IntervalsSet remainingRegion;
-
-    /** Simple constructor.
-     * @param line underlying line
-     * @param remainingRegion remaining region of the line
-     */
-    public SubLine(final Line line, final IntervalsSet remainingRegion) {
-        this.line            = line;
-        this.remainingRegion = remainingRegion;
-    }
-
-    /** Create a sub-line from two endpoints.
-     * @param start start point
-     * @param end end point
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathIllegalArgumentException if the points are equal
-     * @since 3.3
-     */
-    public SubLine(final Cartesian3D start, final Cartesian3D end, final double tolerance)
-        throws MathIllegalArgumentException {
-        this(new Line(start, end, tolerance), buildIntervalSet(start, end, tolerance));
-    }
-
-    /** Create a sub-line from a segment.
-     * @param segment single segment forming the sub-line
-     * @exception MathIllegalArgumentException if the segment endpoints are equal
-     */
-    public SubLine(final Segment segment) throws MathIllegalArgumentException {
-        this(segment.getLine(),
-             buildIntervalSet(segment.getStart(), segment.getEnd(), segment.getLine().getTolerance()));
-    }
-
-    /** Get the endpoints of the sub-line.
-     * <p>
-     * A subline may be any arbitrary number of disjoints segments, so the endpoints
-     * are provided as a list of endpoint pairs. Each element of the list represents
-     * one segment, and each segment contains a start point at index 0 and an end point
-     * at index 1. If the sub-line is unbounded in the negative infinity direction,
-     * the start point of the first segment will have infinite coordinates. If the
-     * sub-line is unbounded in the positive infinity direction, the end point of the
-     * last segment will have infinite coordinates. So a sub-line covering the whole
-     * line will contain just one row and both elements of this row will have infinite
-     * coordinates. If the sub-line is empty, the returned list will contain 0 segments.
-     * </p>
-     * @return list of segments endpoints
-     */
-    public List<Segment> getSegments() {
-
-        final List<Interval> list = remainingRegion.asList();
-        final List<Segment> segments = new ArrayList<>(list.size());
-
-        for (final Interval interval : list) {
-            final Cartesian3D start = line.toSpace(new Cartesian1D(interval.getInf()));
-            final Cartesian3D end   = line.toSpace(new Cartesian1D(interval.getSup()));
-            segments.add(new Segment(start, end, line));
-        }
-
-        return segments;
-
-    }
-
-    /** Get the intersection of the instance and another sub-line.
-     * <p>
-     * This method is related to the {@link Line#intersection(Line)
-     * intersection} method in the {@link Line Line} class, but in addition
-     * to compute the point along infinite lines, it also checks the point
-     * lies on both sub-line ranges.
-     * </p>
-     * @param subLine other sub-line which may intersect instance
-     * @param includeEndPoints if true, endpoints are considered to belong to
-     * instance (i.e. they are closed sets) and may be returned, otherwise endpoints
-     * are considered to not belong to instance (i.e. they are open sets) and intersection
-     * occurring on endpoints lead to null being returned
-     * @return the intersection point if there is one, null if the sub-lines don't intersect
-     */
-    public Cartesian3D intersection(final SubLine subLine, final boolean includeEndPoints) {
-
-        // compute the intersection on infinite line
-        Cartesian3D v1D = line.intersection(subLine.line);
-        if (v1D == null) {
-            return null;
-        }
-
-        // check location of point with respect to first sub-line
-        Location loc1 = remainingRegion.checkPoint((Point<Euclidean1D>) line.toSubSpace((Point<Euclidean3D>) v1D));
-
-        // check location of point with respect to second sub-line
-        Location loc2 = subLine.remainingRegion.checkPoint((Point<Euclidean1D>) subLine.line.toSubSpace((Point<Euclidean3D>) v1D));
-
-        if (includeEndPoints) {
-            return ((loc1 != Location.OUTSIDE) && (loc2 != Location.OUTSIDE)) ? v1D : null;
-        } else {
-            return ((loc1 == Location.INSIDE) && (loc2 == Location.INSIDE)) ? v1D : null;
-        }
-
-    }
-
-    /** Build an interval set from two points.
-     * @param start start point
-     * @param end end point
-     * @return an interval set
-     * @param tolerance tolerance below which points are considered identical
-     * @exception MathIllegalArgumentException if the points are equal
-     */
-    private static IntervalsSet buildIntervalSet(final Cartesian3D start, final Cartesian3D end, final double tolerance)
-        throws MathIllegalArgumentException {
-        final Line line = new Line(start, end, tolerance);
-        return new IntervalsSet(line.toSubSpace((Point<Euclidean3D>) start).getX(),
-                                line.toSubSpace((Point<Euclidean3D>) end).getX(),
-                                tolerance);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
deleted file mode 100644
index adc6860..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
+++ /dev/null
@@ -1,106 +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 org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
-import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D;
-import org.apache.commons.math4.geometry.euclidean.twod.PolygonsSet;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
-import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
-import org.apache.commons.math4.geometry.partitioning.BSPTree;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
-
-/** This class represents a sub-hyperplane for {@link Plane}.
- * @since 3.0
- */
-public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Euclidean2D> {
-
-    /** Simple constructor.
-     * @param hyperplane underlying hyperplane
-     * @param remainingRegion remaining region of the hyperplane
-     */
-    public SubPlane(final Hyperplane<Euclidean3D> hyperplane,
-                    final Region<Euclidean2D> remainingRegion) {
-        super(hyperplane, remainingRegion);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected AbstractSubHyperplane<Euclidean3D, Euclidean2D> buildNew(final Hyperplane<Euclidean3D> hyperplane,
-                                                                       final Region<Euclidean2D> remainingRegion) {
-        return new SubPlane(hyperplane, remainingRegion);
-    }
-
-    /** Split the instance in two parts by an hyperplane.
-     * @param hyperplane splitting hyperplane
-     * @return an object containing both the part of the instance
-     * on the plus side of the instance and the part of the
-     * instance on the minus side of the instance
-     */
-    @Override
-    public SplitSubHyperplane<Euclidean3D> split(Hyperplane<Euclidean3D> hyperplane) {
-
-        final Plane otherPlane = (Plane) hyperplane;
-        final Plane thisPlane  = (Plane) getHyperplane();
-        final Line  inter      = otherPlane.intersection(thisPlane);
-        final double tolerance = thisPlane.getTolerance();
-
-        if (inter == null) {
-            // the hyperplanes are parallel
-            final double global = otherPlane.getOffset(thisPlane);
-            if (global < -tolerance) {
-                return new SplitSubHyperplane<>(null, this);
-            } else if (global > tolerance) {
-                return new SplitSubHyperplane<>(this, null);
-            } else {
-                return new SplitSubHyperplane<>(null, null);
-            }
-        }
-
-        // the hyperplanes do intersect
-        Cartesian2D p = thisPlane.toSubSpace(inter.toSpace(Cartesian1D.ZERO));
-        Cartesian2D q = thisPlane.toSubSpace(inter.toSpace(Cartesian1D.ONE));
-        Cartesian3D crossP = Cartesian3D.crossProduct(inter.getDirection(), thisPlane.getNormal());
-        if (crossP.dotProduct(otherPlane.getNormal()) < 0) {
-            final Cartesian2D tmp = p;
-            p           = q;
-            q           = tmp;
-        }
-        final SubHyperplane<Euclidean2D> l2DMinus =
-            new org.apache.commons.math4.geometry.euclidean.twod.Line(p, q, tolerance).wholeHyperplane();
-        final SubHyperplane<Euclidean2D> l2DPlus =
-            new org.apache.commons.math4.geometry.euclidean.twod.Line(q, p, tolerance).wholeHyperplane();
-
-        final BSPTree<Euclidean2D> splitTree = getRemainingRegion().getTree(false).split(l2DMinus);
-        final BSPTree<Euclidean2D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
-                                               new BSPTree<Euclidean2D>(Boolean.FALSE) :
-                                               new BSPTree<>(l2DPlus, new BSPTree<Euclidean2D>(Boolean.FALSE),
-                                                                        splitTree.getPlus(), null);
-
-        final BSPTree<Euclidean2D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
-                                               new BSPTree<Euclidean2D>(Boolean.FALSE) :
-                                                   new BSPTree<>(l2DMinus, new BSPTree<Euclidean2D>(Boolean.FALSE),
-                                                                            splitTree.getMinus(), null);
-
-        return new SplitSubHyperplane<>(new SubPlane(thisPlane.copySelf(), new PolygonsSet(plusTree, tolerance)),
-                                                   new SubPlane(thisPlane.copySelf(), new PolygonsSet(minusTree, tolerance)));
-
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3D.java
deleted file mode 100644
index 15400f7..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3D.java
+++ /dev/null
@@ -1,46 +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 org.apache.commons.math4.geometry.Vector;
-
-/**
- * This class implements vectors in a three-dimensional space.
- * @since 1.2
- */
-public abstract class Vector3D implements Vector<Euclidean3D> {
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see Cartesian3D#Cartesian3D(double, double, double)
-     */
-    public abstract double getX();
-
-    /** Get the ordinate of the vector.
-     * @return ordinate of the vector
-     * @see Cartesian3D#Cartesian3D(double, double, double)
-     */
-    public abstract double getY();
-
-    /** Get the height of the vector.
-     * @return height of the vector
-     * @see Cartesian3D#Cartesian3D(double, double, double)
-     */
-    public abstract double getZ();
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3DFormat.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3DFormat.java
deleted file mode 100644
index 1991c53..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3DFormat.java
+++ /dev/null
@@ -1,155 +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.text.FieldPosition;
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-import org.apache.commons.math4.exception.MathParseException;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.geometry.VectorFormat;
-import org.apache.commons.math4.util.CompositeFormat;
-
-/**
- * Formats a 3D vector in components list format "{x; y; z}".
- * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
- * any user-defined strings. The number format for components can be configured.</p>
- * <p>White space is ignored at parse time, even if it is in the prefix, suffix
- * or separator specifications. So even if the default separator does include a space
- * character that is used at format time, both input string "{1;1;1}" and
- * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be
- * returned. In the second case, however, the parse position after parsing will be
- * just after the closing curly brace, i.e. just before the trailing space.</p>
- * <p><b>Note:</b> using "," as a separator may interfere with the grouping separator
- * of the default {@link NumberFormat} for the current locale. Thus it is advised
- * to use a {@link NumberFormat} instance with disabled grouping in such a case.</p>
- *
- */
-public class Vector3DFormat extends VectorFormat<Euclidean3D> {
-
-    /**
-     * Create an instance with default settings.
-     * <p>The instance uses the default prefix, suffix and separator:
-     * "{", "}", and "; " and the default number format for components.</p>
-     */
-    public Vector3DFormat() {
-        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
-              CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with a custom number format for components.
-     * @param format the custom format for components.
-     */
-    public Vector3DFormat(final NumberFormat format) {
-        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix and separator.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     * @param separator separator to use instead of the default "; "
-     */
-    public Vector3DFormat(final String prefix, final String suffix,
-                         final String separator) {
-        super(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
-    }
-
-    /**
-     * Create an instance with custom prefix, suffix, separator and format
-     * for components.
-     * @param prefix prefix to use instead of the default "{"
-     * @param suffix suffix to use instead of the default "}"
-     * @param separator separator to use instead of the default "; "
-     * @param format the custom format for components.
-     */
-    public Vector3DFormat(final String prefix, final String suffix,
-                         final String separator, final NumberFormat format) {
-        super(prefix, suffix, separator, format);
-    }
-
-    /**
-     * Returns the default 3D vector format for the current locale.
-     * @return the default 3D vector format.
-     */
-    public static Vector3DFormat getInstance() {
-        return getInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns the default 3D vector format for the given locale.
-     * @param locale the specific locale used by the format.
-     * @return the 3D vector format specific to the given locale.
-     */
-    public static Vector3DFormat getInstance(final Locale locale) {
-        return new Vector3DFormat(CompositeFormat.getDefaultNumberFormat(locale));
-    }
-
-    /**
-     * Formats a {@link Vector3D} object to produce a string.
-     * @param vector the object to format.
-     * @param toAppendTo where the text is to be appended
-     * @param pos On input: an alignment field, if desired. On output: the
-     *            offsets of the alignment field
-     * @return the value passed in as toAppendTo.
-     */
-    @Override
-    public StringBuffer format(final Vector<Euclidean3D> vector, final StringBuffer toAppendTo,
-                               final FieldPosition pos) {
-        final Vector3D v3 = (Vector3D) vector;
-        return format(toAppendTo, pos, v3.getX(), v3.getY(), v3.getZ());
-    }
-
-    /**
-     * Parses a string to produce a {@link Vector3D} object.
-     * @param source the string to parse
-     * @return the parsed {@link Vector3D} object.
-     * @throws MathParseException if the beginning of the specified string
-     * cannot be parsed.
-     */
-    @Override
-    public Vector3D parse(final String source) throws MathParseException {
-        ParsePosition parsePosition = new ParsePosition(0);
-        Vector3D result = parse(source, parsePosition);
-        if (parsePosition.getIndex() == 0) {
-            throw new MathParseException(source,
-                                         parsePosition.getErrorIndex(),
-                                         Vector3D.class);
-        }
-        return result;
-    }
-
-    /**
-     * Parses a string to produce a {@link Vector3D} object.
-     * @param source the string to parse
-     * @param pos input/ouput parsing parameter.
-     * @return the parsed {@link Vector3D} object.
-     */
-    @Override
-    public Vector3D parse(final String source, final ParsePosition pos) {
-        final double[] coordinates = parseCoordinates(3, source, pos);
-        if (coordinates == null) {
-            return null;
-        }
-        return new Cartesian3D(coordinates[0], coordinates[1], coordinates[2]);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/package-info.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/package-info.java
deleted file mode 100644
index 92e2739..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/package-info.java
+++ /dev/null
@@ -1,24 +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.
- */
-/**
- *
- * <p>
- * This package provides basic 3D geometry components.
- * </p>
- *
- */
-package org.apache.commons.math4.geometry.euclidean.threed;
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Cartesian2D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Cartesian2D.java
deleted file mode 100644
index 1198ff6..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Cartesian2D.java
+++ /dev/null
@@ -1,492 +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.twod;
-
-import java.text.NumberFormat;
-
-import org.apache.commons.numbers.arrays.LinearCombination;
-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.MathUtils;
-
-/** This class represents a 2D point or a 2D vector.
- * <p>An instance of Cartesian2D represents the point with the corresponding
- * coordinates.</p>
- * <p>An instance of Cartesian2D 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 Cartesian2D extends Vector2D implements Point<Euclidean2D> {
-
-    /** Origin (coordinates: 0, 0). */
-    public static final Cartesian2D ZERO   = new Cartesian2D(0, 0);
-
-    // CHECKSTYLE: stop ConstantName
-    /** A vector with all coordinates set to NaN. */
-    public static final Cartesian2D NaN = new Cartesian2D(Double.NaN, Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A vector with all coordinates set to positive infinity. */
-    public static final Cartesian2D POSITIVE_INFINITY =
-        new Cartesian2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-
-    /** A vector with all coordinates set to negative infinity. */
-    public static final Cartesian2D NEGATIVE_INFINITY =
-        new Cartesian2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 266938651998679754L;
-
-    /** Abscissa. */
-    private final double x;
-
-    /** Ordinate. */
-    private final double y;
-
-    /** Simple constructor.
-     * Build a vector from its coordinates
-     * @param x abscissa
-     * @param y ordinate
-     * @see #getX()
-     * @see #getY()
-     */
-    public Cartesian2D(double x, double y) {
-        this.x = x;
-        this.y = y;
-    }
-
-    /** Simple constructor.
-     * Build a vector from its coordinates
-     * @param v coordinates array
-     * @exception DimensionMismatchException if array does not have 2 elements
-     * @see #toArray()
-     */
-    public Cartesian2D(double[] v) throws DimensionMismatchException {
-        if (v.length != 2) {
-            throw new DimensionMismatchException(v.length, 2);
-        }
-        this.x = v[0];
-        this.y = v[1];
-    }
-
-    /** 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 Cartesian2D(double a, Cartesian2D u) {
-        this.x = a * u.x;
-        this.y = a * u.y;
-    }
-
-    /** 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 Cartesian2D(double a1, Cartesian2D u1, double a2, Cartesian2D u2) {
-        this.x = a1 * u1.x + a2 * u2.x;
-        this.y = a1 * u1.y + a2 * u2.y;
-    }
-
-    /** 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 Cartesian2D(double a1, Cartesian2D u1, double a2, Cartesian2D u2,
-                   double a3, Cartesian2D u3) {
-        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
-        this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y;
-    }
-
-    /** 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 Cartesian2D(double a1, Cartesian2D u1, double a2, Cartesian2D u2,
-                   double a3, Cartesian2D u3, double a4, Cartesian2D u4) {
-        this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
-        this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y;
-    }
-
-    /** Get the abscissa of the vector.
-     * @return abscissa of the vector
-     * @see #Cartesian2D(double, double)
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** Get the ordinate of the vector.
-     * @return ordinate of the vector
-     * @see #Cartesian2D(double, double)
-     */
-    public double getY() {
-        return y;
-    }
-
-    /** Get the vector coordinates as a dimension 2 array.
-     * @return vector coordinates
-     * @see #Cartesian2D(double[])
-     */
-    public double[] toArray() {
-        return new double[] { x, y };
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Space getSpace() {
-        return Euclidean2D.getInstance();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D getZero() {
-        return ZERO;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm1() {
-        return FastMath.abs(x) + FastMath.abs(y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNorm() {
-        return FastMath.sqrt (x * x + y * y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormSq() {
-        return x * x + y * y;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getNormInf() {
-        return FastMath.max(FastMath.abs(x), FastMath.abs(y));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D add(Vector<Euclidean2D> v) {
-        Cartesian2D v2 = (Cartesian2D) v;
-        return new Cartesian2D(x + v2.getX(), y + v2.getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D add(double factor, Vector<Euclidean2D> v) {
-        Cartesian2D v2 = (Cartesian2D) v;
-        return new Cartesian2D(x + factor * v2.getX(), y + factor * v2.getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D subtract(Vector<Euclidean2D> p) {
-        Cartesian2D p3 = (Cartesian2D) p;
-        return new Cartesian2D(x - p3.x, y - p3.y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D subtract(double factor, Vector<Euclidean2D> v) {
-        Cartesian2D v2 = (Cartesian2D) v;
-        return new Cartesian2D(x - factor * v2.getX(), y - factor * v2.getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D normalize() throws MathArithmeticException {
-        double s = getNorm();
-        if (s == 0) {
-            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
-        }
-        return scalarMultiply(1 / s);
-    }
-
-    /** 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(Cartesian2D v1, Cartesian2D 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
-            final double n = FastMath.abs(LinearCombination.value(v1.x, v2.y, -v1.y, v2.x));
-            if (dot >= 0) {
-                return FastMath.asin(n / normProduct);
-            }
-            return FastMath.PI - FastMath.asin(n / normProduct);
-        }
-
-        // the vectors are sufficiently separated to use the cosine
-        return FastMath.acos(dot / normProduct);
-
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D negate() {
-        return new Cartesian2D(-x, -y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D scalarMultiply(double a) {
-        return new Cartesian2D(a * x, a * y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isNaN() {
-        return Double.isNaN(x) || Double.isNaN(y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isInfinite() {
-        return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance1(Vector<Euclidean2D> p) {
-        Cartesian2D p3 = (Cartesian2D) p;
-        final double dx = FastMath.abs(p3.x - x);
-        final double dy = FastMath.abs(p3.y - y);
-        return dx + dy;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point<Euclidean2D> p) {
-        return distance((Cartesian2D) p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Vector<Euclidean2D> v) {
-        return distance((Cartesian2D) 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(Cartesian2D c) {
-        final double dx = c.x - x;
-        final double dy = c.y - y;
-        return FastMath.sqrt(dx * dx + dy * dy);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceInf(Vector<Euclidean2D> p) {
-        Cartesian2D p3 = (Cartesian2D) p;
-        final double dx = FastMath.abs(p3.x - x);
-        final double dy = FastMath.abs(p3.y - y);
-        return FastMath.max(dx, dy);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distanceSq(Vector<Euclidean2D> p) {
-        Cartesian2D p3 = (Cartesian2D) p;
-        final double dx = p3.x - x;
-        final double dy = p3.y - y;
-        return dx * dx + dy * dy;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double dotProduct(final Vector<Euclidean2D> v) {
-        final Cartesian2D v2 = (Cartesian2D) v;
-        return LinearCombination.value(x, v2.x, y, v2.y);
-    }
-
-    /**
-     * Compute the cross-product of the instance and the given vector.
-     * <p>
-     * The cross product can be used to determine the location of a point
-     * with regard to the line formed by (p1, p2) and is calculated as:
-     * \[
-     *    P = (x_2 - x_1)(y_3 - y_1) - (y_2 - y_1)(x_3 - x_1)
-     * \]
-     * with \(p3 = (x_3, y_3)\) being this instance.
-     * <p>
-     * If the result is 0, the points are collinear, i.e. lie on a single straight line L;
-     * if it is positive, this point lies to the left, otherwise to the right of the line
-     * formed by (p1, p2).
-     *
-     * @param p1 first point of the line
-     * @param p2 second point of the line
-     * @return the cross-product
-     *
-     * @see <a href="http://en.wikipedia.org/wiki/Cross_product">Cross product (Wikipedia)</a>
-     */
-    public double crossProduct(final Cartesian2D p1, final Cartesian2D p2) {
-        final double x1 = p2.getX() - p1.getX();
-        final double y1 = getY() - p1.getY();
-        final double x2 = getX() - p1.getX();
-        final double y2 = p2.getY() - p1.getY();
-        return LinearCombination.value(x1, y1, -x2, y2);
-    }
-
-    /** 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 point
-     * @param p2 second point
-     * @return the distance between p1 and p2 according to the L<sub>2</sub> norm
-     */
-    public static double distance(Cartesian2D p1, Cartesian2D 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 point
-     * @param p2 second point
-     * @return the distance between p1 and p2 according to the L<sub>&infin;</sub> norm
-     */
-    public static double distanceInf(Cartesian2D p1, Cartesian2D 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 point
-     * @param p2 second point
-     * @return the square of the distance between p1 and p2
-     */
-    public static double distanceSq(Cartesian2D p1, Cartesian2D p2) {
-        return p1.distanceSq(p2);
-    }
-
-    /**
-     * Test for the equality of two 2D instances.
-     * <p>
-     * If all coordinates of two 2D vectors are exactly the same, and none are
-     * <code>Double.NaN</code>, the two 2D instances 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
-     * 2D vector are equal to <code>Double.NaN</code>, the 2D vector is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if two 2D Cartesian objects are equal, false if
-     *         object is null, not an instance of Cartesian2D, or
-     *         not equal to this Cartesian2D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Cartesian2D) {
-            final Cartesian2D rhs = (Cartesian2D)other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return (x == rhs.x) && (y == rhs.y);
-        }
-        return false;
-    }
-
-    /**
-     * Get a hashCode for the 2D coordinates.
-     * <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 542;
-        }
-        return 122 * (76 * MathUtils.hash(x) +  MathUtils.hash(y));
-    }
-
-    /** Get a string representation of this vector.
-     * @return a string representation of this vector
-     */
-    @Override
-    public String toString() {
-        return Vector2DFormat.getInstance().format(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString(final NumberFormat format) {
-        return new Vector2DFormat(format).format(this);
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/DiskGenerator.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/DiskGenerator.java
deleted file mode 100644
index ba2b7cc..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/DiskGenerator.java
+++ /dev/null
@@ -1,109 +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.twod;
-
-import java.util.List;
-
-import org.apache.commons.math4.fraction.BigFraction;
-import org.apache.commons.math4.geometry.enclosing.EnclosingBall;
-import org.apache.commons.math4.geometry.enclosing.SupportBallGenerator;
-import org.apache.commons.math4.util.FastMath;
-
-/** Class generating an enclosing ball from its support points.
- * @since 3.3
- */
-public class DiskGenerator implements SupportBallGenerator<Euclidean2D, Cartesian2D> {
-
-    /** {@inheritDoc} */
-    @Override
-    public EnclosingBall<Euclidean2D, Cartesian2D> ballOnSupport(final List<Cartesian2D> support) {
-
-        if (support.size() < 1) {
-            return new EnclosingBall<>(Cartesian2D.ZERO, Double.NEGATIVE_INFINITY);
-        } else {
-            final Cartesian2D vA = support.get(0);
-            if (support.size() < 2) {
-                return new EnclosingBall<>(vA, 0, vA);
-            } else {
-                final Cartesian2D vB = support.get(1);
-                if (support.size() < 3) {
-                    return new EnclosingBall<>(new Cartesian2D(0.5, vA, 0.5, vB),
-                                                                    0.5 * vA.distance(vB),
-                                                                    vA, vB);
-                } else {
-                    final Cartesian2D vC = support.get(2);
-                    // a disk is 2D can be defined as:
-                    // (1)   (x - x_0)^2 + (y - y_0)^2 = r^2
-                    // which can be written:
-                    // (2)   (x^2 + y^2) - 2 x_0 x - 2 y_0 y + (x_0^2 + y_0^2 - r^2) = 0
-                    // or simply:
-                    // (3)   (x^2 + y^2) + a x + b y + c = 0
-                    // with disk center coordinates -a/2, -b/2
-                    // If the disk exists, a, b and c are a non-zero solution to
-                    // [ (x^2  + y^2 )   x    y   1 ]   [ 1 ]   [ 0 ]
-                    // [ (xA^2 + yA^2)   xA   yA  1 ]   [ a ]   [ 0 ]
-                    // [ (xB^2 + yB^2)   xB   yB  1 ] * [ b ] = [ 0 ]
-                    // [ (xC^2 + yC^2)   xC   yC  1 ]   [ c ]   [ 0 ]
-                    // So the determinant of the matrix is zero. Computing this determinant
-                    // by expanding it using the minors m_ij of first row leads to
-                    // (4)   m_11 (x^2 + y^2) - m_12 x + m_13 y - m_14 = 0
-                    // So by identifying equations (2) and (4) we get the coordinates
-                    // of center as:
-                    //      x_0 = +m_12 / (2 m_11)
-                    //      y_0 = -m_13 / (2 m_11)
-                    // Note that the minors m_11, m_12 and m_13 all have the last column
-                    // filled with 1.0, hence simplifying the computation
-                    final BigFraction[] c2 = new BigFraction[] {
-                        new BigFraction(vA.getX()), new BigFraction(vB.getX()), new BigFraction(vC.getX())
-                    };
-                    final BigFraction[] c3 = new BigFraction[] {
-                        new BigFraction(vA.getY()), new BigFraction(vB.getY()), new BigFraction(vC.getY())
-                    };
-                    final BigFraction[] c1 = new BigFraction[] {
-                        c2[0].multiply(c2[0]).add(c3[0].multiply(c3[0])),
-                        c2[1].multiply(c2[1]).add(c3[1].multiply(c3[1])),
-                        c2[2].multiply(c2[2]).add(c3[2].multiply(c3[2]))
-                    };
-                    final BigFraction twoM11  = minor(c2, c3).multiply(2);
-                    final BigFraction m12     = minor(c1, c3);
-                    final BigFraction m13     = minor(c1, c2);
-                    final BigFraction centerX = m12.divide(twoM11);
-                    final BigFraction centerY = m13.divide(twoM11).negate();
-                    final BigFraction dx      = c2[0].subtract(centerX);
-                    final BigFraction dy      = c3[0].subtract(centerY);
-                    final BigFraction r2      = dx.multiply(dx).add(dy.multiply(dy));
-                    return new EnclosingBall<>(new Cartesian2D(centerX.doubleValue(),
-                                                                                 centerY.doubleValue()),
-                                                                    FastMath.sqrt(r2.doubleValue()),
-                                                                    vA, vB, vC);
-                }
-            }
-        }
-    }
-
-    /** Compute a dimension 3 minor, when 3<sup>d</sup> column is known to be filled with 1.0.
-     * @param c1 first column
-     * @param c2 second column
-     * @return value of the minor computed has an exact fraction
-     */
-    private BigFraction minor(final BigFraction[] c1, final BigFraction[] c2) {
-        return      c2[0].multiply(c1[2].subtract(c1[1])).
-                add(c2[1].multiply(c1[0].subtract(c1[2]))).
-                add(c2[2].multiply(c1[1].subtract(c1[0])));
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Euclidean2D.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Euclidean2D.java
deleted file mode 100644
index dc30c98..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Euclidean2D.java
+++ /dev/null
@@ -1,76 +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.twod;
-
-import java.io.Serializable;
-
-import org.apache.commons.math4.geometry.Space;
-import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
-
-/**
- * This class implements a two-dimensional space.
- * @since 3.0
- */
-public class Euclidean2D implements Serializable, Space {
-
-    /** Serializable version identifier. */
-    private static final long serialVersionUID = 4793432849757649566L;
-
-    /** Private constructor for the singleton.
-     */
-    private Euclidean2D() {
-    }
-
-    /** Get the unique instance.
-     * @return the unique instance
-     */
-    public static Euclidean2D getInstance() {
-        return LazyHolder.INSTANCE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Euclidean1D getSubSpace() {
-        return Euclidean1D.getInstance();
-    }
-
-    // CHECKSTYLE: stop HideUtilityClassConstructor
-    /** Holder for the instance.
-     * <p>We use here the Initialization On Demand Holder Idiom.</p>
-     */
-    private static class LazyHolder {
-        /** Cached field instance. */
-        private static final Euclidean2D INSTANCE = new Euclidean2D();
-    }
-    // CHECKSTYLE: resume HideUtilityClassConstructor
-
-    /** Handle deserialization of the singleton.
-     * @return the singleton instance
-     */
-    private Object readResolve() {
-        // return the singleton instance
-        return LazyHolder.INSTANCE;
-    }
-
-}
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Line.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Line.java
deleted file mode 100644
index 670d8f4..0000000
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/Line.java
+++ /dev/null
@@ -1,574 +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.twod;
-
-import org.apache.commons.numbers.arrays.LinearCombination;
-import org.apache.commons.numbers.angle.PlaneAngleRadians;
-import org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.geometry.Point;
-import org.apache.commons.math4.geometry.Vector;
-import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
-import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.math4.geometry.euclidean.oned.OrientedPoint;
-import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
-import org.apache.commons.math4.geometry.partitioning.Embedding;
-import org.apache.commons.math4.geometry.partitioning.Hyperplane;
-import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
-import org.apache.commons.math4.geometry.partitioning.Transform;
-import org.apache.commons.math4.util.FastMath;
-
-/** This class represents an oriented line in the 2D plane.
-
- * <p>An oriented line can be defined either by prolongating a line
- * segment between two points past these points, or by one point and
- * an angular direction (in trigonometric orientation).</p>
-
- * <p>Since it is oriented the two half planes at its two sides are
- * unambiguously identified as a left half plane and a right half
- * plane. This can be used to identify the interior and the exterior
- * in a simple way by local properties only when part of a line is
- * used to define part of a polygon boundary.</p>
-
- * <p>A line can also be used to completely define a reference frame
- * in the plane. It is sufficient to select one specific point in the
- * line (the orthogonal projection of the original reference frame on
- * the line) and to use the unit vector in the line direction and the
- * orthogonal vector oriented from left half plane to right half
- * plane. We define two coordinates by the process, the
- * <em>abscissa</em> along the line, and the <em>offset</em> across
- * the line. All points of the plane are uniquely identified by these
- * two coordinates. The line is the set of points at zero offset, the
- * left half plane is the set of points with negative offsets and the
- * right half plane is the set of points with positive offsets.</p>
-
- * @since 3.0
- */
-public class Line implements Hyperplane<Euclidean2D>, Embedding<Euclidean2D, Euclidean1D> {
-    /** Angle with respect to the abscissa axis. */
-    private double angle;
-
-    /** Cosine of the line angle. */
-    private double cos;
-
-    /** Sine of the line angle. */
-    private double sin;
-
-    /** Offset of the frame origin. */
-    private double originOffset;
-
-    /** Tolerance below which points are considered identical. */
-    private final double tolerance;
-
-    /** Reverse line. */
-    private Line reverse;
-
-    /** Build a line from two points.
-     * <p>The line is oriented from p1 to p2</p>
-     * @param p1 first point
-     * @param p2 second point
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public Line(final Cartesian2D p1, final Cartesian2D p2, final double tolerance) {
-        reset(p1, p2);
-        this.tolerance = tolerance;
-    }
-
-    /** Build a line from a point and an angle.
-     * @param p point belonging to the line
-     * @param angle angle of the line with respect to abscissa axis
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    public Line(final Cartesian2D p, final double angle, final double tolerance) {
-        reset(p, angle);
-        this.tolerance = tolerance;
-    }
-
-    /** Build a line from its internal characteristics.
-     * @param angle angle of the line with respect to abscissa axis
-     * @param cos cosine of the angle
-     * @param sin sine of the angle
-     * @param originOffset offset of the origin
-     * @param tolerance tolerance below which points are considered identical
-     * @since 3.3
-     */
-    private Line(final double angle, final double cos, final double sin,
-                 final double originOffset, final double tolerance) {
-        this.angle        = angle;
-        this.cos          = cos;
-        this.sin          = sin;
-        this.originOffset = originOffset;
-        this.tolerance    = tolerance;
-        this.reverse      = null;
-    }
-
-    /** Copy constructor.
-     * <p>The created instance is completely independent from the
-     * original instance, it is a deep copy.</p>
-     * @param line line to copy
-     */
-    public Line(final Line line) {
-        angle        = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(line.angle);
-        cos          = line.cos;
-        sin          = line.sin;
-        originOffset = line.originOffset;
-        tolerance    = line.tolerance;
-        reverse      = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Line copySelf() {
-        return new Line(this);
-    }
-
-    /** Reset the instance as if built from two points.
-     * <p>The line is oriented from p1 to p2</p>
-     * @param p1 first point
-     * @param p2 second point
-     */
-    public void reset(final Cartesian2D p1, final Cartesian2D p2) {
-        unlinkReverse();
-        final double dx = p2.getX() - p1.getX();
-        final double dy = p2.getY() - p1.getY();
-        final double d = FastMath.hypot(dx, dy);
-        if (d == 0.0) {
-            angle        = 0.0;
-            cos          = 1.0;
-            sin          = 0.0;
-            originOffset = p1.getY();
-        } else {
-            angle        = FastMath.PI + FastMath.atan2(-dy, -dx);
-            cos          = dx / d;
-            sin          = dy / d;
-            originOffset = LinearCombination.value(p2.getX(), p1.getY(), -p1.getX(), p2.getY()) / d;
-        }
-    }
-
-    /** Reset the instance as if built from a line and an angle.
-     * @param p point belonging to the line
-     * @param alpha angle of the line with respect to abscissa axis
-     */
-    public void reset(final Cartesian2D p, final double alpha) {
-        unlinkReverse();
-        this.angle   = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(alpha);
-        cos          = FastMath.cos(this.angle);
-        sin          = FastMath.sin(this.angle);
-        originOffset = LinearCombination.value(cos, p.getY(), -sin, p.getX());
-    }
-
-    /** Revert the instance.
-     */
-    public void revertSelf() {
-        unlinkReverse();
-        if (angle < FastMath.PI) {
-            angle += FastMath.PI;
-        } else {
-            angle -= FastMath.PI;
-        }
-        cos          = -cos;
-        sin          = -sin;
-        originOffset = -originOffset;
-    }
-
-    /** Unset the link between an instance and its reverse.
-     */
-    private void unlinkReverse() {
-        if (reverse != null) {
-            reverse.reverse = null;
-        }
-        reverse = null;
-    }
-
-    /** Get the reverse of the instance.
-     * <p>Get a line with reversed orientation with respect to the
-     * instance.</p>
-     * <p>
-     * As long as neither the instance nor its reverse are modified
-     * (i.e. as long as none of the {@link #reset(Cartesian2D, Cartesian2D)},
-     * {@link #reset(Cartesian2D, double)}, {@link #revertSelf()},
-     * {@link #setAngle(double)} or {@link #setOriginOffset(double)}
-     * methods are called), then the line and its reverse remain linked
-     * together so that {@code line.getReverse().getReverse() == line}.
-     * When one of the line is modified, the link is deleted as both
-     * instance becomes independent.
-     * </p>
-     * @return a new line, with orientation opposite to the instance orientation
-     */
-    public Line getReverse() {
-        if (reverse == null) {
-            reverse = new Line((angle < FastMath.PI) ? (angle + FastMath.PI) : (angle - FastMath.PI),
-                               -cos, -sin, -originOffset, tolerance);
-            reverse.reverse = this;
-        }
-        return reverse;
-    }
-
-    /** Transform a space point into a sub-space point.
-     * @param vector n-dimension point of the space
-     * @return (n-1)-dimension point of the sub-space corresponding to
-     * the specified space point
-     */
-    public Cartesian1D toSubSpace(Vector<Euclidean2D> vector) {
-        return toSubSpace((Cartesian2D) vector);
-    }
-
-    /** Transform a sub-space point into a space point.
-     * @param vector (n-1)-dimension point of the sub-space
-     * @return n-dimension point of the space corresponding to the
-     * specified sub-space point
-     */
-    public Cartesian2D toSpace(Vector<Euclidean1D> vector) {
-        return toSpace((Cartesian1D) vector);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian1D toSubSpace(final Point<Euclidean2D> point) {
-        return toSubSpace((Cartesian2D) point);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Cartesian2D toSpace(final Point<Euclidean1D> point) {
-        return toSpace((Cartesian1D) point);
-    }
-
-    /** Transform a space point into a sub-space point.
-     * @param cartesian n-dimension point of the space
-     * @return (n-1)-dimension point of the sub-space corresponding to
-     * the specified space point
-     */
-    public Cartesian1D toSubSpace(final Cartesian2D cartesian) {
-        return new Cartesian1D(LinearCombination.value(cos, cartesian.getX(), sin, cartesian.getY()));
-    }
-
-    /** Transform a sub-space point into a space point.
-     * @param cartesian (n-1)-dimension point of the sub-space
-     * @return n-dimension point of the space corresponding to the
-     * specified sub-space point
-     */
-    public Cartesian2D toSpace(Cartesian1D cartesian) {
-        final double abscissa = cartesian.getX();
-        return new Cartesian2D(LinearCombination.value(abscissa, cos, -originOffset, sin),
-                            LinearCombination.value(abscissa, sin,  originOffset, cos));
-    }
-
-    /** Get the intersection point of the instance and another line.
-     * @param other other line
-     * @return intersection point of the instance and the other line
-     * or null if there are no intersection points
-     */
-    public Cartesian2D intersection(final Line other) {
-        final double d = LinearCombination.value(sin, other.cos, -other.sin, cos);
-        if (FastMath.abs(d) < tolerance) {
-            return null;
-        }
-        return new Cartesian2D(LinearCombination.value(cos, other.originOffset, -other.cos, originOffset) / d,
-                            LinearCombination.value(sin, other.originOffset, -other.sin, originOffset) / d);
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public Point<Euclidean2D> project(Point<Euclidean2D> point) {
-        return toSpace(toSubSpace(point));
-    }
-
-    /** {@inheritDoc}
-     * @since 3.3
-     */
-    @Override
-    public double getTolerance() {
-        return tolerance;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public SubLine wholeHyperplane() {
-        return new SubLine(this, new IntervalsSet(tolerance));
-    }
-
-    /** Build a region covering the whole space.
-     * @return a region containing the instance (really a {@link
-     * PolygonsSet PolygonsSet} instance)
-     */
-    @Override
-    public PolygonsSet wholeSpace() {
-        return new PolygonsSet(tolerance);
-    }
-
-    /** Get the offset (oriented distance) of a parallel line.
-     * <p>This method should be called only for parallel lines otherwise
-     * the result is not meaningful.</p>
-     * <p>The offset is 0 if both lines are the same, it is
-     * positive if the line is on the right side of the instance and
-     * negative if it is on the left side, according to its natural
-     * orientation.</p>
-     * @param line line to check
-     * @return offset of the line
-     */
-    public double getOffset(final Line line) {
-        return originOffset +
-               (LinearCombination.value(cos, line.cos, sin, line.sin) > 0 ? -line.originOffset : line.originOffset);
-    }
-
-    /** Get the offset (oriented distance) of a vector.
-     * @param vector vector to check
-     * @return offset of the vector
-     */
-    public double getOffset(Vector<Euclidean2D> vector) {
-        return getOffset((Cartesian2D) vector);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double getOffset(final Point<Euclidean2D> point) {
-        return getOffset((Cartesian2D) point);
-    }
-
-    /** Get the offset (oriented distance) of a point.
-     * @param cartesian point to check
-     * @return offset of the point
-     */
-    public double getOffset(Cartesian2D cartesian) {
-        return LinearCombination.value(sin, cartesian.getX(), -cos, cartesian.getY(), 1.0, originOffset);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean sameOrientationAs(final Hyperplane<Euclidean2D> other) {
-        final Line otherL = (Line) other;
-        return LinearCombination.value(sin, otherL.sin, cos, otherL.cos) >= 0.0;
-    }
-
-    /** Get one point from the plane.
-     * @param abscissa desired abscissa for the point
-     * @param offset desired offset for the point
-     * @return one point in the plane, with given abscissa and offset
-     * relative to the line
-     */
-    public Cartesian2D getPointAt(final Cartesian1D abscissa, final double offset) {
-        final double x       = abscissa.getX();
-        final double dOffset = offset - originOffset;
-        return new Cartesian2D(LinearCombination.value(x, cos,  dOffset, sin),
-                            LinearCombination.value(x, sin, -dOffset, cos));
-    }
-
-    /** Check if the line contains a point.
-     * @param p point to check
-     * @return true if p belongs to the line
-     */
-    public boolean contains(final Cartesian2D p) {
-        return FastMath.abs(getOffset(p)) < tolerance;
-    }
-
-    /** Compute the distance between the instance and a point.
-     * <p>This is a shortcut for invoking FastMath.abs(getOffset(p)),
-     * and provides consistency with what is in the
-     * org.apache.commons.math4.geometry.euclidean.threed.Line class.</p>
-     *
-     * @param p to check
-     * @return distance between the instance and the point
-     * @since 3.1
-     */
-    public double distance(final Cartesian2D p) {
-        return FastMath.abs(getOffset(p));
-    }
-
-    /** Check the instance is parallel to another line.
-     * @param line other line to check
-     * @return true if the instance is parallel to the other line
-     * (they can have either the same or opposite orientations)
-     */
-    public boolean isParallelTo(final Line line) {
-        return FastMath.abs(LinearCombination.value(sin, line.cos, -cos, line.sin)) < tolerance;
-    }
-
-    /** Translate the line to force it passing by a point.
-     * @param p point by which the line should pass
-     */
-    public void translateToPoint(final Cartesian2D p) {
-        originOffset = LinearCombination.value(cos, p.getY(), -sin, p.getX());
-    }
-
-    /** Get the angle of the line.
-     * @return the angle of the line with respect to the abscissa axis
-     */
-    public double getAngle() {
-        return PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(angle);
-    }
-
-    /** Set the angle of the line.
-     * @param angle new angle of the line with respect to the abscissa axis
-     */
-    public void setAngle(final double angle) {
-        unlinkReverse();
-        this.angle = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(angle);
-        cos        = FastMath.cos(this.angle);
-        sin        = FastMath.sin(this.angle);
-    }
-
-    /** Get the offset of the origin.
-     * @return the offset of the origin
-     */
-    public double getOriginOffset() {
-        return originOffset;
-    }
-
-    /** Set the offset of the origin.
-     * @param offset offset of the origin
-     */
-    public void setOriginOffset(final double offset) {
-        unlinkReverse();
-        originOffset = offset;
-    }
-
-    /** Get a {@link org.apache.commons.math4.geometry.partitioning.Transform
-     * Transform} embedding an affine transform.
-     * @param cXX transform factor between input abscissa and output abscissa
-     * @param cYX transform factor between input abscissa and output ordinate
-     * @param cXY transform factor between input ordinate and output abscissa
-     * @param cYY transform factor between input ordinate and output ordinate
-     * @param cX1 transform addendum for output abscissa
-     * @param cY1 transform addendum for output ordinate
-     * @return a new transform that can be applied to either {@link
-     * Cartesian2D}, {@link Line Line} or {@link
-     * org.apache.commons.math4.geometry.partitioning.SubHyperplane
-     * SubHyperplane} instances
-     * @exception MathIllegalArgumentException if the transform is non invertible
-     * @since 4.0
-     */
-    public static Transform<Euclidean2D, Euclidean1D> getTransform(final double cXX,
-                                                                   final double cYX,
-                                                                   final double cXY,
-                                                                   final double cYY,
-                                                                   final double cX1,
-                                                                   final double cY1)
-        throws MathIllegalArgumentException {
-        return new LineTransform(cXX, cYX, cXY, cYY, cX1, cY1);
-    }
-
-    /** Class embedding an affine transform.
-     * <p>This class is used in order to apply an affine transform to a
-     * line. Using a specific object allow to perform some computations
-     * on the transform only once even if the same transform is to be
-     * applied to a large number of lines (for example to a large
-     * polygon)./<p>
-     */
-    private static class LineTransform implements Transform<Euclidean2D, Euclidean1D> {
-
-        /** Transform factor between input abscissa and output abscissa. */
-        private final double cXX;
-
-        /** Transform factor between input abscissa and output ordinate. */
-        private final double cYX;
-
-        /** Transform factor between input ordinate and output abscissa. */
-        private final double cXY;
-
... 25335 lines suppressed ...