You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2018/11/09 11:52:37 UTC

[commons-geometry] 03/08: GEOMETRY-23: removing Euclidean point classes and making Vector?D implement Point

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

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

commit 27fdf7dc30bb5c65c869be0af02aa5a04db20073
Author: Matt Juntunen <ma...@hotmail.com>
AuthorDate: Thu Oct 18 00:44:50 2018 -0400

    GEOMETRY-23: removing Euclidean point classes and making Vector?D implement Point
---
 .../apache/commons/geometry/core/AffinePoint.java  |   45 -
 .../org/apache/commons/geometry/core/Point.java    |   10 +-
 .../org/apache/commons/geometry/core/Vector.java   |   13 +-
 .../threed/enclosing/SphereGenerator.java          |   27 +-
 .../euclidean/twod/enclosing/DiskGenerator.java    |   18 +-
 .../geometry/enclosing/WelzlEncloser2DTest.java    |   56 +-
 .../geometry/enclosing/WelzlEncloser3DTest.java    |  111 +-
 .../threed/enclosing/SphereGeneratorTest.java      |  114 +-
 .../twod/enclosing/DiskGeneratorTest.java          |   58 +-
 .../commons/geometry/euclidean/EuclideanPoint.java |   67 -
 .../geometry/euclidean/EuclideanVector.java        |   51 +-
 .../euclidean/MultiDimensionalEuclideanVector.java |   19 +-
 .../geometry/euclidean/oned/Cartesian1D.java       |   74 -
 .../geometry/euclidean/oned/IntervalsSet.java      |   96 +-
 .../geometry/euclidean/oned/OrientedPoint.java     |   14 +-
 .../commons/geometry/euclidean/oned/Point1D.java   |  278 ----
 .../geometry/euclidean/oned/SubOrientedPoint.java  |   18 +-
 .../commons/geometry/euclidean/oned/Vector1D.java  |  149 +-
 .../commons/geometry/euclidean/package-info.java   |   41 +-
 .../geometry/euclidean/threed/Cartesian3D.java     |  111 --
 .../commons/geometry/euclidean/threed/Line.java    |   38 +-
 .../euclidean/threed/OutlineExtractor.java         |   62 +-
 .../commons/geometry/euclidean/threed/Plane.java   |   66 +-
 .../commons/geometry/euclidean/threed/Point3D.java |  318 ----
 .../geometry/euclidean/threed/PolyhedronsSet.java  |  182 +--
 .../commons/geometry/euclidean/threed/Segment.java |   10 +-
 .../euclidean/threed/SphericalCoordinates.java     |    8 -
 .../commons/geometry/euclidean/threed/SubLine.java |   14 +-
 .../geometry/euclidean/threed/SubPlane.java        |   40 +-
 .../geometry/euclidean/threed/Vector3D.java        |  246 +--
 .../geometry/euclidean/twod/Cartesian2D.java       |  100 --
 .../commons/geometry/euclidean/twod/Line.java      |   64 +-
 .../geometry/euclidean/twod/NestedLoops.java       |   22 +-
 .../commons/geometry/euclidean/twod/Point2D.java   |  298 ----
 .../geometry/euclidean/twod/PolarCoordinates.java  |    9 -
 .../geometry/euclidean/twod/PolygonsSet.java       |  152 +-
 .../commons/geometry/euclidean/twod/Segment.java   |   14 +-
 .../commons/geometry/euclidean/twod/SubLine.java   |   48 +-
 .../commons/geometry/euclidean/twod/Vector2D.java  |  201 ++-
 .../core/partitioning/CharacterizationTest.java    |  186 +--
 .../geometry/euclidean/EuclideanTestUtils.java     |   68 +-
 .../geometry/euclidean/internal/VectorsTest.java   |    3 +-
 .../geometry/euclidean/oned/Cartesian1DTest.java   |   90 -
 .../geometry/euclidean/oned/IntervalsSetTest.java  |  120 +-
 .../geometry/euclidean/oned/OrientedPointTest.java |   64 +-
 .../geometry/euclidean/oned/Point1DTest.java       |  333 ----
 .../euclidean/oned/SubOrientedPointTest.java       |   38 +-
 .../geometry/euclidean/oned/Vector1DTest.java      |  100 +-
 .../geometry/euclidean/threed/Cartesian3DTest.java |  144 --
 .../geometry/euclidean/threed/LineTest.java        |   66 +-
 .../geometry/euclidean/threed/OBJWriter.java       |   50 +-
 .../geometry/euclidean/threed/PLYParser.java       |    8 +-
 .../geometry/euclidean/threed/PlaneTest.java       |   70 +-
 .../geometry/euclidean/threed/Point3DTest.java     |  380 -----
 .../euclidean/threed/PolyhedronsSetTest.java       |  894 +++++-----
 .../euclidean/threed/SphericalCoordinatesTest.java |   25 +-
 .../geometry/euclidean/threed/SubLineTest.java     |   64 +-
 .../geometry/euclidean/threed/Vector3DTest.java    |  159 +-
 .../geometry/euclidean/twod/Cartesian2DTest.java   |  142 --
 .../commons/geometry/euclidean/twod/LineTest.java  |   66 +-
 .../geometry/euclidean/twod/NestedLoopsTest.java   |   16 +-
 .../geometry/euclidean/twod/Point2DTest.java       |  362 -----
 .../euclidean/twod/PolarCoordinatesTest.java       |   26 +-
 .../geometry/euclidean/twod/PolygonsSetTest.java   | 1714 ++++++++++----------
 .../geometry/euclidean/twod/SegmentTest.java       |   12 +-
 .../geometry/euclidean/twod/SubLineTest.java       |   64 +-
 .../geometry/euclidean/twod/Vector2DTest.java      |  146 +-
 .../twod/hull/AbstractConvexHullGenerator2D.java   |   10 +-
 .../euclidean/twod/hull/AklToussaintHeuristic.java |   37 +-
 .../geometry/euclidean/twod/hull/ConvexHull2D.java |   32 +-
 .../euclidean/twod/hull/ConvexHullGenerator2D.java |    6 +-
 .../euclidean/twod/hull/MonotoneChain.java         |   28 +-
 .../twod/hull/AklToussaintHeuristicTest.java       |    4 +-
 .../hull/ConvexHullGenerator2DAbstractTest.java    |  223 ++-
 .../euclidean/twod/hull/MonotoneChainTest.java     |   22 +-
 .../spherical/twod/PropertiesComputer.java         |   11 +-
 .../spherical/twod/SphericalPolygonsSet.java       |   25 +-
 77 files changed, 3407 insertions(+), 5663 deletions(-)

diff --git a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/AffinePoint.java b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/AffinePoint.java
deleted file mode 100644
index a684da4..0000000
--- a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/AffinePoint.java
+++ /dev/null
@@ -1,45 +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.geometry.core;
-
-/** Interface that adds affine space operations to the base {@link Point}
- * interface. Affine spaces consist of points and displacement vectors
- * representing translations between points. Since this interface extends
- * {@link Point}, the represented space is both affine and metric.
- *
- * @see <a href="https://en.wikipedia.org/wiki/Affine_space">Affine space</a>
- * @see <a href="https://en.wikipedia.org/wiki/Metric_space">Metric space</a>
- * @see Point
- *
- * @param <P> Point implementation type
- * @param <V> Vector implementation type
- */
-public interface AffinePoint<P extends AffinePoint<P, V>, V extends Vector<V>> extends Point<P> {
-
-    /** Get the displacement vector from this point to p.
-     * @param p second point
-     * @return The displacement vector from this point to p.
-     */
-    V subtract(P p);
-
-    /** Get the point resulting from adding the given displacement
-     * vector to this point.
-     * @param v displacement vector
-     * @return point resulting from displacing this point by v
-     */
-    P add(V v);
-}
diff --git a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Point.java b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Point.java
index 191088f..32209f4 100644
--- a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Point.java
+++ b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Point.java
@@ -17,12 +17,20 @@
 package org.apache.commons.geometry.core;
 
 /** Interface representing a point in a mathematical space.
- * Implementations of this interface are sufficient to define a
+ *
+ * <p>Implementations of this interface are sufficient to define a
  * space since they define both the structure of the points making up
  * the space and the operations permitted on them. The only mathematical
  * requirement at this level is that the represented space have a defined
  * distance metric, meaning an operation that can compute the distance
  * between two points (ie, the space must be a metric space).
+ * </p>
+ *
+ * <p>This interface uses self-referencing generic parameters to ensure
+ * that implementations are only used with instances of their own type.
+ * This removes the need for casting inside of methods in order to access
+ * implementation-specific data, such as coordinate values.
+ * </p>
  *
  * @see <a href="https://en.wikipedia.org/wiki/Metric_space">Metric space</a>
  *
diff --git a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Vector.java b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Vector.java
index 043cccc..87b8b82 100644
--- a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Vector.java
+++ b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/Vector.java
@@ -18,15 +18,18 @@ package org.apache.commons.geometry.core;
 
 import org.apache.commons.geometry.core.exception.IllegalNormException;
 
-/** Interface representing a vector in a vector space. The most common
- * use of this interface is to represent displacement vectors in an affine
- * space.
+/** Interface representing a vector in a vector space or displacement vectors
+ * in an affine space.
+ *
+ * <p>This interface uses self-referencing generic parameters to ensure
+ * that implementations are only used with instances of their own type.
+ * This removes the need for casting inside of methods in order to access
+ * implementation-specific data, such as coordinate values.
+ * </p>
  *
  * @see <a href="https://en.wikipedia.org/wiki/Vector_space">Vector space</a>
  * @see <a href="https://en.wikipedia.org/wiki/Affine_space">Affine space</a>
  *
- * @see AffinePoint
- *
  * @param <V> Vector implementation type
  */
 public interface Vector<V extends Vector<V>> extends Spatial {
diff --git a/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGenerator.java b/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGenerator.java
index 0111191..80c9dbd 100644
--- a/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGenerator.java
+++ b/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGenerator.java
@@ -21,41 +21,40 @@ import java.util.List;
 
 import org.apache.commons.geometry.enclosing.EnclosingBall;
 import org.apache.commons.geometry.enclosing.SupportBallGenerator;
-import org.apache.commons.geometry.euclidean.threed.Cartesian3D;
 import org.apache.commons.geometry.euclidean.threed.Plane;
-import org.apache.commons.geometry.euclidean.threed.Point3D;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.enclosing.DiskGenerator;
 import org.apache.commons.numbers.fraction.BigFraction;
 
 /** Class generating an enclosing ball from its support points.
  */
-public class SphereGenerator implements SupportBallGenerator<Point3D> {
+public class SphereGenerator implements SupportBallGenerator<Vector3D> {
 
     /** {@inheritDoc} */
     @Override
-    public EnclosingBall<Point3D> ballOnSupport(final List<Point3D> support) {
+    public EnclosingBall<Vector3D> ballOnSupport(final List<Vector3D> support) {
 
         if (support.size() < 1) {
-            return new EnclosingBall<>(Point3D.ZERO, Double.NEGATIVE_INFINITY);
+            return new EnclosingBall<>(Vector3D.ZERO, Double.NEGATIVE_INFINITY);
         } else {
-            final Point3D vA = support.get(0);
+            final Vector3D vA = support.get(0);
             if (support.size() < 2) {
                 return new EnclosingBall<>(vA, 0, vA);
             } else {
-                final Point3D vB = support.get(1);
+                final Vector3D vB = support.get(1);
                 if (support.size() < 3) {
-                    return new EnclosingBall<>(Point3D.vectorCombination(0.5, vA, 0.5, vB),
+                    return new EnclosingBall<>(Vector3D.linearCombination(0.5, vA, 0.5, vB),
                                                                     0.5 * vA.distance(vB),
                                                                     vA, vB);
                 } else {
-                    final Point3D vC = support.get(2);
+                    final Vector3D vC = support.get(2);
                     if (support.size() < 4) {
 
                         // delegate to 2D disk generator
                         final Plane p = new Plane(vA, vB, vC,
                                                   1.0e-10 * (norm1(vA) + norm1(vB) + norm1(vC)));
-                        final EnclosingBall<Point2D> disk =
+                        final EnclosingBall<Vector2D> disk =
                                 new DiskGenerator().ballOnSupport(Arrays.asList(p.toSubSpace(vA),
                                                                                 p.toSubSpace(vB),
                                                                                 p.toSubSpace(vC)));
@@ -65,7 +64,7 @@ public class SphereGenerator implements SupportBallGenerator<Point3D> {
                                                                         disk.getRadius(), vA, vB, vC);
 
                     } else {
-                        final Point3D vD = support.get(3);
+                        final Vector3D 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:
@@ -118,7 +117,7 @@ public class SphereGenerator implements SupportBallGenerator<Point3D> {
                         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<>(Point3D.of(centerX.doubleValue(),
+                        return new EnclosingBall<>(Vector3D.of(centerX.doubleValue(),
                                                                                      centerY.doubleValue(),
                                                                                      centerZ.doubleValue()),
                                                                         Math.sqrt(r2.doubleValue()),
@@ -156,7 +155,7 @@ public class SphereGenerator implements SupportBallGenerator<Point3D> {
      * @return L<sub>1</sub> vector norm for the given set of coordinates
      * @see <a href="http://mathworld.wolfram.com/L1-Norm.html">L1 Norm</a>
      */
-    private double norm1(final Cartesian3D coord) {
+    private double norm1(final Vector3D coord) {
         return Math.abs(coord.getX()) + Math.abs(coord.getY()) + Math.abs(coord.getZ());
     }
 }
diff --git a/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGenerator.java b/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGenerator.java
index bab99ac..15a6382 100644
--- a/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGenerator.java
+++ b/commons-geometry-enclosing/src/main/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGenerator.java
@@ -20,31 +20,31 @@ import java.util.List;
 
 import org.apache.commons.geometry.enclosing.EnclosingBall;
 import org.apache.commons.geometry.enclosing.SupportBallGenerator;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.numbers.fraction.BigFraction;
 
 /** Class generating an enclosing ball from its support points.
  */
-public class DiskGenerator implements SupportBallGenerator<Point2D> {
+public class DiskGenerator implements SupportBallGenerator<Vector2D> {
 
     /** {@inheritDoc} */
     @Override
-    public EnclosingBall<Point2D> ballOnSupport(final List<Point2D> support) {
+    public EnclosingBall<Vector2D> ballOnSupport(final List<Vector2D> support) {
 
         if (support.size() < 1) {
-            return new EnclosingBall<>(Point2D.ZERO, Double.NEGATIVE_INFINITY);
+            return new EnclosingBall<>(Vector2D.ZERO, Double.NEGATIVE_INFINITY);
         } else {
-            final Point2D vA = support.get(0);
+            final Vector2D vA = support.get(0);
             if (support.size() < 2) {
                 return new EnclosingBall<>(vA, 0, vA);
             } else {
-                final Point2D vB = support.get(1);
+                final Vector2D vB = support.get(1);
                 if (support.size() < 3) {
-                    return new EnclosingBall<>(Point2D.vectorCombination(0.5, vA, 0.5, vB),
+                    return new EnclosingBall<>(Vector2D.linearCombination(0.5, vA, 0.5, vB),
                                                                     0.5 * vA.distance(vB),
                                                                     vA, vB);
                 } else {
-                    final Point2D vC = support.get(2);
+                    final Vector2D 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:
@@ -85,7 +85,7 @@ public class DiskGenerator implements SupportBallGenerator<Point2D> {
                     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<>(Point2D.of(centerX.doubleValue(),
+                    return new EnclosingBall<>(Vector2D.of(centerX.doubleValue(),
                                                                                  centerY.doubleValue()),
                                                                     Math.sqrt(r2.doubleValue()),
                                                                     vA, vB, vC);
diff --git a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser2DTest.java b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser2DTest.java
index 5f6fb80..6d0f0e8 100644
--- a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser2DTest.java
+++ b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser2DTest.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.enclosing.DiskGenerator;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.simple.RandomSource;
@@ -33,36 +33,36 @@ public class WelzlEncloser2DTest {
     @Test
     public void testNullList() {
         DiskGenerator generator = new DiskGenerator();
-        WelzlEncloser<Point2D> encloser =
+        WelzlEncloser<Vector2D> encloser =
                 new WelzlEncloser<>(1.0e-10, generator);
-        EnclosingBall<Point2D> ball = encloser.enclose(null);
+        EnclosingBall<Vector2D> ball = encloser.enclose(null);
         Assert.assertTrue(ball.getRadius() < 0);
     }
 
     @Test
     public void testNoPoints() {
         DiskGenerator generator = new DiskGenerator();
-        WelzlEncloser<Point2D> encloser =
+        WelzlEncloser<Vector2D> encloser =
                 new WelzlEncloser<>(1.0e-10, generator);
-        EnclosingBall<Point2D> ball = encloser.enclose(new ArrayList<Point2D>());
+        EnclosingBall<Vector2D> ball = encloser.enclose(new ArrayList<Vector2D>());
         Assert.assertTrue(ball.getRadius() < 0);
     }
 
     @Test
     public void testRegularPoints() {
-        List<Point2D> list = buildList(22, 26, 30, 38, 64, 28,  8, 54, 11, 15);
+        List<Vector2D> list = buildList(22, 26, 30, 38, 64, 28,  8, 54, 11, 15);
         checkDisk(list, Arrays.asList(list.get(2), list.get(3), list.get(4)));
     }
 
     @Test
     public void testSolutionOnDiameter() {
-        List<Point2D> list = buildList(22, 26, 30, 38, 64, 28,  8, 54);
+        List<Vector2D> list = buildList(22, 26, 30, 38, 64, 28,  8, 54);
         checkDisk(list, Arrays.asList(list.get(2), list.get(3)));
     }
 
     @Test
     public void testReducingBall1() {
-        List<Point2D> list = buildList(0.05380958511396061, 0.57332359658700000,
+        List<Vector2D> list = buildList(0.05380958511396061, 0.57332359658700000,
                                         0.99348810731127870, 0.02056421361521466,
                                         0.01203950647796437, 0.99779675042261860,
                                         0.00810189987706078, 0.00589246003827815,
@@ -72,7 +72,7 @@ public class WelzlEncloser2DTest {
 
     @Test
     public void testReducingBall2() {
-        List<Point2D> list = buildList(0.016930586154703, 0.333955448537779,
+        List<Vector2D> list = buildList(0.016930586154703, 0.333955448537779,
                                         0.987189104892331, 0.969778855274507,
                                         0.983696889599935, 0.012904580013266,
                                         0.013114499572905, 0.034740156356895);
@@ -84,39 +84,39 @@ public class WelzlEncloser2DTest {
         UniformRandomProvider random = RandomSource.create(RandomSource.WELL_1024_A, 0xa2a63cad12c01fb2l);
         for (int k = 0; k < 100; ++k) {
             int nbPoints = random.nextInt(10000);
-            List<Point2D> points = new ArrayList<>();
+            List<Vector2D> points = new ArrayList<>();
             for (int i = 0; i < nbPoints; ++i) {
                 double x = random.nextDouble();
                 double y = random.nextDouble();
-                points.add(Point2D.of(x, y));
+                points.add(Vector2D.of(x, y));
             }
             checkDisk(points);
         }
     }
 
-    private List<Point2D> buildList(final double ... coordinates) {
-        List<Point2D> list = new ArrayList<>(coordinates.length / 2);
+    private List<Vector2D> buildList(final double ... coordinates) {
+        List<Vector2D> list = new ArrayList<>(coordinates.length / 2);
         for (int i = 0; i < coordinates.length; i += 2) {
-            list.add(Point2D.of(coordinates[i], coordinates[i + 1]));
+            list.add(Vector2D.of(coordinates[i], coordinates[i + 1]));
         }
         return list;
     }
 
-    private void checkDisk(List<Point2D> points, List<Point2D> refSupport) {
+    private void checkDisk(List<Vector2D> points, List<Vector2D> refSupport) {
 
-        EnclosingBall<Point2D> disk = checkDisk(points);
+        EnclosingBall<Vector2D> disk = checkDisk(points);
 
         // compare computed disk with expected disk
         DiskGenerator generator = new DiskGenerator();
-        EnclosingBall<Point2D> expected = generator.ballOnSupport(refSupport);
+        EnclosingBall<Vector2D> expected = generator.ballOnSupport(refSupport);
         Assert.assertEquals(refSupport.size(), disk.getSupportSize());
         Assert.assertEquals(expected.getRadius(),        disk.getRadius(),        1.0e-10);
         Assert.assertEquals(expected.getCenter().getX(), disk.getCenter().getX(), 1.0e-10);
         Assert.assertEquals(expected.getCenter().getY(), disk.getCenter().getY(), 1.0e-10);
 
-        for (Point2D s : disk.getSupport()) {
+        for (Vector2D s : disk.getSupport()) {
             boolean found = false;
-            for (Point2D rs : refSupport) {
+            for (Vector2D rs : refSupport) {
                 if (s == rs) {
                     found = true;
                 }
@@ -126,14 +126,14 @@ public class WelzlEncloser2DTest {
 
         // check removing any point of the support disk fails to enclose the point
         for (int i = 0; i < disk.getSupportSize(); ++i) {
-            List<Point2D> reducedSupport = new ArrayList<>();
+            List<Vector2D> reducedSupport = new ArrayList<>();
             int count = 0;
-            for (Point2D s : disk.getSupport()) {
+            for (Vector2D s : disk.getSupport()) {
                 if (count++ != i) {
                     reducedSupport.add(s);
                 }
             }
-            EnclosingBall<Point2D> reducedDisk = generator.ballOnSupport(reducedSupport);
+            EnclosingBall<Vector2D> reducedDisk = generator.ballOnSupport(reducedSupport);
             boolean foundOutside = false;
             for (int j = 0; j < points.size() && !foundOutside; ++j) {
                 if (!reducedDisk.contains(points.get(j), 1.0e-10)) {
@@ -145,20 +145,20 @@ public class WelzlEncloser2DTest {
 
     }
 
-    private EnclosingBall<Point2D> checkDisk(List<Point2D> points) {
+    private EnclosingBall<Vector2D> checkDisk(List<Vector2D> points) {
 
-        WelzlEncloser<Point2D> encloser =
+        WelzlEncloser<Vector2D> encloser =
                 new WelzlEncloser<>(1.0e-10, new DiskGenerator());
-        EnclosingBall<Point2D> disk = encloser.enclose(points);
+        EnclosingBall<Vector2D> disk = encloser.enclose(points);
 
         // all points are enclosed
-        for (Point2D v : points) {
+        for (Vector2D v : points) {
             Assert.assertTrue(disk.contains(v, 1.0e-10));
         }
 
-        for (Point2D v : points) {
+        for (Vector2D v : points) {
             boolean inSupport = false;
-            for (Point2D s : disk.getSupport()) {
+            for (Vector2D s : disk.getSupport()) {
                 if (v == s) {
                     inSupport = true;
                 }
diff --git a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser3DTest.java b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser3DTest.java
index a9b1dc1..d113841 100644
--- a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser3DTest.java
+++ b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/WelzlEncloser3DTest.java
@@ -16,12 +16,11 @@
  */
 package org.apache.commons.geometry.enclosing;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.commons.geometry.euclidean.threed.Point3D;
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.geometry.euclidean.threed.enclosing.SphereGenerator;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.sampling.UnitSphereSampler;
@@ -35,67 +34,67 @@ public class WelzlEncloser3DTest {
     @Test
     public void testNullList() {
         SphereGenerator generator = new SphereGenerator();
-        WelzlEncloser<Point3D> encloser =
+        WelzlEncloser<Vector3D> encloser =
                 new WelzlEncloser<>(1.0e-10, generator);
-        EnclosingBall<Point3D> ball = encloser.enclose(null);
+        EnclosingBall<Vector3D> ball = encloser.enclose(null);
         Assert.assertTrue(ball.getRadius() < 0);
     }
 
     @Test
     public void testNoPoints() {
         SphereGenerator generator = new SphereGenerator();
-        WelzlEncloser<Point3D> encloser =
+        WelzlEncloser<Vector3D> encloser =
                 new WelzlEncloser<>(1.0e-10, generator);
-        EnclosingBall<Point3D> ball = encloser.enclose(new ArrayList<Point3D>());
+        EnclosingBall<Vector3D> ball = encloser.enclose(new ArrayList<Vector3D>());
         Assert.assertTrue(ball.getRadius() < 0);
     }
 
     @Test
     public void testReducingBall() {
-        List<Point3D> list =
-                Arrays.asList(Point3D.of(-7.140397329568118, -16.571661242582177,  11.714458961735405),
-                              Point3D.of(-7.137986707455888, -16.570767323375720,  11.708602108715928),
-                              Point3D.of(-7.139185068549035, -16.570891204702250,  11.715554057357394),
-                              Point3D.of(-7.142682716997507, -16.571609818234290,  11.710787934580328),
-                              Point3D.of(-7.139018392423351, -16.574405614157020,  11.710518716711425),
-                              Point3D.of(-7.140870659936730, -16.567993074240455,  11.710914678204503),
-                              Point3D.of(-7.136350173659562, -16.570498228820930,  11.713965225900928),
-                              Point3D.of(-7.141675762759172, -16.572852471407028,  11.714033471449508),
-                              Point3D.of(-7.140453077221105, -16.570212820780647,  11.708624578004980),
-                              Point3D.of(-7.140322188726825, -16.574152894557717,  11.710305611121410),
-                              Point3D.of(-7.141116131477088, -16.574061164624560,  11.712938509321699));
-        WelzlEncloser<Point3D> encloser =
+        List<Vector3D> list =
+                Arrays.asList(Vector3D.of(-7.140397329568118, -16.571661242582177,  11.714458961735405),
+                              Vector3D.of(-7.137986707455888, -16.570767323375720,  11.708602108715928),
+                              Vector3D.of(-7.139185068549035, -16.570891204702250,  11.715554057357394),
+                              Vector3D.of(-7.142682716997507, -16.571609818234290,  11.710787934580328),
+                              Vector3D.of(-7.139018392423351, -16.574405614157020,  11.710518716711425),
+                              Vector3D.of(-7.140870659936730, -16.567993074240455,  11.710914678204503),
+                              Vector3D.of(-7.136350173659562, -16.570498228820930,  11.713965225900928),
+                              Vector3D.of(-7.141675762759172, -16.572852471407028,  11.714033471449508),
+                              Vector3D.of(-7.140453077221105, -16.570212820780647,  11.708624578004980),
+                              Vector3D.of(-7.140322188726825, -16.574152894557717,  11.710305611121410),
+                              Vector3D.of(-7.141116131477088, -16.574061164624560,  11.712938509321699));
+        WelzlEncloser<Vector3D> encloser =
                 new WelzlEncloser<>(1.0e-10, new SphereGenerator());
-        EnclosingBall<Point3D> ball = encloser.enclose(list);
+        EnclosingBall<Vector3D> ball = encloser.enclose(list);
         Assert.assertTrue(ball.getRadius() > 0);
     }
 
     @Test
     public void testInfiniteLoop() {
         // this test used to generate an infinite loop
-        List<Point3D> list =
-                Arrays.asList(Point3D.of( -0.89227075512164380,  -2.89317694645713900,  14.84572323743355500),
-                              Point3D.of( -0.92099498940693580,  -2.31086108263908940,  12.92071026467688300),
-                              Point3D.of( -0.85227999411005200,  -3.06314731441320730,  15.40163831651287000),
-                              Point3D.of( -1.77399413020785970,  -3.65630391378114260,  14.13190097751873400),
-                              Point3D.of(  0.33157833272465354,  -2.22813591757792160,  14.21225234159008200),
-                              Point3D.of( -1.53065579165484400,  -1.65692084770139570,  14.61483055714788500),
-                              Point3D.of( -1.08457093941217140,  -1.96100325935602980,  13.09265170575555000),
-                              Point3D.of(  0.30029469589708850,  -3.05470831395667370,  14.56352400426342600),
-                              Point3D.of( -0.95007443938638460,  -1.86810946486118360,  15.14491234340057000),
-                              Point3D.of( -1.89661503804130830,  -2.17004080885185860,  14.81235128513927000),
-                              Point3D.of( -0.72193328761607530,  -1.44513142833618270,  14.52355724218561800),
-                              Point3D.of( -0.26895980939606550,  -3.69512371522084140,  14.72272846327652000),
-                              Point3D.of( -1.53501693431786170,  -3.25055166611021900,  15.15509062584274800),
-                              Point3D.of( -0.71727553535519410,  -3.62284279460799100,  13.26256700929380700),
-                              Point3D.of( -0.30220950676137365,  -3.25410412500779070,  13.13682612771606000),
-                              Point3D.of( -0.04543996608267075,  -1.93081853923797750,  14.79497997883171400),
-                              Point3D.of( -1.53348892951571640,  -3.66688919703524900,  14.73095600812074200),
-                              Point3D.of( -0.98034899533935820,  -3.34004481162763960,  13.03245014017556800));
-
-        WelzlEncloser<Point3D> encloser =
+        List<Vector3D> list =
+                Arrays.asList(Vector3D.of( -0.89227075512164380,  -2.89317694645713900,  14.84572323743355500),
+                              Vector3D.of( -0.92099498940693580,  -2.31086108263908940,  12.92071026467688300),
+                              Vector3D.of( -0.85227999411005200,  -3.06314731441320730,  15.40163831651287000),
+                              Vector3D.of( -1.77399413020785970,  -3.65630391378114260,  14.13190097751873400),
+                              Vector3D.of(  0.33157833272465354,  -2.22813591757792160,  14.21225234159008200),
+                              Vector3D.of( -1.53065579165484400,  -1.65692084770139570,  14.61483055714788500),
+                              Vector3D.of( -1.08457093941217140,  -1.96100325935602980,  13.09265170575555000),
+                              Vector3D.of(  0.30029469589708850,  -3.05470831395667370,  14.56352400426342600),
+                              Vector3D.of( -0.95007443938638460,  -1.86810946486118360,  15.14491234340057000),
+                              Vector3D.of( -1.89661503804130830,  -2.17004080885185860,  14.81235128513927000),
+                              Vector3D.of( -0.72193328761607530,  -1.44513142833618270,  14.52355724218561800),
+                              Vector3D.of( -0.26895980939606550,  -3.69512371522084140,  14.72272846327652000),
+                              Vector3D.of( -1.53501693431786170,  -3.25055166611021900,  15.15509062584274800),
+                              Vector3D.of( -0.71727553535519410,  -3.62284279460799100,  13.26256700929380700),
+                              Vector3D.of( -0.30220950676137365,  -3.25410412500779070,  13.13682612771606000),
+                              Vector3D.of( -0.04543996608267075,  -1.93081853923797750,  14.79497997883171400),
+                              Vector3D.of( -1.53348892951571640,  -3.66688919703524900,  14.73095600812074200),
+                              Vector3D.of( -0.98034899533935820,  -3.34004481162763960,  13.03245014017556800));
+
+        WelzlEncloser<Vector3D> encloser =
                 new WelzlEncloser<>(1.0e-10, new SphereGenerator());
-        EnclosingBall<Point3D> ball = encloser.enclose(list);
+        EnclosingBall<Vector3D> ball = encloser.enclose(list);
         Assert.assertTrue(ball.getRadius() > 0);
     }
 
@@ -109,13 +108,13 @@ public class WelzlEncloser3DTest {
             // define the reference sphere we want to compute
             double d = 25 * random.nextDouble();
             double refRadius = 10 * random.nextDouble();
-            Point3D refCenter = Point3D.vectorCombination(d, Point3D.ofArray(sr.nextVector()));
+            Vector3D refCenter = Vector3D.linearCombination(d, Vector3D.ofArray(sr.nextVector()));
             // set up a large sample inside the reference sphere
             int nbPoints = random.nextInt(1000);
-            List<Point3D> points = new ArrayList<>();
+            List<Vector3D> points = new ArrayList<>();
             for (int i = 0; i < nbPoints; ++i) {
                 double r = refRadius * random.nextDouble();
-                points.add(Point3D.vectorCombination(1.0, refCenter, r, Point3D.ofArray(sr.nextVector())));
+                points.add(Vector3D.linearCombination(1.0, refCenter, r, Vector3D.ofArray(sr.nextVector())));
             }
 
             // test we find a sphere at most as large as the one used for random drawings
@@ -124,23 +123,23 @@ public class WelzlEncloser3DTest {
         }
     }
 
-    private void checkSphere(List<Point3D> points, double refRadius) {
+    private void checkSphere(List<Vector3D> points, double refRadius) {
 
-        EnclosingBall<Point3D> sphere = checkSphere(points);
+        EnclosingBall<Vector3D> sphere = checkSphere(points);
 
         // compare computed sphere with bounding sphere
         Assert.assertTrue(sphere.getRadius() <= refRadius);
 
         // check removing any point of the support Sphere fails to enclose the point
         for (int i = 0; i < sphere.getSupportSize(); ++i) {
-            List<Point3D> reducedSupport = new ArrayList<>();
+            List<Vector3D> reducedSupport = new ArrayList<>();
             int count = 0;
-            for (Point3D s : sphere.getSupport()) {
+            for (Vector3D s : sphere.getSupport()) {
                 if (count++ != i) {
                     reducedSupport.add(s);
                 }
             }
-            EnclosingBall<Point3D> reducedSphere =
+            EnclosingBall<Vector3D> reducedSphere =
                     new SphereGenerator().ballOnSupport(reducedSupport);
             boolean foundOutside = false;
             for (int j = 0; j < points.size() && !foundOutside; ++j) {
@@ -153,20 +152,20 @@ public class WelzlEncloser3DTest {
 
     }
 
-    private EnclosingBall<Point3D> checkSphere(List<Point3D> points) {
+    private EnclosingBall<Vector3D> checkSphere(List<Vector3D> points) {
 
-        WelzlEncloser<Point3D> encloser =
+        WelzlEncloser<Vector3D> encloser =
                 new WelzlEncloser<>(1.0e-10, new SphereGenerator());
-        EnclosingBall<Point3D> Sphere = encloser.enclose(points);
+        EnclosingBall<Vector3D> Sphere = encloser.enclose(points);
 
         // all points are enclosed
-        for (Point3D v : points) {
+        for (Vector3D v : points) {
             Assert.assertTrue(Sphere.contains(v, 1.0e-10));
         }
 
-        for (Point3D v : points) {
+        for (Vector3D v : points) {
             boolean inSupport = false;
-            for (Point3D s : Sphere.getSupport()) {
+            for (Vector3D s : Sphere.getSupport()) {
                 if (v == s) {
                     inSupport = true;
                 }
diff --git a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGeneratorTest.java b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGeneratorTest.java
index 8ab75e4..cc29ec7 100644
--- a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGeneratorTest.java
+++ b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/threed/enclosing/SphereGeneratorTest.java
@@ -21,7 +21,7 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.commons.geometry.enclosing.EnclosingBall;
-import org.apache.commons.geometry.euclidean.threed.Point3D;
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.sampling.UnitSphereSampler;
 import org.apache.commons.rng.simple.RandomSource;
@@ -32,8 +32,8 @@ public class SphereGeneratorTest {
 
     @Test
     public void testSupport0Point() {
-        List<Point3D> support = Arrays.asList(new Point3D[0]);
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        List<Vector3D> support = Arrays.asList(new Vector3D[0]);
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
         Assert.assertTrue(sphere.getRadius() < 0);
         Assert.assertEquals(0, sphere.getSupportSize());
         Assert.assertEquals(0, sphere.getSupport().length);
@@ -41,16 +41,16 @@ public class SphereGeneratorTest {
 
     @Test
     public void testSupport1Point() {
-        List<Point3D> support = Arrays.asList(Point3D.of(1, 2, 3));
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        List<Vector3D> support = Arrays.asList(Vector3D.of(1, 2, 3));
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
         Assert.assertEquals(0.0, sphere.getRadius(), 1.0e-10);
         Assert.assertTrue(sphere.contains(support.get(0)));
         Assert.assertTrue(sphere.contains(support.get(0), 0.5));
-        Assert.assertFalse(sphere.contains(Point3D.of(support.get(0).getX() + 0.1,
+        Assert.assertFalse(sphere.contains(Vector3D.of(support.get(0).getX() + 0.1,
                                                         support.get(0).getY() + 0.1,
                                                         support.get(0).getZ() + 0.1),
                                            0.001));
-        Assert.assertTrue(sphere.contains(Point3D.of(support.get(0).getX() + 0.1,
+        Assert.assertTrue(sphere.contains(Vector3D.of(support.get(0).getX() + 0.1,
                                                        support.get(0).getY() + 0.1,
                                                        support.get(0).getZ() + 0.1),
                                           0.5));
@@ -61,73 +61,73 @@ public class SphereGeneratorTest {
 
     @Test
     public void testSupport2Points() {
-        List<Point3D> support = Arrays.asList(Point3D.of(1, 0, 0),
-                                               Point3D.of(3, 0, 0));
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        List<Vector3D> support = Arrays.asList(Vector3D.of(1, 0, 0),
+                                               Vector3D.of(3, 0, 0));
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
         Assert.assertEquals(1.0, sphere.getRadius(), 1.0e-10);
         int i = 0;
-        for (Point3D v : support) {
+        for (Vector3D v : support) {
             Assert.assertTrue(sphere.contains(v));
             Assert.assertEquals(1.0, v.distance(sphere.getCenter()), 1.0e-10);
             Assert.assertTrue(v == sphere.getSupport()[i++]);
         }
-        Assert.assertTrue(sphere.contains(Point3D.of(2, 0.9, 0)));
-        Assert.assertFalse(sphere.contains(Point3D.ZERO));
-        Assert.assertEquals(0.0, Point3D.of(2, 0, 0).distance(sphere.getCenter()), 1.0e-10);
+        Assert.assertTrue(sphere.contains(Vector3D.of(2, 0.9, 0)));
+        Assert.assertFalse(sphere.contains(Vector3D.ZERO));
+        Assert.assertEquals(0.0, Vector3D.of(2, 0, 0).distance(sphere.getCenter()), 1.0e-10);
         Assert.assertEquals(2, sphere.getSupportSize());
     }
 
     @Test
     public void testSupport3Points() {
-        List<Point3D> support = Arrays.asList(Point3D.of(1, 0, 0),
-                                               Point3D.of(3, 0, 0),
-                                               Point3D.of(2, 2, 0));
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        List<Vector3D> support = Arrays.asList(Vector3D.of(1, 0, 0),
+                                               Vector3D.of(3, 0, 0),
+                                               Vector3D.of(2, 2, 0));
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
         Assert.assertEquals(5.0 / 4.0, sphere.getRadius(), 1.0e-10);
         int i = 0;
-        for (Point3D v : support) {
+        for (Vector3D v : support) {
             Assert.assertTrue(sphere.contains(v));
             Assert.assertEquals(5.0 / 4.0, v.distance(sphere.getCenter()), 1.0e-10);
             Assert.assertTrue(v == sphere.getSupport()[i++]);
         }
-        Assert.assertTrue(sphere.contains(Point3D.of(2, 0.9, 0)));
-        Assert.assertFalse(sphere.contains(Point3D.of(0.9,  0, 0)));
-        Assert.assertFalse(sphere.contains(Point3D.of(3.1,  0, 0)));
-        Assert.assertTrue(sphere.contains(Point3D.of(2.0, -0.499, 0)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2.0, -0.501, 0)));
-        Assert.assertTrue(sphere.contains(Point3D.of(2.0, 3.0 / 4.0, -1.249)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2.0, 3.0 / 4.0, -1.251)));
-        Assert.assertEquals(0.0, Point3D.of(2.0, 3.0 / 4.0, 0).distance(sphere.getCenter()), 1.0e-10);
+        Assert.assertTrue(sphere.contains(Vector3D.of(2, 0.9, 0)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(0.9,  0, 0)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(3.1,  0, 0)));
+        Assert.assertTrue(sphere.contains(Vector3D.of(2.0, -0.499, 0)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2.0, -0.501, 0)));
+        Assert.assertTrue(sphere.contains(Vector3D.of(2.0, 3.0 / 4.0, -1.249)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2.0, 3.0 / 4.0, -1.251)));
+        Assert.assertEquals(0.0, Vector3D.of(2.0, 3.0 / 4.0, 0).distance(sphere.getCenter()), 1.0e-10);
         Assert.assertEquals(3, sphere.getSupportSize());
     }
 
     @Test
     public void testSupport4Points() {
-        List<Point3D> support = Arrays.asList(Point3D.of(17, 14,  18),
-                                               Point3D.of(11, 14,  22),
-                                               Point3D.of( 2, 22,  17),
-                                               Point3D.of(22, 11, -10));
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        List<Vector3D> support = Arrays.asList(Vector3D.of(17, 14,  18),
+                                               Vector3D.of(11, 14,  22),
+                                               Vector3D.of( 2, 22,  17),
+                                               Vector3D.of(22, 11, -10));
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
         Assert.assertEquals(25.0, sphere.getRadius(), 1.0e-10);
         int i = 0;
-        for (Point3D v : support) {
+        for (Vector3D v : support) {
             Assert.assertTrue(sphere.contains(v));
             Assert.assertEquals(25.0, v.distance(sphere.getCenter()), 1.0e-10);
             Assert.assertTrue(v == sphere.getSupport()[i++]);
         }
-        Assert.assertTrue(sphere.contains (Point3D.of(-22.999, 2, 2)));
-        Assert.assertFalse(sphere.contains(Point3D.of(-23.001, 2, 2)));
-        Assert.assertTrue(sphere.contains (Point3D.of( 26.999, 2, 2)));
-        Assert.assertFalse(sphere.contains(Point3D.of( 27.001, 2, 2)));
-        Assert.assertTrue(sphere.contains (Point3D.of(2, -22.999, 2)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2, -23.001, 2)));
-        Assert.assertTrue(sphere.contains (Point3D.of(2,  26.999, 2)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2,  27.001, 2)));
-        Assert.assertTrue(sphere.contains (Point3D.of(2, 2, -22.999)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2, 2, -23.001)));
-        Assert.assertTrue(sphere.contains (Point3D.of(2, 2,  26.999)));
-        Assert.assertFalse(sphere.contains(Point3D.of(2, 2,  27.001)));
-        Assert.assertEquals(0.0, Point3D.of(2.0, 2.0, 2.0).distance(sphere.getCenter()), 1.0e-10);
+        Assert.assertTrue(sphere.contains (Vector3D.of(-22.999, 2, 2)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(-23.001, 2, 2)));
+        Assert.assertTrue(sphere.contains (Vector3D.of( 26.999, 2, 2)));
+        Assert.assertFalse(sphere.contains(Vector3D.of( 27.001, 2, 2)));
+        Assert.assertTrue(sphere.contains (Vector3D.of(2, -22.999, 2)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2, -23.001, 2)));
+        Assert.assertTrue(sphere.contains (Vector3D.of(2,  26.999, 2)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2,  27.001, 2)));
+        Assert.assertTrue(sphere.contains (Vector3D.of(2, 2, -22.999)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2, 2, -23.001)));
+        Assert.assertTrue(sphere.contains (Vector3D.of(2, 2,  26.999)));
+        Assert.assertFalse(sphere.contains(Vector3D.of(2, 2,  27.001)));
+        Assert.assertEquals(0.0, Vector3D.of(2.0, 2.0, 2.0).distance(sphere.getCenter()), 1.0e-10);
         Assert.assertEquals(4, sphere.getSupportSize());
     }
 
@@ -139,12 +139,12 @@ public class SphereGeneratorTest {
         for (int i = 0; i < 100; ++i) {
             double d = 25 * random.nextDouble();
             double refRadius = 10 * random.nextDouble();
-            Point3D refCenter = Point3D.vectorCombination(d, Point3D.ofArray(sr.nextVector()));
-            List<Point3D> support = new ArrayList<>();
+            Vector3D refCenter = Vector3D.linearCombination(d, Vector3D.ofArray(sr.nextVector()));
+            List<Vector3D> support = new ArrayList<>();
             for (int j = 0; j < 5; ++j) {
-                support.add(Point3D.vectorCombination(1.0, refCenter, refRadius, Point3D.ofArray(sr.nextVector())));
+                support.add(Vector3D.linearCombination(1.0, refCenter, refRadius, Vector3D.ofArray(sr.nextVector())));
             }
-            EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+            EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
             Assert.assertEquals(0.0, refCenter.distance(sphere.getCenter()), 4e-7 * refRadius);
             Assert.assertEquals(refRadius, sphere.getRadius(), 1e-7 * refRadius);
         }
@@ -152,20 +152,20 @@ public class SphereGeneratorTest {
 
     @Test
     public void testDegeneratedCase() {
-       final List<Point3D> support =
-               Arrays.asList(Point3D.of(Math.scalb(-8039905610797991.0, -50),   //   -7.140870659936730
+       final List<Vector3D> support =
+               Arrays.asList(Vector3D.of(Math.scalb(-8039905610797991.0, -50),   //   -7.140870659936730
                                           Math.scalb(-4663475464714142.0, -48),   //  -16.567993074240455
                                           Math.scalb( 6592658872616184.0, -49)),  //   11.710914678204503
-                             Point3D.of(Math.scalb(-8036658568968473.0, -50),   //   -7.137986707455888
+                             Vector3D.of(Math.scalb(-8036658568968473.0, -50),   //   -7.137986707455888
                                           Math.scalb(-4664256346424880.0, -48),   //  -16.570767323375720
                                           Math.scalb( 6591357011730307.0, -49)),  //  11.708602108715928)
-                             Point3D.of(Math.scalb(-8037820142977230.0, -50),   //   -7.139018392423351
+                             Vector3D.of(Math.scalb(-8037820142977230.0, -50),   //   -7.139018392423351
                                           Math.scalb(-4665280434237813.0, -48),   //  -16.574405614157020
                                           Math.scalb( 6592435966112099.0, -49)),  //   11.710518716711425
-                             Point3D.of(Math.scalb(-8038007803611611.0, -50),   //   -7.139185068549035
+                             Vector3D.of(Math.scalb(-8038007803611611.0, -50),   //   -7.139185068549035
                                           Math.scalb(-4664291215918380.0, -48),   //  -16.570891204702250
                                           Math.scalb( 6595270610894208.0, -49))); //   11.715554057357394
-        EnclosingBall<Point3D> sphere = new SphereGenerator().ballOnSupport(support);
+        EnclosingBall<Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
 
         // the following values have been computed using Emacs calc with exact arithmetic from the
         // rational representation corresponding to the scalb calls (i.e. -8039905610797991/2^50, ...)
@@ -176,7 +176,7 @@ public class SphereGeneratorTest {
         Assert.assertEquals(-16.571096474251747245361467833760, sphere.getCenter().getY(), 1.0e-20);
         Assert.assertEquals( 11.711945804096960876521111630800, sphere.getCenter().getZ(), 1.0e-20);
 
-        for (Point3D v : support) {
+        for (Vector3D v : support) {
             Assert.assertTrue(sphere.contains(v, 1.0e-14));
         }
 
diff --git a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGeneratorTest.java b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGeneratorTest.java
index e5972e5..966e0c9 100644
--- a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGeneratorTest.java
+++ b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/euclidean/twod/enclosing/DiskGeneratorTest.java
@@ -21,7 +21,7 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.commons.geometry.enclosing.EnclosingBall;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.sampling.UnitSphereSampler;
 import org.apache.commons.rng.simple.RandomSource;
@@ -33,8 +33,8 @@ public class DiskGeneratorTest {
 
     @Test
     public void testSupport0Point() {
-        List<Point2D> support = Arrays.asList(new Point2D[0]);
-        EnclosingBall<Point2D> disk = new DiskGenerator().ballOnSupport(support);
+        List<Vector2D> support = Arrays.asList(new Vector2D[0]);
+        EnclosingBall<Vector2D> disk = new DiskGenerator().ballOnSupport(support);
         Assert.assertTrue(disk.getRadius() < 0);
         Assert.assertEquals(0, disk.getSupportSize());
         Assert.assertEquals(0, disk.getSupport().length);
@@ -42,15 +42,15 @@ public class DiskGeneratorTest {
 
     @Test
     public void testSupport1Point() {
-        List<Point2D> support = Arrays.asList(Point2D.of(1, 2));
-        EnclosingBall<Point2D> disk = new DiskGenerator().ballOnSupport(support);
+        List<Vector2D> support = Arrays.asList(Vector2D.of(1, 2));
+        EnclosingBall<Vector2D> disk = new DiskGenerator().ballOnSupport(support);
         Assert.assertEquals(0.0, disk.getRadius(), 1.0e-10);
         Assert.assertTrue(disk.contains(support.get(0)));
         Assert.assertTrue(disk.contains(support.get(0), 0.5));
-        Assert.assertFalse(disk.contains(Point2D.of(support.get(0).getX() + 0.1,
+        Assert.assertFalse(disk.contains(Vector2D.of(support.get(0).getX() + 0.1,
                                                       support.get(0).getY() - 0.1),
                                          0.001));
-        Assert.assertTrue(disk.contains(Point2D.of(support.get(0).getX() + 0.1,
+        Assert.assertTrue(disk.contains(Vector2D.of(support.get(0).getX() + 0.1,
                                                      support.get(0).getY() - 0.1),
                                         0.5));
         Assert.assertEquals(0, support.get(0).distance(disk.getCenter()), 1.0e-10);
@@ -60,41 +60,41 @@ public class DiskGeneratorTest {
 
     @Test
     public void testSupport2Points() {
-        List<Point2D> support = Arrays.asList(Point2D.of(1, 0),
-                                               Point2D.of(3, 0));
-        EnclosingBall<Point2D> disk = new DiskGenerator().ballOnSupport(support);
+        List<Vector2D> support = Arrays.asList(Vector2D.of(1, 0),
+                                               Vector2D.of(3, 0));
+        EnclosingBall<Vector2D> disk = new DiskGenerator().ballOnSupport(support);
         Assert.assertEquals(1.0, disk.getRadius(), 1.0e-10);
         int i = 0;
-        for (Point2D v : support) {
+        for (Vector2D v : support) {
             Assert.assertTrue(disk.contains(v));
             Assert.assertEquals(1.0, v.distance(disk.getCenter()), 1.0e-10);
             Assert.assertTrue(v == disk.getSupport()[i++]);
         }
-        Assert.assertTrue(disk.contains(Point2D.of(2, 0.9)));
-        Assert.assertFalse(disk.contains(Point2D.ZERO));
-        Assert.assertEquals(0.0, Point2D.of(2, 0).distance(disk.getCenter()), 1.0e-10);
+        Assert.assertTrue(disk.contains(Vector2D.of(2, 0.9)));
+        Assert.assertFalse(disk.contains(Vector2D.ZERO));
+        Assert.assertEquals(0.0, Vector2D.of(2, 0).distance(disk.getCenter()), 1.0e-10);
         Assert.assertEquals(2, disk.getSupportSize());
     }
 
     @Test
     public void testSupport3Points() {
-        List<Point2D> support = Arrays.asList(Point2D.of(1, 0),
-                                               Point2D.of(3, 0),
-                                               Point2D.of(2, 2));
-        EnclosingBall<Point2D> disk = new DiskGenerator().ballOnSupport(support);
+        List<Vector2D> support = Arrays.asList(Vector2D.of(1, 0),
+                                               Vector2D.of(3, 0),
+                                               Vector2D.of(2, 2));
+        EnclosingBall<Vector2D> disk = new DiskGenerator().ballOnSupport(support);
         Assert.assertEquals(5.0 / 4.0, disk.getRadius(), 1.0e-10);
         int i = 0;
-        for (Point2D v : support) {
+        for (Vector2D v : support) {
             Assert.assertTrue(disk.contains(v));
             Assert.assertEquals(5.0 / 4.0, v.distance(disk.getCenter()), 1.0e-10);
             Assert.assertTrue(v == disk.getSupport()[i++]);
         }
-        Assert.assertTrue(disk.contains(Point2D.of(2, 0.9)));
-        Assert.assertFalse(disk.contains(Point2D.of(0.9,  0)));
-        Assert.assertFalse(disk.contains(Point2D.of(3.1,  0)));
-        Assert.assertTrue(disk.contains(Point2D.of(2.0, -0.499)));
-        Assert.assertFalse(disk.contains(Point2D.of(2.0, -0.501)));
-        Assert.assertEquals(0.0, Point2D.of(2.0, 3.0 / 4.0).distance(disk.getCenter()), 1.0e-10);
+        Assert.assertTrue(disk.contains(Vector2D.of(2, 0.9)));
+        Assert.assertFalse(disk.contains(Vector2D.of(0.9,  0)));
+        Assert.assertFalse(disk.contains(Vector2D.of(3.1,  0)));
+        Assert.assertTrue(disk.contains(Vector2D.of(2.0, -0.499)));
+        Assert.assertFalse(disk.contains(Vector2D.of(2.0, -0.501)));
+        Assert.assertEquals(0.0, Vector2D.of(2.0, 3.0 / 4.0).distance(disk.getCenter()), 1.0e-10);
         Assert.assertEquals(3, disk.getSupportSize());
     }
 
@@ -106,12 +106,12 @@ public class DiskGeneratorTest {
         for (int i = 0; i < 500; ++i) {
             double d = 25 * random.nextDouble();
             double refRadius = 10 * random.nextDouble();
-            Point2D refCenter = Point2D.vectorCombination(d, Point2D.ofArray(sr.nextVector()));
-            List<Point2D> support = new ArrayList<>();
+            Vector2D refCenter = Vector2D.linearCombination(d, Vector2D.ofArray(sr.nextVector()));
+            List<Vector2D> support = new ArrayList<>();
             for (int j = 0; j < 3; ++j) {
-                support.add(Point2D.vectorCombination(1.0, refCenter, refRadius, Point2D.ofArray(sr.nextVector())));
+                support.add(Vector2D.linearCombination(1.0, refCenter, refRadius, Vector2D.ofArray(sr.nextVector())));
             }
-            EnclosingBall<Point2D> disk = new DiskGenerator().ballOnSupport(support);
+            EnclosingBall<Vector2D> disk = new DiskGenerator().ballOnSupport(support);
             Assert.assertEquals(0.0, refCenter.distance(disk.getCenter()), 3e-9 * refRadius);
             Assert.assertEquals(refRadius, disk.getRadius(), 7e-10 * refRadius);
         }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanPoint.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanPoint.java
deleted file mode 100644
index f3c332c..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanPoint.java
+++ /dev/null
@@ -1,67 +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.geometry.euclidean;
-
-import org.apache.commons.geometry.core.AffinePoint;
-import org.apache.commons.geometry.core.exception.IllegalNormException;
-
-/** Represents a point in a Euclidean space of any dimension.
- *
- * @param <P> Point implementation type
- * @param <V> Vector implementation type
- */
-public interface EuclideanPoint<P extends EuclideanPoint<P, V>, V extends EuclideanVector<P, V>> extends AffinePoint<P, V> {
-
-    /** Get a vector with the same coordinates as this point.
-     * This is equivalent to the expression {@code v = P - Z} where
-     * {@code P} is this point, {@code Z} is the zero point. and
-     * {@code v} is the returned vector.
-     * @return vector with same coordinate values as this point
-     */
-    V asVector();
-
-    /** Returns the vector representing the displacement from this point
-     * to the given point. This is exactly equivalent to {@code p.subtract(thisPoint)}
-     * but with a method name that is much easier to visualize.
-     * @param p the point the returned vector will be directed toward
-     * @return vector representing the displacement <em>from</em> this point <em>to</em> the given point
-     */
-    V vectorTo(P p);
-
-    /** Returns the unit vector representing the direction of displacement from this
-     * point to the given point. This is exactly equivalent to {@code p.subtract(thisPoint).normalize()}
-     * but without the intermediate vector instance.
-     * @param p the point the returned vector will be directed toward
-     * @return unit vector representing the direction of displacement <em>from</em> this point
-     *      <em>to</em> the given point
-     * @throws IllegalNormException if the norm of the vector pointing from this point to {@code p}
-     *      is zero, NaN, or infinite
-     */
-    V directionTo(P p);
-
-    /** Linearly interpolates between this point and the given point using the equation
-     * {@code P = (1 - t)*A + t*B}, where {@code A} is the current point and {@code B}
-     * is the given point. This means that if {@code t = 0}, a point equal to the current
-     * point will be returned. If {@code t = 1}, a point equal to the argument will be returned.
-     * The {@code t} parameter is not constrained to the range {@code [0, 1]}, meaning that
-     * linear extrapolation can also be performed with this method.
-     * @param p other point
-     * @param t interpolation parameter
-     * @return interpolated or extrapolated point
-     */
-    P lerp(P p, double t);
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanVector.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanVector.java
index 595d5e3..00edec6 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanVector.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/EuclideanVector.java
@@ -16,22 +16,44 @@
  */
 package org.apache.commons.geometry.euclidean;
 
+import java.io.Serializable;
+
+import org.apache.commons.geometry.core.Point;
 import org.apache.commons.geometry.core.Vector;
+import org.apache.commons.geometry.core.exception.IllegalNormException;
+import org.apache.commons.geometry.euclidean.internal.Vectors;
 
-/** Vector extension interface for working in Euclidean space.
+/** Abstract base class for Euclidean vectors <em>and</em> points. See
+ * {@link org.apache.commons.geometry.euclidean here} for a discussion
+ * of the combination of point and vector functionality into a single
+ * class hierarchy.
  *
- * @param <P> Point implementation type
  * @param <V> Vector implementation type
  */
-public interface EuclideanVector<P extends EuclideanPoint<P, V>, V extends EuclideanVector<P, V>> extends Vector<V> {
+public abstract class EuclideanVector<V extends EuclideanVector<V>>
+    implements Vector<V>, Point<V>, Serializable {
+
+    /** Serializable version identifer */
+    private static final long serialVersionUID = 20181017L;
+
+    /** Return the vector representing the displacement from this vector
+     * to the given vector. This is exactly equivalent to {@code v.subtract(thisVector)}
+     * but with a method name that is much easier to visualize.
+     * @param v the vector that the returned vector will be directed toward
+     * @return vector representing the displacement <em>from</em> this vector <em>to</em> the given vector
+     */
+    public abstract V vectorTo(V v);
 
-    /** Get a point with the same coordinates as this vector.
-     * This is equivalent to the expression {@code P = Z + v}, where
-     * {@code v} is this vector, {@code Z} is the zero point, and
-     * {@code P} is the returned point.
-     * @return point with the same coordinates as this vector
+    /** Return the unit vector representing the direction of displacement from this
+     * vector to the given vector. This is exactly equivalent to {@code v.subtract(thisVector).normalize()}
+     * but without the intermediate vector instance.
+     * @param v the vector that the returned vector will be directed toward
+     * @return unit vector representing the direction of displacement <em>from</em> this vector
+     *      <em>to</em> the given vector
+     * @throws IllegalNormException if the norm of the vector pointing from this instance to {@code v}
+     *      is zero, NaN, or infinite
      */
-    P asPoint();
+    public abstract V directionTo(V v);
 
     /** Get a vector constructed by linearly interpolating between this vector and the given vector.
      * The vector coordinates are generated by the equation {@code V = (1 - t)*A + t*B}, where {@code A}
@@ -43,5 +65,14 @@ public interface EuclideanVector<P extends EuclideanPoint<P, V>, V extends Eucli
      * @param t interpolation parameter
      * @return interpolated or extrapolated vector
      */
-    V lerp(V v, double t);
+    public abstract V lerp(V v, double t);
+
+    /** Return the vector norm value, throwing an {@link IllegalNormException} if the value
+     * is not real (ie, NaN or infinite) or zero.
+     * @return the vector norm value, guaranteed to be real and non-zero
+     * @throws IllegalNormException if the vector norm is zero, NaN, or infinite
+     */
+    protected double getCheckedNorm() {
+        return Vectors.checkedNorm(this);
+    }
 }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/MultiDimensionalEuclideanVector.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/MultiDimensionalEuclideanVector.java
index 6553a53..05f6c2e 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/MultiDimensionalEuclideanVector.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/MultiDimensionalEuclideanVector.java
@@ -19,14 +19,15 @@ package org.apache.commons.geometry.euclidean;
 import org.apache.commons.geometry.core.exception.IllegalNormException;
 
 /**
- * Euclidean vector extension interface with methods applicable to spaces of
- * two or more dimensions.
+ * Abstract base class for Euclidean vectors with two or more dimensions.
  *
- * @param <P> Point implementation type
  * @param <V> Vector implementation type
  */
-public interface MultiDimensionalEuclideanVector<P extends EuclideanPoint<P, V>, V extends MultiDimensionalEuclideanVector<P, V>>
-        extends EuclideanVector<P, V> {
+public abstract class MultiDimensionalEuclideanVector<V extends MultiDimensionalEuclideanVector<V>>
+        extends EuclideanVector<V> {
+
+    /** Serializable version identifer */
+    private static final long serialVersionUID = 20181017L;
 
     /** Get the projection of the instance onto the given base vector. The returned
      * vector is parallel to {@code base}. Vector projection and rejection onto
@@ -39,7 +40,7 @@ public interface MultiDimensionalEuclideanVector<P extends EuclideanPoint<P, V>,
      * @exception IllegalNormException if the norm of the base vector is zero, NaN, or infinite
      * @see #reject(MultiDimensionalEuclideanVector)
      */
-    V project(V base);
+    public abstract V project(V base);
 
     /** Get the rejection of the instance from the given base vector. The returned
      * vector is orthogonal to {@code base}. This operation can be interpreted as
@@ -54,14 +55,14 @@ public interface MultiDimensionalEuclideanVector<P extends EuclideanPoint<P, V>,
      * @exception IllegalNormException if the norm of the base vector is zero, NaN, or infinite
      * @see #project(MultiDimensionalEuclideanVector)
      */
-    V reject(V base);
+    public abstract V reject(V base);
 
     /** Get a unit vector orthogonal to the instance.
      * @return a unit vector orthogonal to the current instance
      * @throws IllegalNormException if the norm of the current instance is zero, NaN,
      *  or infinite
      */
-    V orthogonal();
+    public abstract V orthogonal();
 
     /** Get a unit vector orthogonal to the current vector and pointing in the direction
      * of {@code dir}. This method is equivalent to calling {@code dir.reject(vec).normalize()}
@@ -72,5 +73,5 @@ public interface MultiDimensionalEuclideanVector<P extends EuclideanPoint<P, V>,
      * @throws IllegalNormException if either vector norm is zero, NaN or infinite,
      *      or the given vector is collinear with this vector.
      */
-    V orthogonal(V dir);
+    public abstract V orthogonal(V dir);
 }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Cartesian1D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Cartesian1D.java
deleted file mode 100644
index 047a0ff..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Cartesian1D.java
+++ /dev/null
@@ -1,74 +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.geometry.euclidean.oned;
-
-import java.io.Serializable;
-
-import org.apache.commons.geometry.core.Spatial;
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-
-/** This class represents a Cartesian coordinate value in
- * one-dimensional Euclidean space.
- */
-public abstract class Cartesian1D implements Spatial, Serializable {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Abscissa (coordinate value). */
-    private final double x;
-
-    /**
-     * Simple constructor.
-     * @param x abscissa (coordinate value)
-     */
-    protected Cartesian1D(double x) {
-        this.x = x;
-    }
-
-    /**
-     * Returns the abscissa (coordinate value) of the instance.
-     * @return the abscissa value
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isNaN() {
-        return Double.isNaN(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isInfinite() {
-        return !isNaN() && Double.isInfinite(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return SimpleTupleFormat.getDefault().format(getX());
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/IntervalsSet.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/IntervalsSet.java
index 376b8fc..ae6d8dc 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/IntervalsSet.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/IntervalsSet.java
@@ -29,7 +29,7 @@ import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 
 /** This class represents a 1D region: a set of intervals.
  */
-public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements Iterable<double[]> {
+public class IntervalsSet extends AbstractRegion<Vector1D, Vector1D> implements Iterable<double[]> {
 
     /** Build an intervals set representing the whole real line.
      * @param tolerance tolerance below which points are considered identical.
@@ -59,7 +59,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param tree inside/outside BSP tree representing the intervals set
      * @param tolerance tolerance below which points are considered identical.
      */
-    public IntervalsSet(final BSPTree<Point1D> tree, final double tolerance) {
+    public IntervalsSet(final BSPTree<Vector1D> tree, final double tolerance) {
         super(tree, tolerance);
     }
 
@@ -83,7 +83,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param boundary collection of boundary elements
      * @param tolerance tolerance below which points are considered identical.
      */
-    public IntervalsSet(final Collection<SubHyperplane<Point1D>> boundary,
+    public IntervalsSet(final Collection<SubHyperplane<Vector1D>> boundary,
                         final double tolerance) {
         super(boundary, tolerance);
     }
@@ -96,7 +96,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param tolerance tolerance below which points are considered identical.
      * @return the built tree
      */
-    private static BSPTree<Point1D> buildTree(final double lower, final double upper,
+    private static BSPTree<Vector1D> buildTree(final double lower, final double upper,
                                                   final double tolerance) {
         if (Double.isInfinite(lower) && (lower < 0)) {
             if (Double.isInfinite(upper) && (upper > 0)) {
@@ -104,31 +104,31 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
                 return new BSPTree<>(Boolean.TRUE);
             }
             // the tree must be open on the negative infinity side
-            final SubHyperplane<Point1D> upperCut =
-                new OrientedPoint(Point1D.of(upper), true, tolerance).wholeHyperplane();
+            final SubHyperplane<Vector1D> upperCut =
+                new OrientedPoint(Vector1D.of(upper), true, tolerance).wholeHyperplane();
             return new BSPTree<>(upperCut,
-                               new BSPTree<Point1D>(Boolean.FALSE),
-                               new BSPTree<Point1D>(Boolean.TRUE),
+                               new BSPTree<Vector1D>(Boolean.FALSE),
+                               new BSPTree<Vector1D>(Boolean.TRUE),
                                null);
         }
-        final SubHyperplane<Point1D> lowerCut =
-            new OrientedPoint(Point1D.of(lower), false, tolerance).wholeHyperplane();
+        final SubHyperplane<Vector1D> lowerCut =
+            new OrientedPoint(Vector1D.of(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<Point1D>(Boolean.FALSE),
-                                            new BSPTree<Point1D>(Boolean.TRUE),
+                                            new BSPTree<Vector1D>(Boolean.FALSE),
+                                            new BSPTree<Vector1D>(Boolean.TRUE),
                                             null);
         }
 
         // the tree must be bounded on the two sides
-        final SubHyperplane<Point1D> upperCut =
-            new OrientedPoint(Point1D.of(upper), true, tolerance).wholeHyperplane();
+        final SubHyperplane<Vector1D> upperCut =
+            new OrientedPoint(Vector1D.of(upper), true, tolerance).wholeHyperplane();
         return new BSPTree<>(lowerCut,
-                                        new BSPTree<Point1D>(Boolean.FALSE),
+                                        new BSPTree<Vector1D>(Boolean.FALSE),
                                         new BSPTree<>(upperCut,
-                                                                 new BSPTree<Point1D>(Boolean.FALSE),
-                                                                 new BSPTree<Point1D>(Boolean.TRUE),
+                                                                 new BSPTree<Vector1D>(Boolean.FALSE),
+                                                                 new BSPTree<Vector1D>(Boolean.TRUE),
                                                                  null),
                                         null);
 
@@ -136,7 +136,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
 
     /** {@inheritDoc} */
     @Override
-    public IntervalsSet buildNew(final BSPTree<Point1D> tree) {
+    public IntervalsSet buildNew(final BSPTree<Vector1D> tree) {
         return new IntervalsSet(tree, getTolerance());
     }
 
@@ -144,7 +144,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
     @Override
     protected void computeGeometricalProperties() {
         if (getTree(false).getCut() == null) {
-            setBarycenter(Point1D.NaN);
+            setBarycenter(Vector1D.NaN);
             setSize(((Boolean) getTree(false).getAttribute()) ? Double.POSITIVE_INFINITY : 0);
         } else {
             double size = 0.0;
@@ -155,9 +155,9 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
             }
             setSize(size);
             if (Double.isInfinite(size)) {
-                setBarycenter(Point1D.NaN);
+                setBarycenter(Vector1D.NaN);
             } else if (size > 0) {
-                setBarycenter(Point1D.of(sum / size));
+                setBarycenter(Vector1D.of(sum / size));
             } else {
                 setBarycenter(((OrientedPoint) getTree(false).getCut().getHyperplane()).getLocation());
             }
@@ -171,7 +171,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * instance is empty)
      */
     public double getInf() {
-        BSPTree<Point1D> node = getTree(false);
+        BSPTree<Vector1D> node = getTree(false);
         double  inf  = Double.POSITIVE_INFINITY;
         while (node.getCut() != null) {
             final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane();
@@ -188,7 +188,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * instance is empty)
      */
     public double getSup() {
-        BSPTree<Point1D> node = getTree(false);
+        BSPTree<Vector1D> node = getTree(false);
         double  sup  = Double.NEGATIVE_INFINITY;
         while (node.getCut() != null) {
             final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane();
@@ -201,7 +201,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
     /** {@inheritDoc}
      */
     @Override
-    public BoundaryProjection<Point1D> projectToBoundary(final Point1D point) {
+    public BoundaryProjection<Vector1D> projectToBoundary(final Vector1D point) {
 
         // get position of test point
         final double x = point.getX();
@@ -241,8 +241,8 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param x abscissa of the point
      * @return a new point for finite abscissa, null otherwise
      */
-    private Point1D finiteOrNullPoint(final double x) {
-        return Double.isInfinite(x) ? null : Point1D.of(x);
+    private Vector1D finiteOrNullPoint(final double x) {
+        return Double.isInfinite(x) ? null : Vector1D.of(x);
     }
 
     /** Build an ordered list of intervals representing the instance.
@@ -270,15 +270,15 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param root tree root
      * @return first leaf node
      */
-    private BSPTree<Point1D> getFirstLeaf(final BSPTree<Point1D> root) {
+    private BSPTree<Vector1D> getFirstLeaf(final BSPTree<Vector1D> root) {
 
         if (root.getCut() == null) {
             return root;
         }
 
         // find the smallest internal node
-        BSPTree<Point1D> smallest = null;
-        for (BSPTree<Point1D> n = root; n != null; n = previousInternalNode(n)) {
+        BSPTree<Vector1D> smallest = null;
+        for (BSPTree<Vector1D> n = root; n != null; n = previousInternalNode(n)) {
             smallest = n;
         }
 
@@ -290,10 +290,10 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @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<Point1D> getFirstIntervalBoundary() {
+    private BSPTree<Vector1D> getFirstIntervalBoundary() {
 
         // start search at the tree root
-        BSPTree<Point1D> node = getTree(false);
+        BSPTree<Vector1D> node = getTree(false);
         if (node.getCut() == null) {
             return null;
         }
@@ -314,7 +314,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node to check
      * @return true if the node corresponds to the start abscissa of an interval
      */
-    private boolean isIntervalStart(final BSPTree<Point1D> node) {
+    private boolean isIntervalStart(final BSPTree<Vector1D> node) {
 
         if ((Boolean) leafBefore(node).getAttribute()) {
             // it has an inside cell before it, it may end an interval but not start it
@@ -336,7 +336,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node to check
      * @return true if the node corresponds to the end abscissa of an interval
      */
-    private boolean isIntervalEnd(final BSPTree<Point1D> node) {
+    private boolean isIntervalEnd(final BSPTree<Vector1D> node) {
 
         if (!(Boolean) leafBefore(node).getAttribute()) {
             // it has an outside cell before it, it may start an interval but not end it
@@ -359,7 +359,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @return next internal node in ascending order, or null
      * if this is the last internal node
      */
-    private BSPTree<Point1D> nextInternalNode(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> nextInternalNode(BSPTree<Vector1D> node) {
 
         if (childAfter(node).getCut() != null) {
             // the next node is in the sub-tree
@@ -379,7 +379,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @return previous internal node in ascending order, or null
      * if this is the first internal node
      */
-    private BSPTree<Point1D> previousInternalNode(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> previousInternalNode(BSPTree<Vector1D> node) {
 
         if (childBefore(node).getCut() != null) {
             // the next node is in the sub-tree
@@ -398,7 +398,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node at which the sub-tree starts
      * @return leaf node just before the internal node
      */
-    private BSPTree<Point1D> leafBefore(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> leafBefore(BSPTree<Vector1D> node) {
 
         node = childBefore(node);
         while (node.getCut() != null) {
@@ -413,7 +413,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node at which the sub-tree starts
      * @return leaf node just after the internal node
      */
-    private BSPTree<Point1D> leafAfter(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> leafAfter(BSPTree<Vector1D> node) {
 
         node = childAfter(node);
         while (node.getCut() != null) {
@@ -428,8 +428,8 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @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<Point1D> node) {
-        final BSPTree<Point1D> parent = node.getParent();
+    private boolean isBeforeParent(final BSPTree<Vector1D> node) {
+        final BSPTree<Vector1D> parent = node.getParent();
         if (parent == null) {
             return false;
         } else {
@@ -441,8 +441,8 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @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<Point1D> node) {
-        final BSPTree<Point1D> parent = node.getParent();
+    private boolean isAfterParent(final BSPTree<Vector1D> node) {
+        final BSPTree<Vector1D> parent = node.getParent();
         if (parent == null) {
             return false;
         } else {
@@ -454,7 +454,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node at which the sub-tree starts
      * @return child node just before the internal node
      */
-    private BSPTree<Point1D> childBefore(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> childBefore(BSPTree<Vector1D> node) {
         if (isDirect(node)) {
             // smaller abscissas are on minus side, larger abscissas are on plus side
             return node.getMinus();
@@ -468,7 +468,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node at which the sub-tree starts
      * @return child node just after the internal node
      */
-    private BSPTree<Point1D> childAfter(BSPTree<Point1D> node) {
+    private BSPTree<Vector1D> childAfter(BSPTree<Vector1D> node) {
         if (isDirect(node)) {
             // smaller abscissas are on minus side, larger abscissas are on plus side
             return node.getPlus();
@@ -482,7 +482,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node to check
      * @return true if the oriented point is direct
      */
-    private boolean isDirect(final BSPTree<Point1D> node) {
+    private boolean isDirect(final BSPTree<Vector1D> node) {
         return ((OrientedPoint) node.getCut().getHyperplane()).isDirect();
     }
 
@@ -490,7 +490,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
      * @param node internal node to check
      * @return abscissa
      */
-    private double getAngle(final BSPTree<Point1D> node) {
+    private double getAngle(final BSPTree<Vector1D> node) {
         return ((OrientedPoint) node.getCut().getHyperplane()).getLocation().getX();
     }
 
@@ -511,7 +511,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
     private class SubIntervalsIterator implements Iterator<double[]> {
 
         /** Current node. */
-        private BSPTree<Point1D> current;
+        private BSPTree<Vector1D> current;
 
         /** Sub-interval no yet returned. */
         private double[] pending;
@@ -548,7 +548,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
         private void selectPending() {
 
             // look for the start of the interval
-            BSPTree<Point1D> start = current;
+            BSPTree<Vector1D> start = current;
             while (start != null && !isIntervalStart(start)) {
                 start = nextInternalNode(start);
             }
@@ -561,7 +561,7 @@ public class IntervalsSet extends AbstractRegion<Point1D, Point1D> implements It
             }
 
             // look for the end of the interval
-            BSPTree<Point1D> end = start;
+            BSPTree<Vector1D> end = start;
             while (end != null && !isIntervalEnd(end)) {
                 end = nextInternalNode(end);
             }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/OrientedPoint.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/OrientedPoint.java
index e03edbb..79bcb53 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/OrientedPoint.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/OrientedPoint.java
@@ -23,10 +23,10 @@ import org.apache.commons.geometry.core.partitioning.Hyperplane;
  * boolean.</p>
  * <p>Instances of this class are guaranteed to be immutable.</p>
  */
-public class OrientedPoint implements Hyperplane<Point1D> {
+public class OrientedPoint implements Hyperplane<Vector1D> {
 
     /** Point location. */
-    private final Point1D location;
+    private final Vector1D location;
 
     /** Orientation. */
     private boolean direct;
@@ -40,7 +40,7 @@ public class OrientedPoint implements Hyperplane<Point1D> {
      * abscissas greater than {@code location}
      * @param tolerance tolerance below which points are considered to belong to the hyperplane
      */
-    public OrientedPoint(final Point1D location, final boolean direct, final double tolerance) {
+    public OrientedPoint(final Vector1D location, final boolean direct, final double tolerance) {
         this.location  = location;
         this.direct    = direct;
         this.tolerance = tolerance;
@@ -58,7 +58,7 @@ public class OrientedPoint implements Hyperplane<Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    public double getOffset(final Point1D point) {
+    public double getOffset(final Vector1D point) {
         final double delta = point.getX() - location.getX();
         return direct ? delta : -delta;
     }
@@ -90,13 +90,13 @@ public class OrientedPoint implements Hyperplane<Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    public boolean sameOrientationAs(final Hyperplane<Point1D> other) {
+    public boolean sameOrientationAs(final Hyperplane<Vector1D> other) {
         return !(direct ^ ((OrientedPoint) other).direct);
     }
 
     /** {@inheritDoc} */
     @Override
-    public Point1D project(Point1D point) {
+    public Vector1D project(Vector1D point) {
         return location;
     }
 
@@ -109,7 +109,7 @@ public class OrientedPoint implements Hyperplane<Point1D> {
     /** Get the hyperplane location on the real line.
      * @return the hyperplane location
      */
-    public Point1D getLocation() {
+    public Vector1D getLocation() {
         return location;
     }
 
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Point1D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Point1D.java
deleted file mode 100644
index 7e977b7..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Point1D.java
+++ /dev/null
@@ -1,278 +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.geometry.euclidean.oned;
-
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-import org.apache.commons.geometry.euclidean.EuclideanPoint;
-import org.apache.commons.numbers.arrays.LinearCombination;
-
-/** This class representing a point in one-dimensional Euclidean space.
- * Instances of this class are guaranteed to be immutable.
- */
-public final class Point1D extends Cartesian1D implements EuclideanPoint<Point1D, Vector1D> {
-
-    /** Origin (coordinates: 0). */
-    public static final Point1D ZERO = new Point1D(0.0);
-
-    /** Unit (coordinates: 1). */
-    public static final Point1D ONE  = new Point1D(1.0);
-
-    /** Negative unit (coordinates: 1). */
-    public static final Point1D MINUS_ONE  = new Point1D(-1.0);
-
-    // CHECKSTYLE: stop ConstantName
-    /** A vector with all coordinates set to NaN. */
-    public static final Point1D NaN = new Point1D(Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A point with all coordinates set to positive infinity. */
-    public static final Point1D POSITIVE_INFINITY =
-        new Point1D(Double.POSITIVE_INFINITY);
-
-    /** A point with all coordinates set to negative infinity. */
-    public static final Point1D NEGATIVE_INFINITY =
-        new Point1D(Double.NEGATIVE_INFINITY);
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Simple constructor.
-     * @param x abscissa (coordinate value)
-     */
-    private Point1D(double x) {
-        super(x);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D asVector() {
-        return Vector1D.of(getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point1D p) {
-        return Math.abs(p.getX() - getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D subtract(Point1D p) {
-        return Vector1D.of(getX() - p.getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D vectorTo(Point1D p) {
-        return p.subtract(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector1D directionTo(Point1D p) {
-        return Vector1D.normalize(p.getX() - getX());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point1D lerp(Point1D p, double t) {
-        return vectorCombination(1.0 - t, this, t, p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point1D add(Vector1D v) {
-        return new Point1D(getX() + v.getX());
-    }
-
-    /**
-     * Get a hashCode for this point.
-     * <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 * Double.hashCode(getX());
-    }
-
-    /**
-     * Test for the equality of two points.
-     * <p>
-     * If all coordinates of two points are exactly the same, and none are
-     * <code>Double.NaN</code>, the two points are considered to be equal.
-     * </p>
-     * <p>
-     * <code>NaN</code> coordinates are considered to globally affect the point
-     * and be equal to each other - i.e, if either (or all) coordinates of the
-     * point are equal to <code>Double.NaN</code>, the point is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if the two point objects are equal, false if
-     *         object is null, not an instance of Point1D, or
-     *         not equal to this Point1D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Point1D) {
-            final Point1D rhs = (Point1D) other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return getX() == rhs.getX();
-        }
-        return false;
-    }
-
-    /** Returns a point with the given coordinate value.
-     * @param x point coordinate
-     * @return point instance
-     */
-    public static Point1D of(double x) {
-        return new Point1D(x);
-    }
-
-    /** Parses the given string and returns a new point instance. The expected string
-     * format is the same as that returned by {@link #toString()}.
-     * @param str the string to parse
-     * @return point instance represented by the string
-     * @throws IllegalArgumentException if the given string has an invalid format
-     */
-    public static Point1D parse(String str) {
-        return SimpleTupleFormat.getDefault().parse(str, Point1D::new);
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a scale factor for first coordinate
-     * @param c first coordinate
-     * @return point with coordinates calculated by {@code a * c}
-     * @see Vector1D#linearCombination(double, Cartesian1D)
-     */
-    public static Point1D vectorCombination(double a, Cartesian1D c) {
-        return new Point1D(a * c.getX());
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
-     * @see Vector1D#linearCombination(double, Cartesian1D, double, Cartesian1D)
-     */
-    public static Point1D vectorCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2) {
-        return new Point1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
-     * @see Vector1D#linearCombination(double, Cartesian1D, double, Cartesian1D, double, Cartesian1D)
-     */
-    public static Point1D vectorCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2,
-            double a3, Cartesian1D c3) {
-        return new Point1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
-     * @see Vector1D#linearCombination(double, Cartesian1D, double, Cartesian1D, double, Cartesian1D, double, Cartesian1D)
-     */
-    public static Point1D vectorCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2,
-            double a3, Cartesian1D c3, double a4, Cartesian1D c4) {
-        return new Point1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()));
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPoint.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPoint.java
index de6881b..3945b28 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPoint.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPoint.java
@@ -25,14 +25,14 @@ import org.apache.commons.geometry.core.partitioning.Region;
  * boolean.</p>
  * <p>Instances of this class are guaranteed to be immutable.</p>
  */
-public class SubOrientedPoint extends AbstractSubHyperplane<Point1D, Point1D> {
+public class SubOrientedPoint extends AbstractSubHyperplane<Vector1D, Vector1D> {
 
     /** Simple constructor.
      * @param hyperplane underlying hyperplane
      * @param remainingRegion remaining region of the hyperplane
      */
-    public SubOrientedPoint(final Hyperplane<Point1D> hyperplane,
-                            final Region<Point1D> remainingRegion) {
+    public SubOrientedPoint(final Hyperplane<Vector1D> hyperplane,
+                            final Region<Vector1D> remainingRegion) {
         super(hyperplane, remainingRegion);
     }
 
@@ -50,14 +50,14 @@ public class SubOrientedPoint extends AbstractSubHyperplane<Point1D, Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    protected AbstractSubHyperplane<Point1D, Point1D> buildNew(final Hyperplane<Point1D> hyperplane,
-                                                                       final Region<Point1D> remainingRegion) {
+    protected AbstractSubHyperplane<Vector1D, Vector1D> buildNew(final Hyperplane<Vector1D> hyperplane,
+                                                                       final Region<Vector1D> remainingRegion) {
         return new SubOrientedPoint(hyperplane, remainingRegion);
     }
 
     /** {@inheritDoc} */
     @Override
-    public SplitSubHyperplane<Point1D> split(final Hyperplane<Point1D> hyperplane) {
+    public SplitSubHyperplane<Vector1D> split(final Hyperplane<Vector1D> hyperplane) {
         final OrientedPoint thisHyperplane = (OrientedPoint) getHyperplane();
         final double global = hyperplane.getOffset(thisHyperplane.getLocation());
 
@@ -65,11 +65,11 @@ public class SubOrientedPoint extends AbstractSubHyperplane<Point1D, Point1D> {
         final double tolerance = thisHyperplane.getTolerance();
 
         if (global < -tolerance) {
-            return new SplitSubHyperplane<Point1D>(null, this);
+            return new SplitSubHyperplane<Vector1D>(null, this);
         } else if (global > tolerance) {
-            return new SplitSubHyperplane<Point1D>(this, null);
+            return new SplitSubHyperplane<Vector1D>(this, null);
         } else {
-            return new SplitSubHyperplane<Point1D>(null, null);
+            return new SplitSubHyperplane<Vector1D>(null, null);
         }
     }
 
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
index 087ac82..58a0261 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
@@ -26,7 +26,7 @@ import org.apache.commons.numbers.arrays.LinearCombination;
 /** This class represents a vector in one-dimensional Euclidean space.
  * Instances of this class are guaranteed to be immutable.
  */
-public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Vector1D> {
+public class Vector1D extends EuclideanVector<Vector1D> {
 
     /** Zero vector (coordinates: 0). */
     public static final Vector1D ZERO = new Vector1D(0.0);
@@ -53,17 +53,52 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
     /** Serializable UID. */
     private static final long serialVersionUID = 20180710L;
 
+    /** Abscissa (coordinate value). */
+    private final double x;
+
     /** Simple constructor.
      * @param x abscissa (coordinate value)
      */
     private Vector1D(double x) {
-        super(x);
+        this.x = x;
+    }
+
+    /**
+     * Returns the abscissa (coordinate value) of the instance.
+     * @return the abscissa value
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getDimension() {
+        return 1;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isNaN() {
+        return Double.isNaN(x);
     }
 
     /** {@inheritDoc} */
     @Override
-    public Point1D asPoint() {
-        return Point1D.of(getX());
+    public boolean isInfinite() {
+        return !isNaN() && Double.isInfinite(x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Vector1D vectorTo(Vector1D v) {
+        return v.subtract(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Vector1D directionTo(Vector1D v) {
+        return normalize(v.x - x);
     }
 
     /** {@inheritDoc} */
@@ -81,81 +116,80 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
     /** {@inheritDoc} */
     @Override
     public double getNorm() {
-        return Vectors.norm(getX());
+        return Vectors.norm(x);
     }
 
     /** {@inheritDoc} */
     @Override
     public double getNormSq() {
-        return Vectors.normSq(getX());
+        return Vectors.normSq(x);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D withNorm(double magnitude) {
         getCheckedNorm(); // validate our norm value
-
-        return (getX() > 0.0)? new Vector1D(magnitude) : new Vector1D(-magnitude);
+        return (x > 0.0)? new Vector1D(magnitude) : new Vector1D(-magnitude);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D add(Vector1D v) {
-        return new Vector1D(getX() + v.getX());
+        return new Vector1D(x + v.x);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D add(double factor, Vector1D v) {
-        return new Vector1D(getX() + (factor * v.getX()));
+        return new Vector1D(x + (factor * v.x));
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D subtract(Vector1D v) {
-        return new Vector1D(getX() - v.getX());
+        return new Vector1D(x - v.x);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D subtract(double factor, Vector1D v) {
-        return new Vector1D(getX() - (factor * v.getX()));
+        return new Vector1D(x - (factor * v.x));
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D negate() {
-        return new Vector1D(-getX());
+        return new Vector1D(-x);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D normalize() {
-        return normalize(getX());
+        return normalize(x);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector1D scalarMultiply(double a) {
-        return new Vector1D(a * getX());
+        return new Vector1D(a * x);
     }
 
     /** {@inheritDoc} */
     @Override
     public double distance(Vector1D v) {
-        return Vectors.norm(getX() - v.getX());
+        return Vectors.norm(x - v.x);
     }
 
     /** {@inheritDoc} */
     @Override
     public double distanceSq(Vector1D v) {
-        return Vectors.normSq(getX() - v.getX());
+        return Vectors.normSq(x - v.x);
     }
 
     /** {@inheritDoc} */
     @Override
     public double dotProduct(Vector1D v) {
-        return getX() * v.getX();
+        return x * v.x;
     }
 
     /** {@inheritDoc}
@@ -168,8 +202,8 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
         getCheckedNorm();
         v.getCheckedNorm();
 
-        final double sig1 = Math.signum(getX());
-        final double sig2 = Math.signum(v.getX());
+        final double sig1 = Math.signum(x);
+        final double sig2 = Math.signum(v.x);
 
         // the angle is 0 if the x value signs are the same and pi if not
         return (sig1 == sig2) ? 0.0 : Geometry.PI;
@@ -186,7 +220,7 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
         if (isNaN()) {
             return 857;
         }
-        return 403 * Double.hashCode(getX());
+        return 403 * Double.hashCode(x);
     }
 
     /**
@@ -221,18 +255,15 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
                 return this.isNaN();
             }
 
-            return getX() == rhs.getX();
+            return x == rhs.x;
         }
         return false;
     }
 
-    /** Returns the vector norm value, throwing an {@link IllegalNormException} if the value
-     * is not real (ie, NaN or infinite) or zero.
-     * @return the vector norm value, guaranteed to be real and non-zero
-     * @throws IllegalNormException if the vector norm is zero, NaN, or infinite
-     */
-    private double getCheckedNorm() {
-        return Vectors.checkedNorm(getNorm());
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return SimpleTupleFormat.getDefault().format(x);
     }
 
     /** Returns a vector with the given coordinate value.
@@ -267,82 +298,74 @@ public class Vector1D extends Cartesian1D implements EuclideanVector<Point1D, Ve
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a scale factor for first coordinate
      * @param c first coordinate
      * @return vector with coordinates calculated by {@code a * c}
      */
-    public static Vector1D linearCombination(double a, Cartesian1D c) {
-        return new Vector1D(a * c.getX());
+    public static Vector1D linearCombination(double a, Vector1D c) {
+        return new Vector1D(a * c.x);
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
+     * @param v2 second coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2)}
      */
-    public static Vector1D linearCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2) {
+    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2) {
         return new Vector1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()));
+                LinearCombination.value(a1, v1.x, a2, v2.x));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
+     * @param v3 third coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3)}
      */
-    public static Vector1D linearCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2,
-            double a3, Cartesian1D c3) {
+    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
+            double a3, Vector1D v3) {
         return new Vector1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
+     * @param v3 third coordinate
      * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
+     * @param v4 fourth coordinate
+     * @return point with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3) + (a4 * v4)}
      */
-    public static Vector1D linearCombination(double a1, Cartesian1D c1, double a2, Cartesian1D c2,
-            double a3, Cartesian1D c3, double a4, Cartesian1D c4) {
+    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
+            double a3, Vector1D v3, double a4, Vector1D v4) {
         return new Vector1D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x, a4, v4.x));
     }
 
     /** Private class used to represent unit vectors. This allows optimizations to be performed for certain
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/package-info.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/package-info.java
index 2ed2a4c..334cea4 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/package-info.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/package-info.java
@@ -15,9 +15,48 @@
  * limitations under the License.
  */
 /**
+ * This package is the top-level package for Euclidean geometry components.
  *
+ * <h2>Definition</h2>
  * <p>
- * This package provides basic interfaces for Euclidean components.
+ * Euclidean space is the space commonly thought of when people think of
+ * geometry. It corresponds with the common notion of "flat" space or the space
+ * that we usually experience in the physical world. Mathematically, Euclidean
+ * space is an <a href="https://en.wikipedia.org/wiki/Affine_space">affine
+ * space</a>, meaning that it consists of points and displacement vectors
+ * representing translations between points. Distances between points are given
+ * by the formula <code>&radic;(A - B)<sup>2</sup></code>, which is also known
+ * as the <em>Euclidean norm</em>.
  * </p>
+ *
+ * <h2>Points and Vectors</h2>
+ * <p>
+ * As mentioned above, points and vectors are separate, distinct entities:
+ * points represent locations in a space and vectors represent displacements.
+ * This difference is the reason that commons-geometry has separate
+ * {@link org.apache.commons.geometry.core.Point Point} and
+ * {@link org.apache.commons.geometry.core.Vector Vector} interfaces. However,
+ * in the case of Euclidean space, the data structures used for points and
+ * vectors are identical and there is overlap in the methods needed for each
+ * type. Creating separate classes for Euclidean points and vectors therefore
+ * means a large amount of very similar or exactly duplicated code in order to
+ * maintain mathematical purity. This is not desirable, so a compromise position
+ * has been taken: there is a single class for each dimension that implements
+ * both {@link org.apache.commons.geometry.core.Point Point} <em>and</em>
+ * {@link org.apache.commons.geometry.core.Vector Vector}. These classes are
+ * named <code>Vector?D</code> to reflect the fact that they support the full
+ * range of vector operations. It is up to users of the library to make the
+ * correct distinctions between instances that represent points and those that
+ * represent displacements. This approach is commonly used in other geometric
+ * libraries as well, such as the
+ * <a href="https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language">OpenGL
+ * Shading Language (GLSL)</a>, <a href=
+ * "https://casual-effects.com/g3d/G3D10/G3D-base.lib/include/G3D-base/Vector3.h">G3D</a>,
+ * and <a href=
+ * "https://threejs.org/docs/index.html#api/en/math/Vector3">Three.js</a>.
+ * </p>
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Euclidean_space">Euclidean
+ *      Space</a>
  */
 package org.apache.commons.geometry.euclidean;
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java
deleted file mode 100644
index fe3b662..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Cartesian3D.java
+++ /dev/null
@@ -1,111 +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.geometry.euclidean.threed;
-
-import java.io.Serializable;
-
-import org.apache.commons.geometry.core.Spatial;
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-
-/** This class represents a Cartesian coordinate value in
- * three-dimensional Euclidean space.
- */
-public abstract class Cartesian3D implements Spatial, Serializable {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Abscissa (first coordinate value) */
-    private final double x;
-
-    /** Ordinate (second coordinate value) */
-    private final double y;
-
-    /** Height (third coordinate value)*/
-    private final double z;
-
-    /** Simple constructor.
-     * @param x abscissa (first coordinate value)
-     * @param y ordinate (second coordinate value)
-     * @param z height (third coordinate value)
-     */
-    protected Cartesian3D(double x, double y, double z) {
-        this.x = x;
-        this.y = y;
-        this.z = z;
-    }
-
-    /** Returns the abscissa (first coordinate) value of the instance.
-     * @return the abscisaa
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** Returns the ordinate (second coordinate) value of the instance.
-     * @return the ordinate
-     */
-    public double getY() {
-        return y;
-    }
-
-    /** Returns the height (third coordinate) value of the instance.
-     * @return the height
-     */
-    public double getZ() {
-        return z;
-    }
-
-    /** Get the coordinates for this instance as a dimension 3 array.
-     * @return the coordinates for this instance
-     */
-    public double[] toArray() {
-        return new double[] { x, y, z };
-    }
-
-    /** Return an equivalent set of coordinates in spherical form.
-     * @return an equivalent set of coordinates in spherical form.
-     */
-    public SphericalCoordinates toSpherical() {
-        return SphericalCoordinates.ofCartesian(x, y, z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 3;
-    }
-
-    /** {@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));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return SimpleTupleFormat.getDefault().format(getX(), getY(), getZ());
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Line.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Line.java
index 5df7374..87dba2b 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Line.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Line.java
@@ -18,7 +18,7 @@ package org.apache.commons.geometry.euclidean.threed;
 
 import org.apache.commons.geometry.core.partitioning.Embedding;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 import org.apache.commons.numbers.core.Precision;
 
 /** The class represent lines in a three dimensional space.
@@ -30,13 +30,13 @@ import org.apache.commons.numbers.core.Precision;
  * which is closest to the origin. Abscissa increases in the line
  * direction.</p>0
  */
-public class Line implements Embedding<Point3D, Point1D> {
+public class Line implements Embedding<Vector3D, Vector1D> {
 
     /** Line direction. */
     private Vector3D direction;
 
     /** Line point closest to the origin. */
-    private Point3D zero;
+    private Vector3D zero;
 
     /** Tolerance below which points are considered identical. */
     private final double tolerance;
@@ -47,7 +47,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if the points are equal
      */
-    public Line(final Point3D p1, final Point3D p2, final double tolerance)
+    public Line(final Vector3D p1, final Vector3D p2, final double tolerance)
         throws IllegalArgumentException {
         reset(p1, p2);
         this.tolerance = tolerance;
@@ -69,14 +69,14 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param p2 second point belonging to the line (this can be any point, different from p1)
      * @exception IllegalArgumentException if the points are equal
      */
-    public void reset(final Point3D p1, final Point3D p2) {
+    public void reset(final Vector3D p1, final Vector3D p2) {
         final Vector3D delta = p2.subtract(p1);
         final double norm2 = delta.getNormSq();
         if (norm2 == 0.0) {
             throw new IllegalArgumentException("Points are equal");
         }
         this.direction = Vector3D.linearCombination(1.0 / Math.sqrt(norm2), delta);
-        this.zero = Point3D.vectorCombination(1.0, p1, -p1.asVector().dotProduct(delta) / norm2, delta);
+        this.zero = Vector3D.linearCombination(1.0, p1, -p1.dotProduct(delta) / norm2, delta);
     }
 
     /** Get the tolerance below which points are considered identical.
@@ -105,7 +105,7 @@ public class Line implements Embedding<Point3D, Point1D> {
     /** Get the line point closest to the origin.
      * @return line point closest to the origin
      */
-    public Point3D getOrigin() {
+    public Vector3D getOrigin() {
         return zero;
     }
 
@@ -116,7 +116,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param point point to check
      * @return abscissa of the point
      */
-    public double getAbscissa(final Point3D point) {
+    public double getAbscissa(final Vector3D point) {
         return point.subtract(zero).dotProduct(direction);
     }
 
@@ -124,8 +124,8 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param abscissa desired abscissa for the point
      * @return one point belonging to the line, at specified abscissa
      */
-    public Point3D pointAt(final double abscissa) {
-        return Point3D.vectorCombination(1.0, zero, abscissa, direction);
+    public Vector3D pointAt(final double abscissa) {
+        return Vector3D.linearCombination(1.0, zero, abscissa, direction);
     }
 
     /** Transform a space point into a sub-space point.
@@ -134,8 +134,8 @@ public class Line implements Embedding<Point3D, Point1D> {
      * the specified space point
      */
     @Override
-    public Point1D toSubSpace(final Point3D point) {
-        return Point1D.of(getAbscissa(point));
+    public Vector1D toSubSpace(final Vector3D point) {
+        return Vector1D.of(getAbscissa(point));
     }
 
     /** Transform a sub-space point into a space point.
@@ -144,7 +144,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * specified sub-space point
      */
     @Override
-    public Point3D toSpace(final Point1D point) {
+    public Vector3D toSpace(final Vector1D point) {
         return pointAt(point.getX());
     }
 
@@ -164,7 +164,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param p point to check
      * @return true if p belongs to the line
      */
-    public boolean contains(final Point3D p) {
+    public boolean contains(final Vector3D p) {
         return distance(p) < tolerance;
     }
 
@@ -172,7 +172,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param p to check
      * @return distance between the instance and the point
      */
-    public double distance(final Point3D p) {
+    public double distance(final Vector3D p) {
         final Vector3D d = p.subtract(zero);
         final Vector3D n = Vector3D.linearCombination(1.0, d, -d.dotProduct(direction), direction);
         return n.getNorm();
@@ -202,7 +202,7 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @param line line to check against the instance
      * @return point of the instance closest to another line
      */
-    public Point3D closestPoint(final Line line) {
+    public Vector3D closestPoint(final Line line) {
 
         final double cos = direction.dotProduct(line.direction);
         final double n = 1 - cos * cos;
@@ -215,7 +215,7 @@ public class Line implements Embedding<Point3D, Point1D> {
         final double a        = delta0.dotProduct(direction);
         final double b        = delta0.dotProduct(line.direction);
 
-        return Point3D.vectorCombination(1, zero, (a - b * cos) / n, direction);
+        return Vector3D.linearCombination(1, zero, (a - b * cos) / n, direction);
 
     }
 
@@ -224,8 +224,8 @@ public class Line implements Embedding<Point3D, Point1D> {
      * @return intersection point of the instance and the other line
      * or null if there are no intersection points
      */
-    public Point3D intersection(final Line line) {
-        final Point3D closest = closestPoint(line);
+    public Vector3D intersection(final Line line) {
+        final Vector3D closest = closestPoint(line);
         return line.contains(closest) ? closest : null;
     }
 
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/OutlineExtractor.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/OutlineExtractor.java
index be504db..0fd8448 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/OutlineExtractor.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/OutlineExtractor.java
@@ -24,7 +24,7 @@ import org.apache.commons.geometry.core.partitioning.BSPTreeVisitor;
 import org.apache.commons.geometry.core.partitioning.BoundaryAttribute;
 import org.apache.commons.geometry.core.partitioning.RegionFactory;
 import org.apache.commons.geometry.core.partitioning.SubHyperplane;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 
 /** Extractor for {@link PolygonsSet polyhedrons sets} outlines.
@@ -56,7 +56,7 @@ public class OutlineExtractor {
      * @param polyhedronsSet polyhedrons set whose outline must be extracted
      * @return an outline, as an array of loops.
      */
-    public Point2D[][] getOutline(final PolyhedronsSet polyhedronsSet) {
+    public Vector2D[][] getOutline(final PolyhedronsSet polyhedronsSet) {
 
         // project all boundary facets into one polygons set
         final BoundaryProjector projector = new BoundaryProjector(polyhedronsSet.getTolerance());
@@ -64,9 +64,9 @@ public class OutlineExtractor {
         final PolygonsSet projected = projector.getProjected();
 
         // Remove the spurious intermediate vertices from the outline
-        final Point2D[][] outline = projected.getVertices();
+        final Vector2D[][] outline = projected.getVertices();
         for (int i = 0; i < outline.length; ++i) {
-            final Point2D[] rawLoop = outline[i];
+            final Vector2D[] rawLoop = outline[i];
             int end = rawLoop.length;
             int j = 0;
             while (j < end) {
@@ -83,7 +83,7 @@ public class OutlineExtractor {
             }
             if (end != rawLoop.length) {
                 // resize the array
-                outline[i] = new Point2D[end];
+                outline[i] = new Vector2D[end];
                 System.arraycopy(rawLoop, 0, outline[i], 0, end);
             }
         }
@@ -100,10 +100,10 @@ public class OutlineExtractor {
      * @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 Point2D[] loop, final int n, final int i) {
-        final Point2D previous = loop[(i + n - 1) % n];
-        final Point2D current  = loop[i];
-        final Point2D next     = loop[(i + 1) % n];
+    private boolean pointIsBetween(final Vector2D[] loop, final int n, final int i) {
+        final Vector2D previous = loop[(i + n - 1) % n];
+        final Vector2D current  = loop[i];
+        final Vector2D 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();
@@ -115,7 +115,7 @@ public class OutlineExtractor {
     }
 
     /** Visitor projecting the boundary facets on a plane. */
-    private class BoundaryProjector implements BSPTreeVisitor<Point3D> {
+    private class BoundaryProjector implements BSPTreeVisitor<Vector3D> {
 
         /** Projection of the polyhedrons set on the plane. */
         private PolygonsSet projected;
@@ -127,22 +127,22 @@ public class OutlineExtractor {
          * @param tolerance tolerance below which points are considered identical
          */
         BoundaryProjector(final double tolerance) {
-            this.projected = new PolygonsSet(new BSPTree<Point2D>(Boolean.FALSE), tolerance);
+            this.projected = new PolygonsSet(new BSPTree<Vector2D>(Boolean.FALSE), tolerance);
             this.tolerance = tolerance;
         }
 
         /** {@inheritDoc} */
         @Override
-        public Order visitOrder(final BSPTree<Point3D> node) {
+        public Order visitOrder(final BSPTree<Vector3D> node) {
             return Order.MINUS_SUB_PLUS;
         }
 
         /** {@inheritDoc} */
         @Override
-        public void visitInternalNode(final BSPTree<Point3D> node) {
+        public void visitInternalNode(final BSPTree<Vector3D> node) {
             @SuppressWarnings("unchecked")
-            final BoundaryAttribute<Point3D> attribute =
-                (BoundaryAttribute<Point3D>) node.getAttribute();
+            final BoundaryAttribute<Vector3D> attribute =
+                (BoundaryAttribute<Vector3D>) node.getAttribute();
             if (attribute.getPlusOutside() != null) {
                 addContribution(attribute.getPlusOutside(), false);
             }
@@ -153,33 +153,33 @@ public class OutlineExtractor {
 
         /** {@inheritDoc} */
         @Override
-        public void visitLeafNode(final BSPTree<Point3D> node) {
+        public void visitLeafNode(final BSPTree<Vector3D> 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<Point3D> facet, final boolean reversed) {
+        private void addContribution(final SubHyperplane<Vector3D> facet, final boolean reversed) {
 
             // extract the vertices of the facet
             @SuppressWarnings("unchecked")
-            final AbstractSubHyperplane<Point3D, Point2D> absFacet =
-                (AbstractSubHyperplane<Point3D, Point2D>) facet;
+            final AbstractSubHyperplane<Vector3D, Vector2D> absFacet =
+                (AbstractSubHyperplane<Vector3D, Vector2D>) facet;
             final Plane plane    = (Plane) facet.getHyperplane();
 
             final double scal = plane.getNormal().dotProduct(w);
             if (Math.abs(scal) > 1.0e-3) {
-                Point2D[][] vertices =
+                Vector2D[][] vertices =
                     ((PolygonsSet) absFacet.getRemainingRegion()).getVertices();
 
                 if ((scal < 0) ^ reversed) {
                     // the facet is seen from the inside,
                     // we need to invert its boundary orientation
-                    final Point2D[][] newVertices = new Point2D[vertices.length][];
+                    final Vector2D[][] newVertices = new Vector2D[vertices.length][];
                     for (int i = 0; i < vertices.length; ++i) {
-                        final Point2D[] loop = vertices[i];
-                        final Point2D[] newLoop = new Point2D[loop.length];
+                        final Vector2D[] loop = vertices[i];
+                        final Vector2D[] newLoop = new Vector2D[loop.length];
                         if (loop[0] == null) {
                             newLoop[0] = null;
                             for (int j = 1; j < loop.length; ++j) {
@@ -199,22 +199,22 @@ public class OutlineExtractor {
                 }
 
                 // compute the projection of the facet in the outline plane
-                final ArrayList<SubHyperplane<Point2D>> edges = new ArrayList<>();
-                for (Point2D[] loop : vertices) {
+                final ArrayList<SubHyperplane<Vector2D>> edges = new ArrayList<>();
+                for (Vector2D[] loop : vertices) {
                     final boolean closed = loop[0] != null;
                     int previous         = closed ? (loop.length - 1) : 1;
-                    Vector3D previous3D  = plane.toSpace(loop[previous]).asVector();
+                    Vector3D previous3D  = plane.toSpace(loop[previous]);
                     int current          = (previous + 1) % loop.length;
-                    Point2D pPoint       = Point2D.of(previous3D.dotProduct(u),
+                    Vector2D pPoint       = Vector2D.of(previous3D.dotProduct(u),
                                                          previous3D.dotProduct(v));
                     while (current < loop.length) {
 
-                        final Vector3D current3D = plane.toSpace(loop[current]).asVector();
-                        final Point2D  cPoint    = Point2D.of(current3D.dotProduct(u),
+                        final Vector3D current3D = plane.toSpace(loop[current]);
+                        final Vector2D  cPoint    = Vector2D.of(current3D.dotProduct(u),
                                                                  current3D.dotProduct(v));
                         final org.apache.commons.geometry.euclidean.twod.Line line =
                             new org.apache.commons.geometry.euclidean.twod.Line(pPoint, cPoint, tolerance);
-                        SubHyperplane<Point2D> edge = line.wholeHyperplane();
+                        SubHyperplane<Vector2D> edge = line.wholeHyperplane();
 
                         if (closed || (previous != 1)) {
                             // the previous point is a real vertex
@@ -245,7 +245,7 @@ public class OutlineExtractor {
                 final PolygonsSet projectedFacet = new PolygonsSet(edges, tolerance);
 
                 // add the contribution of the facet to the global outline
-                projected = (PolygonsSet) new RegionFactory<Point2D>().union(projected, projectedFacet);
+                projected = (PolygonsSet) new RegionFactory<Vector2D>().union(projected, projectedFacet);
 
             }
         }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Plane.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Plane.java
index 4d5ba76..865b666 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Plane.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Plane.java
@@ -20,19 +20,19 @@ import org.apache.commons.geometry.core.exception.IllegalNormException;
 import org.apache.commons.geometry.core.partitioning.Embedding;
 import org.apache.commons.geometry.core.partitioning.Hyperplane;
 import org.apache.commons.geometry.euclidean.internal.Vectors;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 
 /** The class represent planes in a three dimensional space.
  */
-public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
+public class Plane implements Hyperplane<Vector3D>, Embedding<Vector3D, Vector2D> {
 
     /** Offset of the origin with respect to the plane. */
     private double originOffset;
 
     /** Origin of the plane frame. */
-    private Point3D origin;
+    private Vector3D origin;
 
     /** First vector of the plane frame (in plane). */
     private Vector3D u;
@@ -65,11 +65,11 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if the normal norm is too small
      */
-    public Plane(final Point3D p, final Vector3D normal, final double tolerance)
+    public Plane(final Vector3D p, final Vector3D normal, final double tolerance)
         throws IllegalArgumentException {
         setNormal(normal);
         this.tolerance = tolerance;
-        this.originOffset = -p.asVector().dotProduct(w);
+        this.originOffset = -p.dotProduct(w);
         setFrame();
     }
 
@@ -82,7 +82,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if the points do not constitute a plane
      */
-    public Plane(final Point3D p1, final Point3D p2, final Point3D p3, final double tolerance)
+    public Plane(final Vector3D p1, final Vector3D p2, final Vector3D p3, final double tolerance)
         throws IllegalArgumentException {
         this(p1, p2.subtract(p1).crossProduct(p3.subtract(p1)), tolerance);
     }
@@ -118,9 +118,9 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param normal normal direction to the plane
      * @exception IllegalArgumentException if the normal norm is too small
      */
-    public void reset(final Point3D p, final Vector3D normal) {
+    public void reset(final Vector3D p, final Vector3D normal) {
         setNormal(normal);
-        originOffset = -p.asVector().dotProduct(w);
+        originOffset = -p.dotProduct(w);
         setFrame();
     }
 
@@ -151,7 +151,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
     /** Reset the plane frame.
      */
     private void setFrame() {
-        origin = Vector3D.linearCombination(-originOffset, w).asPoint();
+        origin = Vector3D.linearCombination(-originOffset, w);
         u = w.orthogonal();
         v = w.crossProduct(u);
     }
@@ -162,7 +162,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @return the origin point of the plane frame (point closest to the
      * 3D-space origin)
      */
-    public Point3D getOrigin() {
+    public Vector3D getOrigin() {
         return origin;
     }
 
@@ -204,7 +204,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
 
     /** {@inheritDoc} */
     @Override
-    public Point3D project(Point3D point) {
+    public Vector3D project(Vector3D point) {
         return toSpace(toSubSpace(point));
     }
 
@@ -234,24 +234,24 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
     }
 
     /** Transform a 3D space point into an in-plane point.
-     * @param point point of the space (must be a {@link Point3D} instance)
+     * @param point point of the space (must be a {@link Vector3D} instance)
      * @return in-plane point
      * @see #toSpace
      */
     @Override
-    public Point2D toSubSpace(final Point3D point) {
-        Vector3D vec = point.asVector();
-        return Point2D.of(vec.dotProduct(u), vec.dotProduct(v));
+    public Vector2D toSubSpace(final Vector3D point) {
+        Vector3D vec = point;
+        return Vector2D.of(vec.dotProduct(u), vec.dotProduct(v));
     }
 
     /** Transform an in-plane point into a 3D space point.
-     * @param point in-plane point (must be a {@link Point2D} instance)
+     * @param point in-plane point (must be a {@link Vector2D} instance)
      * @return 3D space point
      * @see #toSubSpace
      */
     @Override
-    public Point3D toSpace(final Point2D point) {
-        return Point3D.vectorCombination(point.getX(), u, point.getY(), v, -originOffset, w);
+    public Vector3D toSpace(final Vector2D point) {
+        return Vector3D.linearCombination(point.getX(), u, point.getY(), v, -originOffset, w);
     }
 
     /** Get one point from the 3D-space.
@@ -261,8 +261,8 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @return one point in the 3D-space, with given coordinates and offset
      * relative to the plane
      */
-    public Point3D getPointAt(final Point2D inPlane, final double offset) {
-        return Point3D.vectorCombination(inPlane.getX(), u, inPlane.getY(), v, offset - originOffset, w);
+    public Vector3D getPointAt(final Vector2D inPlane, final double offset) {
+        return Vector3D.linearCombination(inPlane.getX(), u, inPlane.getY(), v, offset - originOffset, w);
     }
 
     /** Check if the instance is similar to another plane.
@@ -284,7 +284,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param rotation vectorial rotation operator
      * @return a new plane
      */
-    public Plane rotate(final Point3D center, final Rotation rotation) {
+    public Plane rotate(final Vector3D center, final Rotation rotation) {
 
         final Vector3D delta = origin.subtract(center);
         final Plane plane = new Plane(center.add(rotation.applyTo(delta)),
@@ -320,15 +320,15 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @return intersection point between between the line and the
      * instance (null if the line is parallel to the instance)
      */
-    public Point3D intersection(final Line line) {
+    public Vector3D intersection(final Line line) {
         final Vector3D direction = line.getDirection();
         final double   dot       = w.dotProduct(direction);
         if (Math.abs(dot) < 1.0e-10) {
             return null;
         }
-        final Point3D point = line.toSpace(Point1D.ZERO);
-        final double   k     = -(originOffset + w.dotProduct(point.asVector())) / dot;
-        return Point3D.vectorCombination(1.0, point, k, direction);
+        final Vector3D point = line.toSpace(Vector1D.ZERO);
+        final double   k     = -(originOffset + w.dotProduct(point)) / dot;
+        return Vector3D.linearCombination(1.0, point, k, direction);
     }
 
     /** Build the line shared by the instance and another plane.
@@ -341,7 +341,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
         if (direction.getNorm() < tolerance) {
             return null;
         }
-        final Point3D point = intersection(this, other, new Plane(direction, tolerance));
+        final Vector3D point = intersection(this, other, new Plane(direction, tolerance));
         return new Line(point, point.add(direction), tolerance);
     }
 
@@ -351,7 +351,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param plane3 third plane2
      * @return intersection point of three planes, null if some planes are parallel
      */
-    public static Point3D intersection(final Plane plane1, final Plane plane2, final Plane plane3) {
+    public static Vector3D intersection(final Plane plane1, final Plane plane2, final Plane plane3) {
 
         // coefficients of the three planes linear equations
         final double a1 = plane1.w.getX();
@@ -380,7 +380,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
         }
 
         final double r = 1.0 / determinant;
-        return Point3D.of(
+        return Vector3D.of(
                             (-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);
@@ -408,7 +408,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @param p point to check
      * @return true if p belongs to the plane
      */
-    public boolean contains(final Point3D p) {
+    public boolean contains(final Vector3D p) {
         return Math.abs(getOffset(p)) < tolerance;
     }
 
@@ -435,8 +435,8 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * @return offset of the point
      */
     @Override
-    public double getOffset(final Point3D point) {
-        return point.asVector().dotProduct(w) + originOffset;
+    public double getOffset(final Vector3D point) {
+        return point.dotProduct(w) + originOffset;
     }
 
     /** Check if the instance has the same orientation as another hyperplane.
@@ -445,7 +445,7 @@ public class Plane implements Hyperplane<Point3D>, Embedding<Point3D, Point2D> {
      * the same orientation
      */
     @Override
-    public boolean sameOrientationAs(final Hyperplane<Point3D> other) {
+    public boolean sameOrientationAs(final Hyperplane<Vector3D> other) {
         return (((Plane) other).w).dotProduct(w) > 0.0;
     }
 
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java
deleted file mode 100644
index 24626ec..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Point3D.java
+++ /dev/null
@@ -1,318 +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.geometry.euclidean.threed;
-
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-import org.apache.commons.geometry.euclidean.EuclideanPoint;
-import org.apache.commons.geometry.euclidean.internal.Vectors;
-import org.apache.commons.numbers.arrays.LinearCombination;
-
-/** This class represents a point in three-dimensional Euclidean space.
- * Instances of this class are guaranteed to be immutable.
- */
-public final class Point3D extends Cartesian3D implements EuclideanPoint<Point3D, Vector3D> {
-
-    /** Zero point (coordinates: 0, 0, 0). */
-    public static final Point3D ZERO   = new Point3D(0, 0, 0);
-
-    // CHECKSTYLE: stop ConstantName
-    /** A point with all coordinates set to NaN. */
-    public static final Point3D NaN = new Point3D(Double.NaN, Double.NaN, Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A point with all coordinates set to positive infinity. */
-    public static final Point3D POSITIVE_INFINITY =
-        new Point3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-
-    /** A point with all coordinates set to negative infinity. */
-    public static final Point3D NEGATIVE_INFINITY =
-        new Point3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-
-    /** Serializable version identifier. */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Simple constructor.
-     * Build a point from its coordinates
-     * @param x abscissa
-     * @param y ordinate
-     * @param z height
-     */
-    private Point3D(double x, double y, double z) {
-        super(x, y, z);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector3D asVector() {
-        return Vector3D.of(getX(), getY(), getZ());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point3D p) {
-        return Vectors.norm(
-                getX() - p.getX(),
-                getY() - p.getY(),
-                getZ() - p.getZ());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector3D subtract(Point3D p) {
-        return Vector3D.of(
-                    getX() - p.getX(),
-                    getY() - p.getY(),
-                    getZ() - p.getZ()
-                );
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector3D vectorTo(Point3D p) {
-        return p.subtract(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector3D directionTo(Point3D p) {
-        return Vector3D.normalize(
-                p.getX() - getX(),
-                p.getY() - getY(),
-                p.getZ() - getZ());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point3D lerp(Point3D p, double t) {
-        return vectorCombination(1.0 - t, this, t, p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point3D add(Vector3D v) {
-        return new Point3D(
-                    getX() + v.getX(),
-                    getY() + v.getY(),
-                    getZ() + v.getZ()
-                );
-    }
-
-    /**
-     * Get a hashCode for the point.
-     * <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 * Double.hashCode(getX()) +  3 * Double.hashCode(getY()) +  Double.hashCode(getZ()));
-    }
-
-    /** Test for the equality of two points.
-     * <p>
-     * If all coordinates of two points are exactly the same, and none are
-     * <code>Double.NaN</code>, the two points are considered to be equal.
-     * </p>
-     * <p>
-     * <code>NaN</code> coordinates are considered to globally affect the point
-     * and be equal to each other - i.e, if either (or all) coordinates of the
-     * point are equal to <code>Double.NaN</code>, the point is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if two Point3D objects are equal, false if
-     *         object is null, not an instance of Point3D, or
-     *         not equal to this Point3D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Point3D) {
-            final Point3D rhs = (Point3D) other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return (getX() == rhs.getX()) && (getY() == rhs.getY()) && (getZ() == rhs.getZ());
-        }
-        return false;
-    }
-
-    /** Returns a point with the given coordinate values
-     * @param x abscissa (first coordinate value)
-     * @param y ordinate (second coordinate value)
-     * @param z height (third coordinate value)
-     * @return point instance
-     */
-    public static Point3D of(double x, double y, double z) {
-        return new Point3D(x, y, z);
-    }
-
-    /** Creates a point from the coordinates in the given 3-element array.
-     * @param p coordinates array
-     * @return new point
-     * @exception IllegalArgumentException if the array does not have 3 elements
-     */
-    public static Point3D ofArray(double[] p) {
-        if (p.length != 3) {
-            throw new IllegalArgumentException("Dimension mismatch: " + p.length + " != 3");
-        }
-        return new Point3D(p[0], p[1], p[2]);
-    }
-
-    /** Create a point from a set of spherical coordinates.
-     * @param radius the spherical radius value
-     * @param azimuth the angle in the x-y plane measured in radians counter-clockwise from the
-     *      positive x axis.
-     * @param polar the angle with the positive z axis in radians.
-     * @return a point instance with the given set of spherical coordinates
-     */
-    public static Point3D ofSpherical(double radius, double azimuth, double polar) {
-        return SphericalCoordinates.toCartesian(radius, azimuth, polar, Point3D::new);
-    }
-
-    /** Parses the given string and returns a new point instance. The expected string
-     * format is the same as that returned by {@link #toString()}.
-     * @param str the string to parse
-     * @return point instance represented by the string
-     * @throws IllegalArgumentException if the given string has an invalid format
-     */
-    public static Point3D parse(String str) {
-        return SimpleTupleFormat.getDefault().parse(str, Point3D::new);
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a scale factor for first coordinate
-     * @param c first coordinate
-     * @return point with coordinates calculated by {@code a * c}
-     */
-    public static Point3D vectorCombination(double a, Cartesian3D c) {
-        return new Point3D(a * c.getX(), a * c.getY(), a * c.getZ());
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
-     */
-    public static Point3D vectorCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2) {
-        return new Point3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
-     */
-    public static Point3D vectorCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2,
-            double a3, Cartesian3D c3) {
-        return new Point3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ(), a3, c3.getZ()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
-     */
-    public static Point3D vectorCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2,
-            double a3, Cartesian3D c3, double a4, Cartesian3D c4) {
-        return new Point3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY(), a4, c4.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ(), a3, c3.getZ(), a4, c4.getZ()));
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
index 5c283ac..c107952 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
@@ -32,14 +32,14 @@ import org.apache.commons.geometry.core.partitioning.Region;
 import org.apache.commons.geometry.core.partitioning.RegionFactory;
 import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 import org.apache.commons.geometry.core.partitioning.Transform;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 import org.apache.commons.geometry.euclidean.twod.SubLine;
 
 /** This class represents a 3D region: a set of polyhedrons.
  */
-public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
+public class PolyhedronsSet extends AbstractRegion<Vector3D, Vector2D> {
 
     /** Build a polyhedrons set representing the whole real line.
      * @param tolerance tolerance below which points are considered identical
@@ -68,7 +68,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @param tree inside/outside BSP tree representing the region
      * @param tolerance tolerance below which points are considered identical
      */
-    public PolyhedronsSet(final BSPTree<Point3D> tree, final double tolerance) {
+    public PolyhedronsSet(final BSPTree<Vector3D> tree, final double tolerance) {
         super(tree, tolerance);
     }
 
@@ -92,7 +92,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * collection of {@link SubHyperplane SubHyperplane} objects
      * @param tolerance tolerance below which points are considered identical
      */
-    public PolyhedronsSet(final Collection<SubHyperplane<Point3D>> boundary,
+    public PolyhedronsSet(final Collection<SubHyperplane<Vector3D>> boundary,
                           final double tolerance) {
         super(boundary, tolerance);
     }
@@ -114,7 +114,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if some basic sanity checks fail
      */
-    public PolyhedronsSet(final List<Point3D> vertices, final List<int[]> facets,
+    public PolyhedronsSet(final List<Vector3D> vertices, final List<int[]> facets,
                           final double tolerance) {
         super(buildBoundary(vertices, facets, tolerance), tolerance);
     }
@@ -145,7 +145,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @param tolerance tolerance below which points are considered identical
      * @return boundary tree
      */
-    private static BSPTree<Point3D> buildBoundary(final double xMin, final double xMax,
+    private static BSPTree<Vector3D> buildBoundary(final double xMin, final double xMax,
                                                       final double yMin, final double yMax,
                                                       final double zMin, final double zMax,
                                                       final double tolerance) {
@@ -153,14 +153,14 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
             // too thin box, build an empty polygons set
             return new BSPTree<>(Boolean.FALSE);
         }
-        final Plane pxMin = new Plane(Point3D.of(xMin, 0,    0),   Vector3D.MINUS_X, tolerance);
-        final Plane pxMax = new Plane(Point3D.of(xMax, 0,    0),   Vector3D.PLUS_X,  tolerance);
-        final Plane pyMin = new Plane(Point3D.of(0,    yMin, 0),   Vector3D.MINUS_Y, tolerance);
-        final Plane pyMax = new Plane(Point3D.of(0,    yMax, 0),   Vector3D.PLUS_Y,  tolerance);
-        final Plane pzMin = new Plane(Point3D.of(0,    0,   zMin), Vector3D.MINUS_Z, tolerance);
-        final Plane pzMax = new Plane(Point3D.of(0,    0,   zMax), Vector3D.PLUS_Z,  tolerance);
-        final Region<Point3D> boundary =
-        new RegionFactory<Point3D>().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax);
+        final Plane pxMin = new Plane(Vector3D.of(xMin, 0,    0),   Vector3D.MINUS_X, tolerance);
+        final Plane pxMax = new Plane(Vector3D.of(xMax, 0,    0),   Vector3D.PLUS_X,  tolerance);
+        final Plane pyMin = new Plane(Vector3D.of(0,    yMin, 0),   Vector3D.MINUS_Y, tolerance);
+        final Plane pyMax = new Plane(Vector3D.of(0,    yMax, 0),   Vector3D.PLUS_Y,  tolerance);
+        final Plane pzMin = new Plane(Vector3D.of(0,    0,   zMin), Vector3D.MINUS_Z, tolerance);
+        final Plane pzMax = new Plane(Vector3D.of(0,    0,   zMax), Vector3D.PLUS_Z,  tolerance);
+        final Region<Vector3D> boundary =
+        new RegionFactory<Vector3D>().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax);
         return boundary.getTree(false);
     }
 
@@ -171,13 +171,13 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @return boundary as a list of sub-hyperplanes
      * @exception IllegalArgumentException if some basic sanity checks fail
      */
-    private static List<SubHyperplane<Point3D>> buildBoundary(final List<Point3D> vertices,
+    private static List<SubHyperplane<Vector3D>> buildBoundary(final List<Vector3D> vertices,
                                                                   final List<int[]> facets,
                                                                   final double tolerance) {
 
         // check vertices distances
         for (int i = 0; i < vertices.size() - 1; ++i) {
-            final Point3D vi = vertices.get(i);
+            final Vector3D vi = vertices.get(i);
             for (int j = i + 1; j < vertices.size(); ++j) {
                 if (vi.distance(vertices.get(j)) <= tolerance) {
                     throw new IllegalArgumentException("Vertices are too close near point " + vi);
@@ -203,15 +203,15 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
                         found = found || (v == vA);
                     }
                     if (!found) {
-                        final Point3D start = vertices.get(vA);
-                        final Point3D end   = vertices.get(vB);
+                        final Vector3D start = vertices.get(vA);
+                        final Vector3D end   = vertices.get(vB);
                         throw new IllegalArgumentException(MessageFormat.format("Edge joining points {0} and {1} is connected to one facet only", start, end));
                     }
                 }
             }
         }
 
-        final List<SubHyperplane<Point3D>> boundary = new ArrayList<>();
+        final List<SubHyperplane<Vector3D>> boundary = new ArrayList<>();
 
         for (final int[] facet : facets) {
 
@@ -220,9 +220,9 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
                                     tolerance);
 
             // check all points are in the plane
-            final Point2D[] two2Points = new Point2D[facet.length];
+            final Vector2D[] two2Points = new Vector2D[facet.length];
             for (int i = 0 ; i < facet.length; ++i) {
-                final Point3D v = vertices.get(facet[i]);
+                final Vector3D v = vertices.get(facet[i]);
                 if (!plane.contains(v)) {
                     throw new IllegalArgumentException("Point " + v + " is out of plane");
                 }
@@ -244,7 +244,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @return references array such that r[v][k] = f for some k if facet f contains vertex v
      * @exception IllegalArgumentException if some facets have fewer than 3 vertices
      */
-    private static int[][] findReferences(final List<Point3D> vertices, final List<int[]> facets) {
+    private static int[][] findReferences(final List<Vector3D> vertices, final List<int[]> facets) {
 
         // find the maximum number of facets a vertex belongs to
         final int[] nbFacets = new int[vertices.size()];
@@ -288,7 +288,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * once in the successors list (which means one facet orientation is wrong)
 
      */
-    private static int[][] successors(final List<Point3D> vertices, final List<int[]> facets,
+    private static int[][] successors(final List<Vector3D> vertices, final List<int[]> facets,
                                       final int[][] references) {
 
         // create an array large enough
@@ -311,8 +311,8 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
                 successors[v][k] = facet[(i + 1) % facet.length];
                 for (int l = 0; l < k; ++l) {
                     if (successors[v][l] == successors[v][k]) {
-                        final Point3D start = vertices.get(v);
-                        final Point3D end   = vertices.get(successors[v][k]);
+                        final Vector3D start = vertices.get(v);
+                        final Vector3D end   = vertices.get(successors[v][k]);
                         throw new IllegalArgumentException(MessageFormat.format("Facet orientation mismatch around edge joining points {0} and {1}", start, end));
                     }
                 }
@@ -326,7 +326,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
 
     /** {@inheritDoc} */
     @Override
-    public PolyhedronsSet buildNew(final BSPTree<Point3D> tree) {
+    public PolyhedronsSet buildNew(final BSPTree<Vector3D> tree) {
         return new PolyhedronsSet(tree, getTolerance());
     }
 
@@ -336,11 +336,11 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
         // check simple cases first
         if (isEmpty()) {
             setSize(0.0);
-            setBarycenter(Point3D.NaN);
+            setBarycenter(Vector3D.NaN);
         }
         else if (isFull()) {
             setSize(Double.POSITIVE_INFINITY);
-            setBarycenter(Point3D.NaN);
+            setBarycenter(Vector3D.NaN);
         }
         else {
             // not empty or full; compute the contribution of all boundary facets
@@ -348,12 +348,12 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
             getTree(true).visit(contributionVisitor);
 
             final double size = contributionVisitor.getSize();
-            final Point3D barycenter = contributionVisitor.getBarycenter();
+            final Vector3D barycenter = contributionVisitor.getBarycenter();
 
             if (size < 0) {
                 // the polyhedrons set is a finite outside surrounded by an infinite inside
                 setSize(Double.POSITIVE_INFINITY);
-                setBarycenter(Point3D.NaN);
+                setBarycenter(Vector3D.NaN);
             } else {
                 // the polyhedrons set is finite
                 setSize(size);
@@ -376,13 +376,13 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      *  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<Point3D> {
+    private static class FacetsContributionVisitor implements BSPTreeVisitor<Vector3D> {
 
         /** Accumulator for facet volume contributions. */
         private double volumeSum;
 
         /** Accumulator for barycenter contributions. */
-        private Point3D barycenterSum = Point3D.ZERO;
+        private Vector3D barycenterSum = Vector3D.ZERO;
 
         /** Returns the total computed size (ie, volume) of the polyhedron.
          * This value will be negative if the polyhedron is "inside-out", meaning
@@ -399,25 +399,25 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
          * region is infinite.
          * @return the barycenter.
          */
-        public Point3D getBarycenter() {
+        public Vector3D 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 Point3D.vectorCombination(1.0 / (4 * getSize()), barycenterSum);
+            return Vector3D.linearCombination(1.0 / (4 * getSize()), barycenterSum);
         }
 
         /** {@inheritDoc} */
         @Override
-        public Order visitOrder(final BSPTree<Point3D> node) {
+        public Order visitOrder(final BSPTree<Vector3D> node) {
             return Order.MINUS_SUB_PLUS;
         }
 
         /** {@inheritDoc} */
         @Override
-        public void visitInternalNode(final BSPTree<Point3D> node) {
+        public void visitInternalNode(final BSPTree<Vector3D> node) {
             @SuppressWarnings("unchecked")
-            final BoundaryAttribute<Point3D> attribute =
-                (BoundaryAttribute<Point3D>) node.getAttribute();
+            final BoundaryAttribute<Vector3D> attribute =
+                (BoundaryAttribute<Vector3D>) node.getAttribute();
             if (attribute.getPlusOutside() != null) {
                 addContribution(attribute.getPlusOutside(), false);
             }
@@ -428,34 +428,34 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
 
         /** {@inheritDoc} */
         @Override
-        public void visitLeafNode(final BSPTree<Point3D> node) {
+        public void visitLeafNode(final BSPTree<Vector3D> 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<Point3D> facet, final boolean reversed) {
+        private void addContribution(final SubHyperplane<Vector3D> facet, final boolean reversed) {
 
-            final Region<Point2D> polygon = ((SubPlane) facet).getRemainingRegion();
+            final Region<Vector2D> polygon = ((SubPlane) facet).getRemainingRegion();
             final double area = polygon.getSize();
 
             if (Double.isInfinite(area)) {
                 volumeSum = Double.POSITIVE_INFINITY;
-                barycenterSum = Point3D.NaN;
+                barycenterSum = Vector3D.NaN;
             } else {
                 final Plane plane = (Plane) facet.getHyperplane();
-                final Point3D facetBarycenter = plane.toSpace(polygon.getBarycenter());
+                final Vector3D 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.asVector().dotProduct(plane.getNormal());
+                double scaledVolume = area * facetBarycenter.dotProduct(plane.getNormal());
                 if (reversed) {
                     scaledVolume = -scaledVolume;
                 }
 
                 volumeSum += scaledVolume;
-                barycenterSum = Point3D.vectorCombination(1.0, barycenterSum, scaledVolume, facetBarycenter);
+                barycenterSum = Vector3D.linearCombination(1.0, barycenterSum, scaledVolume, facetBarycenter);
             }
         }
     }
@@ -467,7 +467,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * given point, or null if the line does not intersect any
      * sub-hyperplane
      */
-    public SubHyperplane<Point3D> firstIntersection(final Point3D point, final Line line) {
+    public SubHyperplane<Vector3D> firstIntersection(final Vector3D point, final Line line) {
         return recurseFirstIntersection(getTree(true), point, line);
     }
 
@@ -479,23 +479,23 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * given point, or null if the line does not intersect any
      * sub-hyperplane
      */
-    private SubHyperplane<Point3D> recurseFirstIntersection(final BSPTree<Point3D> node,
-                                                                final Point3D point,
+    private SubHyperplane<Vector3D> recurseFirstIntersection(final BSPTree<Vector3D> node,
+                                                                final Vector3D point,
                                                                 final Line line) {
 
-        final SubHyperplane<Point3D> cut = node.getCut();
+        final SubHyperplane<Vector3D> cut = node.getCut();
         if (cut == null) {
             return null;
         }
-        final BSPTree<Point3D> minus = node.getMinus();
-        final BSPTree<Point3D> plus  = node.getPlus();
+        final BSPTree<Vector3D> minus = node.getMinus();
+        final BSPTree<Vector3D> plus  = node.getPlus();
         final Plane                plane = (Plane) cut.getHyperplane();
 
         // establish search order
         final double offset = plane.getOffset(point);
         final boolean in    = Math.abs(offset) < getTolerance();
-        final BSPTree<Point3D> near;
-        final BSPTree<Point3D> far;
+        final BSPTree<Vector3D> near;
+        final BSPTree<Vector3D> far;
         if (offset < 0) {
             near = minus;
             far  = plus;
@@ -506,23 +506,23 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
 
         if (in) {
             // search in the cut hyperplane
-            final SubHyperplane<Point3D> facet = boundaryFacet(point, node);
+            final SubHyperplane<Vector3D> facet = boundaryFacet(point, node);
             if (facet != null) {
                 return facet;
             }
         }
 
         // search in the near branch
-        final SubHyperplane<Point3D> crossed = recurseFirstIntersection(near, point, line);
+        final SubHyperplane<Vector3D> crossed = recurseFirstIntersection(near, point, line);
         if (crossed != null) {
             return crossed;
         }
 
         if (!in) {
             // search in the cut hyperplane
-            final Point3D hit3D = plane.intersection(line);
+            final Vector3D hit3D = plane.intersection(line);
             if (hit3D != null && line.getAbscissa(hit3D) > line.getAbscissa(point)) {
-                final SubHyperplane<Point3D> facet = boundaryFacet(hit3D, node);
+                final SubHyperplane<Vector3D> facet = boundaryFacet(hit3D, node);
                 if (facet != null) {
                     return facet;
                 }
@@ -540,18 +540,18 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @return the boundary facet this points belongs to (or null if it
      * does not belong to any boundary facet)
      */
-    private SubHyperplane<Point3D> boundaryFacet(final Point3D point,
-                                                     final BSPTree<Point3D> node) {
-        final Point2D point2D = ((Plane) node.getCut().getHyperplane()).toSubSpace(point);
+    private SubHyperplane<Vector3D> boundaryFacet(final Vector3D point,
+                                                     final BSPTree<Vector3D> node) {
+        final Vector2D Vector2D = ((Plane) node.getCut().getHyperplane()).toSubSpace(point);
         @SuppressWarnings("unchecked")
-        final BoundaryAttribute<Point3D> attribute =
-            (BoundaryAttribute<Point3D>) node.getAttribute();
+        final BoundaryAttribute<Vector3D> attribute =
+            (BoundaryAttribute<Vector3D>) node.getAttribute();
         if ((attribute.getPlusOutside() != null) &&
-            (((SubPlane) attribute.getPlusOutside()).getRemainingRegion().checkPoint(point2D) == Location.INSIDE)) {
+            (((SubPlane) attribute.getPlusOutside()).getRemainingRegion().checkPoint(Vector2D) == Location.INSIDE)) {
             return attribute.getPlusOutside();
         }
         if ((attribute.getPlusInside() != null) &&
-            (((SubPlane) attribute.getPlusInside()).getRemainingRegion().checkPoint(point2D) == Location.INSIDE)) {
+            (((SubPlane) attribute.getPlusInside()).getRemainingRegion().checkPoint(Vector2D) == Location.INSIDE)) {
             return attribute.getPlusInside();
         }
         return null;
@@ -563,15 +563,15 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
      * @param rotation vectorial rotation operator
      * @return a new instance representing the rotated region
      */
-    public PolyhedronsSet rotate(final Point3D center, final Rotation rotation) {
+    public PolyhedronsSet rotate(final Vector3D center, final Rotation rotation) {
         return (PolyhedronsSet) applyTransform(new RotationTransform(center, rotation));
     }
 
     /** 3D rotation as a Transform. */
-    private static class RotationTransform implements Transform<Point3D, Point2D> {
+    private static class RotationTransform implements Transform<Vector3D, Vector2D> {
 
         /** Center point of the rotation. */
-        private final Point3D   center;
+        private final Vector3D   center;
 
         /** Vectorial rotation. */
         private final Rotation   rotation;
@@ -580,46 +580,46 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
         private Plane cachedOriginal;
 
         /** Cached 2D transform valid inside the cached original hyperplane. */
-        private Transform<Point2D, Point1D>  cachedTransform;
+        private Transform<Vector2D, Vector1D>  cachedTransform;
 
         /** Build a rotation transform.
          * @param center center point of the rotation
          * @param rotation vectorial rotation
          */
-        RotationTransform(final Point3D center, final Rotation rotation) {
+        RotationTransform(final Vector3D center, final Rotation rotation) {
             this.center   = center;
             this.rotation = rotation;
         }
 
         /** {@inheritDoc} */
         @Override
-        public Point3D apply(final Point3D point) {
+        public Vector3D apply(final Vector3D point) {
             final Vector3D delta = point.subtract(center);
-            return Point3D.vectorCombination(1.0, center, 1.0, rotation.applyTo(delta));
+            return Vector3D.linearCombination(1.0, center, 1.0, rotation.applyTo(delta));
         }
 
         /** {@inheritDoc} */
         @Override
-        public Plane apply(final Hyperplane<Point3D> hyperplane) {
+        public Plane apply(final Hyperplane<Vector3D> hyperplane) {
             return ((Plane) hyperplane).rotate(center, rotation);
         }
 
         /** {@inheritDoc} */
         @Override
-        public SubHyperplane<Point2D> apply(final SubHyperplane<Point2D> sub,
-                                                final Hyperplane<Point3D> original,
-                                                final Hyperplane<Point3D> transformed) {
+        public SubHyperplane<Vector2D> apply(final SubHyperplane<Vector2D> sub,
+                                                final Hyperplane<Vector3D> original,
+                                                final Hyperplane<Vector3D> transformed) {
             if (original != cachedOriginal) {
                 // we have changed hyperplane, reset the in-hyperplane transform
 
                 final Plane    oPlane = (Plane) original;
                 final Plane    tPlane = (Plane) transformed;
-                final Point3D p00    = oPlane.getOrigin();
-                final Point3D p10    = oPlane.toSpace(Point2D.of(1.0, 0.0));
-                final Point3D p01    = oPlane.toSpace(Point2D.of(0.0, 1.0));
-                final Point2D tP00   = tPlane.toSubSpace(apply(p00));
-                final Point2D tP10   = tPlane.toSubSpace(apply(p10));
-                final Point2D tP01   = tPlane.toSubSpace(apply(p01));
+                final Vector3D p00    = oPlane.getOrigin();
+                final Vector3D p10    = oPlane.toSpace(Vector2D.of(1.0, 0.0));
+                final Vector3D p01    = oPlane.toSpace(Vector2D.of(0.0, 1.0));
+                final Vector2D tP00   = tPlane.toSubSpace(apply(p00));
+                final Vector2D tP10   = tPlane.toSubSpace(apply(p10));
+                final Vector2D tP01   = tPlane.toSubSpace(apply(p01));
 
                 cachedOriginal  = (Plane) original;
                 cachedTransform =
@@ -646,7 +646,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
     }
 
     /** 3D translation as a transform. */
-    private static class TranslationTransform implements Transform<Point3D, Point2D> {
+    private static class TranslationTransform implements Transform<Vector3D, Vector2D> {
 
         /** Translation vector. */
         private final Vector3D   translation;
@@ -655,7 +655,7 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
         private Plane cachedOriginal;
 
         /** Cached 2D transform valid inside the cached original hyperplane. */
-        private Transform<Point2D, Point1D>  cachedTransform;
+        private Transform<Vector2D, Vector1D>  cachedTransform;
 
         /** Build a translation transform.
          * @param translation translation vector
@@ -666,27 +666,27 @@ public class PolyhedronsSet extends AbstractRegion<Point3D, Point2D> {
 
         /** {@inheritDoc} */
         @Override
-        public Point3D apply(final Point3D point) {
-            return Point3D.vectorCombination(1.0, point, 1.0, translation);
+        public Vector3D apply(final Vector3D point) {
+            return Vector3D.linearCombination(1.0, point, 1.0, translation);
         }
 
         /** {@inheritDoc} */
         @Override
-        public Plane apply(final Hyperplane<Point3D> hyperplane) {
+        public Plane apply(final Hyperplane<Vector3D> hyperplane) {
             return ((Plane) hyperplane).translate(translation);
         }
 
         /** {@inheritDoc} */
         @Override
-        public SubHyperplane<Point2D> apply(final SubHyperplane<Point2D> sub,
-                                                final Hyperplane<Point3D> original,
-                                                final Hyperplane<Point3D> transformed) {
+        public SubHyperplane<Vector2D> apply(final SubHyperplane<Vector2D> sub,
+                                                final Hyperplane<Vector3D> original,
+                                                final Hyperplane<Vector3D> transformed) {
             if (original != cachedOriginal) {
                 // we have changed hyperplane, reset the in-hyperplane transform
 
                 final Plane   oPlane = (Plane) original;
                 final Plane   tPlane = (Plane) transformed;
-                final Point2D shift  = tPlane.toSubSpace(apply(oPlane.getOrigin()));
+                final Vector2D shift  = tPlane.toSubSpace(apply(oPlane.getOrigin()));
 
                 cachedOriginal  = (Plane) original;
                 cachedTransform =
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Segment.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Segment.java
index 93825d5..8823278 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Segment.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Segment.java
@@ -22,10 +22,10 @@ package org.apache.commons.geometry.euclidean.threed;
 public class Segment {
 
     /** Start point of the segment. */
-    private final Point3D start;
+    private final Vector3D start;
 
     /** End point of the segments. */
-    private final Point3D end;
+    private final Vector3D end;
 
     /** Line containing the segment. */
     private final Line     line;
@@ -35,7 +35,7 @@ public class Segment {
      * @param end end point of the segment
      * @param line line containing the segment
      */
-    public Segment(final Point3D start, final Point3D end, final Line line) {
+    public Segment(final Vector3D start, final Vector3D end, final Line line) {
         this.start  = start;
         this.end    = end;
         this.line   = line;
@@ -44,14 +44,14 @@ public class Segment {
     /** Get the start point of the segment.
      * @return start point of the segment
      */
-    public Point3D getStart() {
+    public Vector3D getStart() {
         return start;
     }
 
     /** Get the end point of the segment.
      * @return end point of the segment
      */
-    public Point3D getEnd() {
+    public Vector3D getEnd() {
         return end;
     }
 
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
index 9c244d0..fc419d2 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
@@ -146,14 +146,6 @@ public final class SphericalCoordinates implements Spatial, Serializable {
         return toCartesian(radius, azimuth, polar, Vector3D::of);
     }
 
-    /** Convert this set of spherical coordinates to a 3 dimensional point.
-    * @return A 3-dimensional point with an equivalent set of
-    *      coordinates.
-    */
-    public Point3D toPoint() {
-        return toCartesian(radius, azimuth, polar, Point3D::of);
-    }
-
     /** Get a hashCode for this set of spherical coordinates.
      * <p>All NaN values have the same hash code.</p>
      *
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubLine.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubLine.java
index b1721ab..823b6a7 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubLine.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubLine.java
@@ -22,7 +22,7 @@ import java.util.List;
 import org.apache.commons.geometry.core.partitioning.Region.Location;
 import org.apache.commons.geometry.euclidean.oned.Interval;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 
 /** This class represents a subset of a {@link Line}.
  */
@@ -49,7 +49,7 @@ public class SubLine {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if the points are equal
      */
-    public SubLine(final Point3D start, final Point3D end, final double tolerance)
+    public SubLine(final Vector3D start, final Vector3D end, final double tolerance)
         throws IllegalArgumentException {
         this(new Line(start, end, tolerance), buildIntervalSet(start, end, tolerance));
     }
@@ -83,8 +83,8 @@ public class SubLine {
         final List<Segment> segments = new ArrayList<>(list.size());
 
         for (final Interval interval : list) {
-            final Point3D start = line.toSpace(Point1D.of(interval.getInf()));
-            final Point3D end   = line.toSpace(Point1D.of(interval.getSup()));
+            final Vector3D start = line.toSpace(Vector1D.of(interval.getInf()));
+            final Vector3D end   = line.toSpace(Vector1D.of(interval.getSup()));
             segments.add(new Segment(start, end, line));
         }
 
@@ -106,10 +106,10 @@ public class SubLine {
      * 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 Point3D intersection(final SubLine subLine, final boolean includeEndPoints) {
+    public Vector3D intersection(final SubLine subLine, final boolean includeEndPoints) {
 
         // compute the intersection on infinite line
-        Point3D v1D = line.intersection(subLine.line);
+        Vector3D v1D = line.intersection(subLine.line);
         if (v1D == null) {
             return null;
         }
@@ -135,7 +135,7 @@ public class SubLine {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if the points are equal
      */
-    private static IntervalsSet buildIntervalSet(final Point3D start, final Point3D end, final double tolerance)
+    private static IntervalsSet buildIntervalSet(final Vector3D start, final Vector3D end, final double tolerance)
         throws IllegalArgumentException {
         final Line line = new Line(start, end, tolerance);
         return new IntervalsSet(line.toSubSpace(start).getX(),
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubPlane.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubPlane.java
index c2848b2..eece004 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubPlane.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SubPlane.java
@@ -21,27 +21,27 @@ import org.apache.commons.geometry.core.partitioning.BSPTree;
 import org.apache.commons.geometry.core.partitioning.Hyperplane;
 import org.apache.commons.geometry.core.partitioning.Region;
 import org.apache.commons.geometry.core.partitioning.SubHyperplane;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 
 /** This class represents a sub-hyperplane for {@link Plane}.
  */
-public class SubPlane extends AbstractSubHyperplane<Point3D, Point2D> {
+public class SubPlane extends AbstractSubHyperplane<Vector3D, Vector2D> {
 
     /** Simple constructor.
      * @param hyperplane underlying hyperplane
      * @param remainingRegion remaining region of the hyperplane
      */
-    public SubPlane(final Hyperplane<Point3D> hyperplane,
-                    final Region<Point2D> remainingRegion) {
+    public SubPlane(final Hyperplane<Vector3D> hyperplane,
+                    final Region<Vector2D> remainingRegion) {
         super(hyperplane, remainingRegion);
     }
 
     /** {@inheritDoc} */
     @Override
-    protected AbstractSubHyperplane<Point3D, Point2D> buildNew(final Hyperplane<Point3D> hyperplane,
-                                                                       final Region<Point2D> remainingRegion) {
+    protected AbstractSubHyperplane<Vector3D, Vector2D> buildNew(final Hyperplane<Vector3D> hyperplane,
+                                                                       final Region<Vector2D> remainingRegion) {
         return new SubPlane(hyperplane, remainingRegion);
     }
 
@@ -52,7 +52,7 @@ public class SubPlane extends AbstractSubHyperplane<Point3D, Point2D> {
      * instance on the minus side of the instance
      */
     @Override
-    public SplitSubHyperplane<Point3D> split(Hyperplane<Point3D> hyperplane) {
+    public SplitSubHyperplane<Vector3D> split(Hyperplane<Vector3D> hyperplane) {
 
         final Plane otherPlane = (Plane) hyperplane;
         final Plane thisPlane  = (Plane) getHyperplane();
@@ -72,28 +72,28 @@ public class SubPlane extends AbstractSubHyperplane<Point3D, Point2D> {
         }
 
         // the hyperplanes do intersect
-        Point2D p = thisPlane.toSubSpace(inter.toSpace(Point1D.ZERO));
-        Point2D q = thisPlane.toSubSpace(inter.toSpace(Point1D.ONE));
+        Vector2D p = thisPlane.toSubSpace(inter.toSpace(Vector1D.ZERO));
+        Vector2D q = thisPlane.toSubSpace(inter.toSpace(Vector1D.ONE));
         Vector3D crossP = inter.getDirection().crossProduct(thisPlane.getNormal());
         if (crossP.dotProduct(otherPlane.getNormal()) < 0) {
-            final Point2D tmp = p;
+            final Vector2D tmp = p;
             p           = q;
             q           = tmp;
         }
-        final SubHyperplane<Point2D> l2DMinus =
+        final SubHyperplane<Vector2D> l2DMinus =
             new org.apache.commons.geometry.euclidean.twod.Line(p, q, tolerance).wholeHyperplane();
-        final SubHyperplane<Point2D> l2DPlus =
+        final SubHyperplane<Vector2D> l2DPlus =
             new org.apache.commons.geometry.euclidean.twod.Line(q, p, tolerance).wholeHyperplane();
 
-        final BSPTree<Point2D> splitTree = getRemainingRegion().getTree(false).split(l2DMinus);
-        final BSPTree<Point2D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
-                                               new BSPTree<Point2D>(Boolean.FALSE) :
-                                               new BSPTree<>(l2DPlus, new BSPTree<Point2D>(Boolean.FALSE),
+        final BSPTree<Vector2D> splitTree = getRemainingRegion().getTree(false).split(l2DMinus);
+        final BSPTree<Vector2D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
+                                               new BSPTree<Vector2D>(Boolean.FALSE) :
+                                               new BSPTree<>(l2DPlus, new BSPTree<Vector2D>(Boolean.FALSE),
                                                                         splitTree.getPlus(), null);
 
-        final BSPTree<Point2D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
-                                               new BSPTree<Point2D>(Boolean.FALSE) :
-                                                   new BSPTree<>(l2DMinus, new BSPTree<Point2D>(Boolean.FALSE),
+        final BSPTree<Vector2D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
+                                               new BSPTree<Vector2D>(Boolean.FALSE) :
+                                                   new BSPTree<>(l2DMinus, new BSPTree<Vector2D>(Boolean.FALSE),
                                                                             splitTree.getMinus(), null);
 
         return new SplitSubHyperplane<>(new SubPlane(thisPlane.copySelf(), new PolygonsSet(plusTree, tolerance)),
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
index 252848d..674dd9f 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
@@ -27,7 +27,7 @@ import org.apache.commons.numbers.arrays.LinearCombination;
 /** This class represents a vector in three-dimensional Euclidean space.
  * Instances of this class are guaranteed to be immutable.
  */
-public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVector<Point3D, Vector3D> {
+public class Vector3D extends MultiDimensionalEuclideanVector<Vector3D> {
 
     /** Zero (null) vector (coordinates: 0, 0, 0). */
     public static final Vector3D ZERO   = new Vector3D(0, 0, 0);
@@ -66,6 +66,15 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     /** Serializable version identifier */
     private static final long serialVersionUID = 20180903L;
 
+    /** Abscissa (first coordinate value) */
+    private final double x;
+
+    /** Ordinate (second coordinate value) */
+    private final double y;
+
+    /** Height (third coordinate value)*/
+    private final double z;
+
     /** Simple constructor.
      * Build a vector from its coordinates
      * @param x abscissa
@@ -73,7 +82,62 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
      * @param z height
      */
     private Vector3D(double x, double y, double z) {
-        super(x, y, z);
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** Returns the abscissa (first coordinate) value of the instance.
+     * @return the abscisaa
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** Returns the ordinate (second coordinate) value of the instance.
+     * @return the ordinate
+     */
+    public double getY() {
+        return y;
+    }
+
+    /** Returns the height (third coordinate) value of the instance.
+     * @return the height
+     */
+    public double getZ() {
+        return z;
+    }
+
+    /** Get the coordinates for this instance as a dimension 3 array.
+     * @return the coordinates for this instance
+     */
+    public double[] toArray() {
+        return new double[] { x, y, z };
+    }
+
+    /** Return an equivalent set of coordinates in spherical form.
+     * @return an equivalent set of coordinates in spherical form.
+     */
+    public SphericalCoordinates toSpherical() {
+        return SphericalCoordinates.ofCartesian(x, y, z);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getDimension() {
+        return 3;
+    }
+
+    /** {@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));
     }
 
     /** {@inheritDoc} */
@@ -84,8 +148,17 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
 
     /** {@inheritDoc} */
     @Override
-    public Point3D asPoint() {
-        return Point3D.of(getX(), getY(), getZ());
+    public Vector3D vectorTo(Vector3D v) {
+        return v.subtract(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Vector3D directionTo(Vector3D v) {
+        return normalize(
+                v.x - x,
+                v.y - y,
+                v.z - z);
     }
 
     /** {@inheritDoc} */
@@ -97,13 +170,13 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     /** {@inheritDoc} */
     @Override
     public double getNorm() {
-        return Vectors.norm(getX(), getY(), getZ());
+        return Vectors.norm(x, y, z);
     }
 
     /** {@inheritDoc} */
     @Override
     public double getNormSq() {
-        return Vectors.normSq(getX(), getY(), getZ());
+        return Vectors.normSq(x, y, z);
     }
 
     /** {@inheritDoc} */
@@ -112,9 +185,9 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
         final double invNorm = 1.0 / getCheckedNorm();
 
         return new Vector3D(
-                    magnitude * getX() * invNorm,
-                    magnitude * getY() * invNorm,
-                    magnitude * getZ() * invNorm
+                    magnitude * x * invNorm,
+                    magnitude * y * invNorm,
+                    magnitude * z * invNorm
                 );
     }
 
@@ -122,9 +195,9 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     @Override
     public Vector3D add(Vector3D v) {
         return new Vector3D(
-                    getX() + v.getX(),
-                    getY() + v.getY(),
-                    getZ() + v.getZ()
+                    x + v.x,
+                    y + v.y,
+                    z + v.z
                 );
     }
 
@@ -132,9 +205,9 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     @Override
     public Vector3D add(double factor, Vector3D v) {
         return new Vector3D(
-                    getX() + (factor * v.getX()),
-                    getY() + (factor * v.getY()),
-                    getZ() + (factor * v.getZ())
+                    x + (factor * v.x),
+                    y + (factor * v.y),
+                    z + (factor * v.z)
                 );
     }
 
@@ -142,9 +215,9 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     @Override
     public Vector3D subtract(Vector3D v) {
         return new Vector3D(
-                    getX() - v.getX(),
-                    getY() - v.getY(),
-                    getZ() - v.getZ()
+                    x - v.x,
+                    y - v.y,
+                    z - v.z
                 );
     }
 
@@ -152,37 +225,37 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     @Override
     public Vector3D subtract(double factor, Vector3D v) {
         return new Vector3D(
-                    getX() - (factor * v.getX()),
-                    getY() - (factor * v.getY()),
-                    getZ() - (factor * v.getZ())
+                    x - (factor * v.x),
+                    y - (factor * v.y),
+                    z - (factor * v.z)
                 );
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector3D negate() {
-        return new Vector3D(-getX(), -getY(), -getZ());
+        return new Vector3D(-x, -y, -z);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector3D normalize() {
-        return normalize(getX(), getY(), getZ());
+        return normalize(x, y, z);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector3D scalarMultiply(double a) {
-        return new Vector3D(a * getX(), a * getY(), a * getZ());
+        return new Vector3D(a * x, a * y, a * z);
     }
 
     /** {@inheritDoc} */
     @Override
     public double distance(Vector3D v) {
         return Vectors.norm(
-                getX() - v.getX(),
-                getY() - v.getY(),
-                getZ() - v.getZ()
+                x - v.x,
+                y - v.y,
+                z - v.z
             );
     }
 
@@ -190,9 +263,9 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     @Override
     public double distanceSq(Vector3D v) {
         return Vectors.normSq(
-                getX() - v.getX(),
-                getY() - v.getY(),
-                getZ() - v.getZ()
+                x - v.x,
+                y - v.y,
+                z - v.z
             );
     }
 
@@ -206,7 +279,7 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
      */
     @Override
     public double dotProduct(Vector3D v) {
-        return LinearCombination.value(getX(), v.getX(), getY(), v.getY(), getZ(), v.getZ());
+        return LinearCombination.value(x, v.x, y, v.y, z, v.z);
     }
 
     /** {@inheritDoc}
@@ -267,10 +340,6 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     public Vector3D orthogonal() {
         double threshold = 0.6 * getCheckedNorm();
 
-        final double x = getX();
-        final double y = getY();
-        final double z = getZ();
-
         if (Math.abs(x) <= threshold) {
             double inverse  = 1 / Math.sqrt(y * y + z * z);
             return new Vector3D(0, inverse * z, -inverse * y);
@@ -290,12 +359,12 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
 
     /** Compute the cross-product of the instance with another vector.
      * @param v other vector
-     * @return the cross product this ^ v as a new Cartesian3D
+     * @return the cross product this ^ v as a new Vector3D
      */
     public Vector3D crossProduct(final Vector3D v) {
-        return new Vector3D(LinearCombination.value(getY(), v.getZ(), -getZ(), v.getY()),
-                            LinearCombination.value(getZ(), v.getX(), -getX(), v.getZ()),
-                            LinearCombination.value(getX(), v.getY(), -getY(), v.getX()));
+        return new Vector3D(LinearCombination.value(y, v.z, -z, v.y),
+                            LinearCombination.value(z, v.x, -x, v.z),
+                            LinearCombination.value(x, v.y, -y, v.x));
     }
 
     /**
@@ -309,7 +378,7 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
         if (isNaN()) {
             return 642;
         }
-        return 643 * (164 * Double.hashCode(getX()) +  3 * Double.hashCode(getY()) +  Double.hashCode(getZ()));
+        return 643 * (164 * Double.hashCode(x) +  3 * Double.hashCode(y) +  Double.hashCode(z));
     }
 
     /**
@@ -343,11 +412,17 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
                 return this.isNaN();
             }
 
-            return (getX() == rhs.getX()) && (getY() == rhs.getY()) && (getZ() == rhs.getZ());
+            return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
         }
         return false;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return SimpleTupleFormat.getDefault().format(x, y, z);
+    }
+
     /** Returns a component of the current instance relative to the given base
      * vector. If {@code reject} is true, the vector rejection is returned; otherwise,
      * the projection is returned.
@@ -373,26 +448,17 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
 
         final double scale = aDotB / baseMagSq;
 
-        final double projX = scale * base.getX();
-        final double projY = scale * base.getY();
-        final double projZ = scale * base.getZ();
+        final double projX = scale * base.x;
+        final double projY = scale * base.y;
+        final double projZ = scale * base.z;
 
         if (reject) {
-            return factory.apply(getX() - projX, getY() - projY, getZ() - projZ);
+            return factory.apply(x - projX, y - projY, z - projZ);
         }
 
         return factory.apply(projX, projY, projZ);
     }
 
-    /** Returns the vector norm value, throwing an {@link IllegalNormException} if the value
-     * is not real (ie, NaN or infinite) or zero.
-     * @return the vector norm value, guaranteed to be real and non-zero
-     * @throws IllegalNormException if the vector norm is zero, NaN, or infinite
-     */
-    private double getCheckedNorm() {
-        return Vectors.checkedNorm(getNorm());
-    }
-
     /** Returns a vector with the given coordinate values.
      * @param x abscissa (first coordinate value)
      * @param y abscissa (second coordinate value)
@@ -453,88 +519,80 @@ public class Vector3D extends Cartesian3D implements MultiDimensionalEuclideanVe
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a scale factor for first coordinate
      * @param c first coordinate
      * @return vector with coordinates calculated by {@code a * c}
      */
-    public static Vector3D linearCombination(double a, Cartesian3D c) {
-        return new Vector3D(a * c.getX(), a * c.getY(), a * c.getZ());
+    public static Vector3D linearCombination(double a, Vector3D c) {
+        return new Vector3D(a * c.x, a * c.y, a * c.z);
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
+     * @param v2 second coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2)}
      */
-    public static Vector3D linearCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2) {
+    public static Vector3D linearCombination(double a1, Vector3D v1, double a2, Vector3D v2) {
         return new Vector3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ()));
+                LinearCombination.value(a1, v1.x, a2, v2.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y),
+                LinearCombination.value(a1, v1.z, a2, v2.z));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
+     * @param v3 third coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3)}
      */
-    public static Vector3D linearCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2,
-            double a3, Cartesian3D c3) {
+    public static Vector3D linearCombination(double a1, Vector3D v1, double a2, Vector3D v2,
+            double a3, Vector3D v3) {
         return new Vector3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ(), a3, c3.getZ()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y, a3, v3.y),
+                LinearCombination.value(a1, v1.z, a2, v2.z, a3, v3.z));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
+     * @param v3 third coordinate
      * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
+     * @param v4 fourth coordinate
+     * @return point with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3) + (a4 * v4)}
      */
-    public static Vector3D linearCombination(double a1, Cartesian3D c1, double a2, Cartesian3D c2,
-            double a3, Cartesian3D c3, double a4, Cartesian3D c4) {
+    public static Vector3D linearCombination(double a1, Vector3D v1, double a2, Vector3D v2,
+            double a3, Vector3D v3, double a4, Vector3D v4) {
         return new Vector3D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY(), a4, c4.getY()),
-                LinearCombination.value(a1, c1.getZ(), a2, c2.getZ(), a3, c3.getZ(), a4, c4.getZ()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x, a4, v4.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y, a3, v3.y, a4, v4.y),
+                LinearCombination.value(a1, v1.z, a2, v2.z, a3, v3.z, a4, v4.z));
     }
 
     /** Private class used to represent unit vectors. This allows optimizations to be performed for certain
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Cartesian2D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Cartesian2D.java
deleted file mode 100644
index a4b48a9..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Cartesian2D.java
+++ /dev/null
@@ -1,100 +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.geometry.euclidean.twod;
-
-import java.io.Serializable;
-
-import org.apache.commons.geometry.core.Spatial;
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-
-/** This class represents a set of Cartesian coordinates in
- * two-dimensional Euclidean space.
- */
-public abstract class Cartesian2D implements Spatial, Serializable {
-
-    /** Serializable UID */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Abscissa (first coordinate) */
-    private final double x;
-
-    /** Ordinate (second coordinate) */
-    private final double y;
-
-    /**
-     * Simple Cartesian constructor.
-     * @param x abscissa (first coordinate)
-     * @param y ordinate (second coordinate)
-     */
-    protected Cartesian2D(double x, double y) {
-        this.x = x;
-        this.y = y;
-    }
-
-    /** Returns the abscissa (first coordinate value) of the instance.
-     * @return the abscissa
-     */
-    public double getX() {
-        return x;
-    }
-
-    /** Returns the ordinate (second coordinate value) of the instance.
-     * @return the ordinate
-     */
-    public double getY() {
-        return y;
-    }
-
-    /** Return an equivalent set of coordinates in polar form.
-     * @return An equivalent set of coordinates in polar form.
-     */
-    public PolarCoordinates toPolar() {
-        return PolarCoordinates.ofCartesian(x, y);
-    }
-
-    /** Get the coordinates for this instance as a dimension 2 array.
-     * @return coordinates for this instance
-     */
-    public double[] toArray() {
-        return new double[] { x, y };
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getDimension() {
-        return 2;
-    }
-
-    /** {@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 String toString() {
-        return SimpleTupleFormat.getDefault().format(getX(), getY());
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java
index c5a5394..357d6ee 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Line.java
@@ -22,7 +22,7 @@ import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 import org.apache.commons.geometry.core.partitioning.Transform;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
 import org.apache.commons.geometry.euclidean.oned.OrientedPoint;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 import org.apache.commons.numbers.angle.PlaneAngleRadians;
 import org.apache.commons.numbers.arrays.LinearCombination;
 
@@ -50,7 +50,7 @@ import org.apache.commons.numbers.arrays.LinearCombination;
  * 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>
  */
-public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
+public class Line implements Hyperplane<Vector2D>, Embedding<Vector2D, Vector1D> {
     /** Angle with respect to the abscissa axis. */
     private double angle;
 
@@ -75,7 +75,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param p2 second point
      * @param tolerance tolerance below which points are considered identical
      */
-    public Line(final Point2D p1, final Point2D p2, final double tolerance) {
+    public Line(final Vector2D p1, final Vector2D p2, final double tolerance) {
         reset(p1, p2);
         this.tolerance = tolerance;
     }
@@ -85,7 +85,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param angle angle of the line with respect to abscissa axis
      * @param tolerance tolerance below which points are considered identical
      */
-    public Line(final Point2D p, final double angle, final double tolerance) {
+    public Line(final Vector2D p, final double angle, final double tolerance) {
         reset(p, angle);
         this.tolerance = tolerance;
     }
@@ -132,7 +132,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param p1 first point
      * @param p2 second point
      */
-    public void reset(final Point2D p1, final Point2D p2) {
+    public void reset(final Vector2D p1, final Vector2D p2) {
         unlinkReverse();
         final double dx = p2.getX() - p1.getX();
         final double dy = p2.getY() - p1.getY();
@@ -154,7 +154,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param p point belonging to the line
      * @param alpha angle of the line with respect to abscissa axis
      */
-    public void reset(final Point2D p, final double alpha) {
+    public void reset(final Vector2D p, final double alpha) {
         unlinkReverse();
         this.angle   = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(alpha);
         cos          = Math.cos(this.angle);
@@ -190,8 +190,8 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * instance.</p>
      * <p>
      * As long as neither the instance nor its reverse are modified
-     * (i.e. as long as none of the {@link #reset(Point2D, Point2D)},
-     * {@link #reset(Point2D, double)}, {@link #revertSelf()},
+     * (i.e. as long as none of the {@link #reset(Vector2D, Vector2D)},
+     * {@link #reset(Vector2D, 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}.
@@ -211,15 +211,15 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    public Point1D toSubSpace(final Point2D point) {
-        return Point1D.of(LinearCombination.value(cos, point.getX(), sin, point.getY()));
+    public Vector1D toSubSpace(final Vector2D point) {
+        return Vector1D.of(LinearCombination.value(cos, point.getX(), sin, point.getY()));
     }
 
     /** {@inheritDoc} */
     @Override
-    public Point2D toSpace(final Point1D point) {
+    public Vector2D toSpace(final Vector1D point) {
         final double abscissa = point.getX();
-        return Point2D.of(LinearCombination.value(abscissa, cos, -originOffset, sin),
+        return Vector2D.of(LinearCombination.value(abscissa, cos, -originOffset, sin),
                             LinearCombination.value(abscissa, sin,  originOffset, cos));
     }
 
@@ -228,18 +228,18 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @return intersection point of the instance and the other line
      * or null if there are no intersection points
      */
-    public Point2D intersection(final Line other) {
+    public Vector2D intersection(final Line other) {
         final double d = LinearCombination.value(sin, other.cos, -other.sin, cos);
         if (Math.abs(d) < tolerance) {
             return null;
         }
-        return Point2D.of(LinearCombination.value(cos, other.originOffset, -other.cos, originOffset) / d,
+        return Vector2D.of(LinearCombination.value(cos, other.originOffset, -other.cos, originOffset) / d,
                             LinearCombination.value(sin, other.originOffset, -other.sin, originOffset) / d);
     }
 
     /** {@inheritDoc} */
     @Override
-    public Point2D project(Point2D point) {
+    public Vector2D project(Vector2D point) {
         return toSpace(toSubSpace(point));
     }
 
@@ -281,13 +281,13 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    public double getOffset(final Point2D point) {
+    public double getOffset(final Vector2D point) {
         return LinearCombination.value(sin, point.getX(), -cos, point.getY(), 1.0, originOffset);
     }
 
     /** {@inheritDoc} */
     @Override
-    public boolean sameOrientationAs(final Hyperplane<Point2D> other) {
+    public boolean sameOrientationAs(final Hyperplane<Vector2D> other) {
         final Line otherL = (Line) other;
         return LinearCombination.value(sin, otherL.sin, cos, otherL.cos) >= 0.0;
     }
@@ -298,10 +298,10 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @return one point in the plane, with given abscissa and offset
      * relative to the line
      */
-    public Point2D getPointAt(final Point1D abscissa, final double offset) {
+    public Vector2D getPointAt(final Vector1D abscissa, final double offset) {
         final double x       = abscissa.getX();
         final double dOffset = offset - originOffset;
-        return Point2D.of(LinearCombination.value(x, cos,  dOffset, sin),
+        return Vector2D.of(LinearCombination.value(x, cos,  dOffset, sin),
                             LinearCombination.value(x, sin, -dOffset, cos));
     }
 
@@ -309,7 +309,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param p point to check
      * @return true if p belongs to the line
      */
-    public boolean contains(final Point2D p) {
+    public boolean contains(final Vector2D p) {
         return Math.abs(getOffset(p)) < tolerance;
     }
 
@@ -321,7 +321,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @param p to check
      * @return distance between the instance and the point
      */
-    public double distance(final Point2D p) {
+    public double distance(final Vector2D p) {
         return Math.abs(getOffset(p));
     }
 
@@ -337,7 +337,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
     /** Translate the line to force it passing by a point.
      * @param p point by which the line should pass
      */
-    public void translateToPoint(final Point2D p) {
+    public void translateToPoint(final Vector2D p) {
         originOffset = LinearCombination.value(cos, p.getY(), -sin, p.getX());
     }
 
@@ -382,12 +382,12 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * @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
-     * Point2D}, {@link Line Line} or {@link
+     * Vector2D}, {@link Line Line} or {@link
      * org.apache.commons.geometry.core.partitioning.SubHyperplane
      * SubHyperplane} instances
      * @exception IllegalArgumentException if the transform is non invertible
      */
-    public static Transform<Point2D, Point1D> getTransform(final double cXX,
+    public static Transform<Vector2D, Vector1D> getTransform(final double cXX,
                                                                    final double cYX,
                                                                    final double cXY,
                                                                    final double cYY,
@@ -404,7 +404,7 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
      * applied to a large number of lines (for example to a large
      * polygon)./<p>
      */
-    private static class LineTransform implements Transform<Point2D, Point1D> {
+    private static class LineTransform implements Transform<Vector2D, Vector1D> {
 
         /** Transform factor between input abscissa and output abscissa. */
         private final double cXX;
@@ -465,16 +465,16 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
 
         /** {@inheritDoc} */
         @Override
-        public Point2D apply(final Point2D point) {
+        public Vector2D apply(final Vector2D point) {
             final double  x   = point.getX();
             final double  y   = point.getY();
-            return Point2D.of(LinearCombination.value(cXX, x, cXY, y, cX1, 1),
+            return Vector2D.of(LinearCombination.value(cXX, x, cXY, y, cX1, 1),
                                 LinearCombination.value(cYX, x, cYY, y, cY1, 1));
         }
 
         /** {@inheritDoc} */
         @Override
-        public Line apply(final Hyperplane<Point2D> hyperplane) {
+        public Line apply(final Hyperplane<Vector2D> hyperplane) {
             final Line   line    = (Line) hyperplane;
             final double rOffset = LinearCombination.value(c1X, line.cos, c1Y, line.sin, c11, line.originOffset);
             final double rCos    = LinearCombination.value(cXX, line.cos, cXY, line.sin);
@@ -487,13 +487,13 @@ public class Line implements Hyperplane<Point2D>, Embedding<Point2D, Point1D> {
 
         /** {@inheritDoc} */
         @Override
-        public SubHyperplane<Point1D> apply(final SubHyperplane<Point1D> sub,
-                                                final Hyperplane<Point2D> original,
-                                                final Hyperplane<Point2D> transformed) {
+        public SubHyperplane<Vector1D> apply(final SubHyperplane<Vector1D> sub,
+                                                final Hyperplane<Vector2D> original,
+                                                final Hyperplane<Vector2D> transformed) {
             final OrientedPoint op     = (OrientedPoint) sub.getHyperplane();
             final Line originalLine    = (Line) original;
             final Line transformedLine = (Line) transformed;
-            final Point1D newLoc =
+            final Vector1D newLoc =
                 transformedLine.toSubSpace(apply(originalLine.toSpace(op.getLocation())));
             return new OrientedPoint(newLoc, op.isDirect(), originalLine.tolerance).wholeHyperplane();
         }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/NestedLoops.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/NestedLoops.java
index 4ee2a7c..82db8d8 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/NestedLoops.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/NestedLoops.java
@@ -43,13 +43,13 @@ import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
 class NestedLoops {
 
     /** Boundary loop. */
-    private Point2D[] loop;
+    private Vector2D[] loop;
 
     /** Surrounded loops. */
     private List<NestedLoops> surrounded;
 
     /** Polygon enclosing a finite region. */
-    private Region<Point2D> polygon;
+    private Region<Vector2D> polygon;
 
     /** Indicator for original loop orientation. */
     private boolean originalIsClockwise;
@@ -75,7 +75,7 @@ class NestedLoops {
      * @param tolerance tolerance below which points are considered identical
      * @exception IllegalArgumentException if an outline has an open boundary loop
      */
-    private NestedLoops(final Point2D[] loop, final double tolerance)
+    private NestedLoops(final Vector2D[] loop, final double tolerance)
         throws IllegalArgumentException {
 
         if (loop[0] == null) {
@@ -87,10 +87,10 @@ class NestedLoops {
         this.tolerance  = tolerance;
 
         // build the polygon defined by the loop
-        final ArrayList<SubHyperplane<Point2D>> edges = new ArrayList<>();
-        Point2D current = loop[loop.length - 1];
+        final ArrayList<SubHyperplane<Vector2D>> edges = new ArrayList<>();
+        Vector2D current = loop[loop.length - 1];
         for (int i = 0; i < loop.length; ++i) {
-            final Point2D previous = current;
+            final Vector2D previous = current;
             current = loop[i];
             final Line   line   = new Line(previous, current, tolerance);
             final IntervalsSet region =
@@ -103,7 +103,7 @@ class NestedLoops {
 
         // ensure the polygon encloses a finite region of the plane
         if (Double.isInfinite(polygon.getSize())) {
-            polygon = new RegionFactory<Point2D>().getComplement(polygon);
+            polygon = new RegionFactory<Vector2D>().getComplement(polygon);
             originalIsClockwise = false;
         } else {
             originalIsClockwise = true;
@@ -116,7 +116,7 @@ class NestedLoops {
      * @exception IllegalArgumentException if an outline has crossing
      * boundary loops or open boundary loops
      */
-    public void add(final Point2D[] bLoop) {
+    public void add(final Vector2D[] bLoop) {
         add(new NestedLoops(bLoop, tolerance));
     }
 
@@ -145,7 +145,7 @@ class NestedLoops {
         }
 
         // we should be separate from the remaining children
-        RegionFactory<Point2D> factory = new RegionFactory<>();
+        RegionFactory<Vector2D> factory = new RegionFactory<>();
         for (final NestedLoops child : surrounded) {
             if (!factory.intersection(node.polygon, child.polygon).isEmpty()) {
                 throw new IllegalArgumentException("Some outline boundary loops cross each other");
@@ -158,7 +158,7 @@ class NestedLoops {
 
     /** Correct the orientation of the loops contained in the tree.
      * <p>This is this method that really inverts the loops that where
-     * provided through the {@link #add(Point2D[]) add} method if
+     * provided through the {@link #add(Vector2D[]) add} method if
      * they are mis-oriented</p>
      */
     public void correctOrientation() {
@@ -178,7 +178,7 @@ class NestedLoops {
             int min = -1;
             int max = loop.length;
             while (++min < --max) {
-                final Point2D tmp = loop[min];
+                final Vector2D tmp = loop[min];
                 loop[min] = loop[max];
                 loop[max] = tmp;
             }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Point2D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Point2D.java
deleted file mode 100644
index ddd707e..0000000
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Point2D.java
+++ /dev/null
@@ -1,298 +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.geometry.euclidean.twod;
-
-import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
-import org.apache.commons.geometry.euclidean.EuclideanPoint;
-import org.apache.commons.geometry.euclidean.internal.Vectors;
-import org.apache.commons.numbers.arrays.LinearCombination;
-
-/** This class represents a point in two-dimensional Euclidean space.
- * Instances of this class are guaranteed to be immutable.
- */
-public final class Point2D extends Cartesian2D implements EuclideanPoint<Point2D, Vector2D> {
-
-    /** Origin (coordinates: 0, 0). */
-    public static final Point2D ZERO   = new Point2D(0, 0);
-
- // CHECKSTYLE: stop ConstantName
-    /** A point with all coordinates set to NaN. */
-    public static final Point2D NaN = new Point2D(Double.NaN, Double.NaN);
-    // CHECKSTYLE: resume ConstantName
-
-    /** A point with all coordinates set to positive infinity. */
-    public static final Point2D POSITIVE_INFINITY =
-        new Point2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-
-    /** A point with all coordinates set to negative infinity. */
-    public static final Point2D NEGATIVE_INFINITY =
-        new Point2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20180710L;
-
-    /** Simple constructor.
-     * Build a point from its coordinates
-     * @param x abscissa
-     * @param y ordinate
-     */
-    private Point2D(double x, double y) {
-        super(x, y);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector2D asVector() {
-        return Vector2D.of(getX(), getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public double distance(Point2D p) {
-        return Vectors.norm(getX() - p.getX(), getY() - p.getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector2D subtract(Point2D p) {
-        return Vector2D.of(getX() - p.getX(), getY() - p.getY());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector2D vectorTo(Point2D p) {
-        return p.subtract(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Vector2D directionTo(Point2D p) {
-        return Vector2D.normalize(
-                    p.getX() - getX(),
-                    p.getY() - getY()
-                );
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point2D lerp(Point2D p, double t) {
-        return vectorCombination(1.0 - t, this, t, p);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Point2D add(Vector2D v) {
-        return new Point2D(getX() + v.getX(), getY() + v.getY());
-    }
-
-    /**
-     * Get a hashCode for this point.
-     * <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 * Double.hashCode(getX()) +  Double.hashCode(getY()));
-    }
-
-    /** Test for the equality of two points.
-     * <p>
-     * If all coordinates of two points are exactly the same, and none are
-     * <code>Double.NaN</code>, the two points are considered to be equal.
-     * </p>
-     * <p>
-     * <code>NaN</code> coordinates are considered to globally affect the point
-     * and be equal to each other - i.e, if either (or all) coordinates of the
-     * point are equal to <code>Double.NaN</code>, the point is equal to
-     * {@link #NaN}.
-     * </p>
-     *
-     * @param other Object to test for equality to this
-     * @return true if two Point2D objects are equal, false if
-     *         object is null, not an instance of Point2D, or
-     *         not equal to this Point2D instance
-     *
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        if (other instanceof Point2D) {
-            final Point2D rhs = (Point2D) other;
-            if (rhs.isNaN()) {
-                return this.isNaN();
-            }
-
-            return (getX() == rhs.getX()) && (getY() == rhs.getY());
-        }
-        return false;
-    }
-
-    /** Returns a point with the given coordinate values
-     * @param x abscissa (first coordinate value)
-     * @param y ordinate (second coordinate value)
-     * @return point instance
-     */
-    public static Point2D of(double x, double y) {
-        return new Point2D(x, y);
-    }
-
-    /** Returns a point with the coordinates from the given 2-element array.
-     * @param p coordinates array
-     * @return new point
-     * @exception IllegalArgumentException if the array does not have 2 elements
-     */
-    public static Point2D ofArray(double[] p) {
-        if (p.length != 2) {
-            throw new IllegalArgumentException("Dimension mismatch: " + p.length + " != 2");
-        }
-        return new Point2D(p[0], p[1]);
-    }
-
-    /**Return a point with coordinates equivalent to the given set of polar coordinates.
-     * @param radius The polar coordinate radius value.
-     * @param azimuth The polar coordinate azimuth angle in radians.
-     * @return point instance with coordinates equivalent to the given polar coordinates.
-     */
-    public static Point2D ofPolar(final double radius, final double azimuth) {
-        return PolarCoordinates.toCartesian(radius, azimuth, Point2D::new);
-    }
-
-    /** Parses the given string and returns a new point instance. The expected string
-     * format is the same as that returned by {@link #toString()}.
-     * @param str the string to parse
-     * @return point instance represented by the string
-     * @throws IllegalArgumentException if the given string has an invalid format
-     */
-    public static Point2D parse(String str) {
-        return SimpleTupleFormat.getDefault().parse(str, Point2D::new);
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a scale factor for first coordinate
-     * @param c first coordinate
-     * @return point with coordinates calculated by {@code a * c}
-     */
-    public static Point2D vectorCombination(double a, Cartesian2D c) {
-        return new Point2D(a * c.getX(), a * c.getY());
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
-     */
-    public static Point2D vectorCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2) {
-        return new Point2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
-     */
-    public static Point2D vectorCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2,
-            double a3, Cartesian2D c3) {
-        return new Point2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY()));
-    }
-
-    /** Returns a point with coordinates calculated by multiplying each input coordinate
-     * with its corresponding factor and adding the results.
-     *
-     * <p>This is equivalent
-     * to converting all input coordinates to vectors, scaling and adding the
-     * vectors (a linear combination), and adding the result to the zero point.
-     * This method, however, does not create any intermediate objects.
-     * </p>
-     * <p>
-     * The name of this method was chosen to emphasize the fact that the operation
-     * should be viewed as occurring in vector space, since addition and scalar
-     * multiplication are not defined directly for points.
-     * </p>
-     *
-     * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
-     * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
-     */
-    public static Point2D vectorCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2,
-            double a3, Cartesian2D c3, double a4, Cartesian2D c4) {
-        return new Point2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY(), a4, c4.getY()));
-    }
-}
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
index cdf5b5b..ee63d93 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
@@ -118,15 +118,6 @@ public final class PolarCoordinates implements Spatial, Serializable {
         return toCartesian(radius, azimuth, Vector2D::of);
     }
 
-    /** Convert this set of polar coordinates to a 2-dimensional
-     * point.
-     * @return A 2-dimensional point with an equivalent set of
-     *      coordinates.
-     */
-    public Point2D toPoint() {
-        return toCartesian(radius, azimuth, Point2D::of);
-    }
-
     /** Get a hashCode for this set of polar coordinates.
      * <p>All NaN values have the same hash code.</p>
      *
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolygonsSet.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolygonsSet.java
index e7ffbeb..a5cea50 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolygonsSet.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolygonsSet.java
@@ -30,15 +30,15 @@ import org.apache.commons.geometry.core.partitioning.Side;
 import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 import org.apache.commons.geometry.euclidean.oned.Interval;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 import org.apache.commons.numbers.core.Precision;
 
 /** This class represents a 2D region: a set of polygons.
  */
-public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
+public class PolygonsSet extends AbstractRegion<Vector2D, Vector1D> {
 
     /** Vertices organized as boundary loops. */
-    private Point2D[][] vertices;
+    private Vector2D[][] vertices;
 
     /** Build a polygons set representing the whole plane.
      * @param tolerance tolerance below which points are considered identical
@@ -67,7 +67,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * @param tree inside/outside BSP tree representing the region
      * @param tolerance tolerance below which points are considered identical
      */
-    public PolygonsSet(final BSPTree<Point2D> tree, final double tolerance) {
+    public PolygonsSet(final BSPTree<Vector2D> tree, final double tolerance) {
         super(tree, tolerance);
     }
 
@@ -92,7 +92,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * collection of {@link SubHyperplane SubHyperplane} objects
      * @param tolerance tolerance below which points are considered identical
      */
-    public PolygonsSet(final Collection<SubHyperplane<Point2D>> boundary, final double tolerance) {
+    public PolygonsSet(final Collection<SubHyperplane<Vector2D>> boundary, final double tolerance) {
         super(boundary, tolerance);
     }
 
@@ -139,7 +139,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * belong to the hyperplane (which is therefore more a slab)
      * @param vertices vertices of the simple loop boundary
      */
-    public PolygonsSet(final double hyperplaneThickness, final Point2D ... vertices) {
+    public PolygonsSet(final double hyperplaneThickness, final Vector2D ... vertices) {
         super(verticesToTree(hyperplaneThickness, vertices), hyperplaneThickness);
     }
 
@@ -158,10 +158,10 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
             // too thin box, build an empty polygons set
             return null;
         }
-        final Point2D minMin = Point2D.of(xMin, yMin);
-        final Point2D minMax = Point2D.of(xMin, yMax);
-        final Point2D maxMin = Point2D.of(xMax, yMin);
-        final Point2D maxMax = Point2D.of(xMax, yMax);
+        final Vector2D minMin = Vector2D.of(xMin, yMin);
+        final Vector2D minMax = Vector2D.of(xMin, yMax);
+        final Vector2D maxMin = Vector2D.of(xMax, yMin);
+        final Vector2D maxMax = Vector2D.of(xMax, yMax);
         return new Line[] {
             new Line(minMin, maxMin, tolerance),
             new Line(maxMin, maxMax, tolerance),
@@ -185,8 +185,8 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * @param vertices vertices of the simple loop boundary
      * @return the BSP tree of the input vertices
      */
-    private static BSPTree<Point2D> verticesToTree(final double hyperplaneThickness,
-                                                       final Point2D ... vertices) {
+    private static BSPTree<Vector2D> verticesToTree(final double hyperplaneThickness,
+                                                       final Vector2D ... vertices) {
 
         final int n = vertices.length;
         if (n == 0) {
@@ -230,7 +230,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         }
 
         // build the tree top-down
-        final BSPTree<Point2D> tree = new BSPTree<>();
+        final BSPTree<Vector2D> tree = new BSPTree<>();
         insertEdges(hyperplaneThickness, tree, edges);
 
         return tree;
@@ -246,7 +246,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * (excluding edges not belonging to the cell defined by this node)
      */
     private static void insertEdges(final double hyperplaneThickness,
-                                    final BSPTree<Point2D> node,
+                                    final BSPTree<Vector2D> node,
                                     final List<Edge> edges) {
 
         // find an edge with an hyperplane that can be inserted in the node
@@ -268,7 +268,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         if (inserted == null) {
             // no suitable edge was found, the node remains a leaf node
             // we need to set its inside/outside boolean indicator
-            final BSPTree<Point2D> parent = node.getParent();
+            final BSPTree<Vector2D> parent = node.getParent();
             if (parent == null || node == parent.getMinus()) {
                 node.setAttribute(Boolean.TRUE);
             } else {
@@ -339,7 +339,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
     private static class Vertex {
 
         /** Vertex location. */
-        private final Point2D location;
+        private final Vector2D location;
 
         /** Incoming edge. */
         private Edge incoming;
@@ -353,7 +353,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         /** Build a non-processed vertex not owned by any node yet.
          * @param location vertex location
          */
-        Vertex(final Point2D location) {
+        Vertex(final Vector2D location) {
             this.location = location;
             this.incoming = null;
             this.outgoing = null;
@@ -363,7 +363,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         /** Get Vertex location.
          * @return vertex location
          */
-        public Point2D getLocation() {
+        public Vector2D getLocation() {
             return location;
         }
 
@@ -448,7 +448,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         private final Line line;
 
         /** Node whose cut hyperplane contains this edge. */
-        private BSPTree<Point2D> node;
+        private BSPTree<Vector2D> node;
 
         /** Build an edge not contained in any node yet.
          * @param start start vertex
@@ -492,7 +492,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         /** Set the node whose cut hyperplane contains this edge.
          * @param node node whose cut hyperplane contains this edge
          */
-        public void setNode(final BSPTree<Point2D> node) {
+        public void setNode(final BSPTree<Vector2D> node) {
             this.node = node;
         }
 
@@ -500,7 +500,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
          * @return node whose cut hyperplane contains this edge
          * (null if edge has not yet been inserted into the BSP tree)
          */
-        public BSPTree<Point2D> getNode() {
+        public BSPTree<Vector2D> getNode() {
             return node;
         }
 
@@ -527,7 +527,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    public PolygonsSet buildNew(final BSPTree<Point2D> tree) {
+    public PolygonsSet buildNew(final BSPTree<Vector2D> tree) {
         return new PolygonsSet(tree, getTolerance());
     }
 
@@ -535,22 +535,22 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
     @Override
     protected void computeGeometricalProperties() {
 
-        final Point2D[][] v = getVertices();
+        final Vector2D[][] v = getVertices();
 
         if (v.length == 0) {
-            final BSPTree<Point2D> tree = getTree(false);
+            final BSPTree<Vector2D> tree = getTree(false);
             if (tree.getCut() == null && (Boolean) tree.getAttribute()) {
                 // the instance covers the whole space
                 setSize(Double.POSITIVE_INFINITY);
-                setBarycenter(Point2D.NaN);
+                setBarycenter(Vector2D.NaN);
             } else {
                 setSize(0);
-                setBarycenter(Point2D.NaN);
+                setBarycenter(Vector2D.NaN);
             }
         } else if (v[0][0] == null) {
             // there is at least one open-loop: the polygon is infinite
             setSize(Double.POSITIVE_INFINITY);
-            setBarycenter(Point2D.NaN);
+            setBarycenter(Vector2D.NaN);
         } else {
             // all loops are closed, we compute some integrals around the shape
 
@@ -558,10 +558,10 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
             double sumX = 0;
             double sumY = 0;
 
-            for (Point2D[] loop : v) {
+            for (Vector2D[] loop : v) {
                 double x1 = loop[loop.length - 1].getX();
                 double y1 = loop[loop.length - 1].getY();
-                for (final Point2D point : loop) {
+                for (final Vector2D point : loop) {
                     final double x0 = x1;
                     final double y0 = y1;
                     x1 = point.getX();
@@ -576,10 +576,10 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
             if (sum < 0) {
                 // the polygon as a finite outside surrounded by an infinite inside
                 setSize(Double.POSITIVE_INFINITY);
-                setBarycenter(Point2D.NaN);
+                setBarycenter(Vector2D.NaN);
             } else {
                 setSize(sum / 2);
-                setBarycenter(Point2D.of(sumX / (3 * sum), sumY / (3 * sum)));
+                setBarycenter(Vector2D.of(sumX / (3 * sum), sumY / (3 * sum)));
             }
 
         }
@@ -609,10 +609,10 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
      * loops with the open loops first (the returned value is guaranteed
      * to be non-null)
      */
-    public Point2D[][] getVertices() {
+    public Vector2D[][] getVertices() {
         if (vertices == null) {
             if (getTree(false).getCut() == null) {
-                vertices = new Point2D[0][];
+                vertices = new Vector2D[0][];
             } else {
 
                 // build the unconnected segments
@@ -651,7 +651,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
                 }
 
                 // transform the loops in an array of arrays of points
-                vertices = new Point2D[loops.size()][];
+                vertices = new Vector2D[loops.size()][];
                 int i = 0;
 
                 for (final List<Segment> loop : loops) {
@@ -659,14 +659,14 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
                         (loop.size() == 2 && loop.get(0).getStart() == null && loop.get(1).getEnd() == null)) {
                         // single infinite line
                         final Line line = loop.get(0).getLine();
-                        vertices[i++] = new Point2D[] {
+                        vertices[i++] = new Vector2D[] {
                             null,
-                            line.toSpace(Point1D.of(-Float.MAX_VALUE)),
-                            line.toSpace(Point1D.of(+Float.MAX_VALUE))
+                            line.toSpace(Vector1D.of(-Float.MAX_VALUE)),
+                            line.toSpace(Vector1D.of(+Float.MAX_VALUE))
                         };
                     } else if (loop.get(0).getStart() == null) {
                         // open loop with at least one real point
-                        final Point2D[] array = new Point2D[loop.size() + 2];
+                        final Vector2D[] array = new Vector2D[loop.size() + 2];
                         int j = 0;
                         for (Segment segment : loop) {
 
@@ -675,7 +675,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
                                 double x = segment.getLine().toSubSpace(segment.getEnd()).getX();
                                 x -= Math.max(1.0, Math.abs(x / 2));
                                 array[j++] = null;
-                                array[j++] = segment.getLine().toSpace(Point1D.of(x));
+                                array[j++] = segment.getLine().toSpace(Vector1D.of(x));
                             }
 
                             if (j < (array.length - 1)) {
@@ -685,13 +685,13 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
                                 // last dummy point
                                 double x = segment.getLine().toSubSpace(segment.getStart()).getX();
                                 x += Math.max(1.0, Math.abs(x / 2));
-                                array[j++] = segment.getLine().toSpace(Point1D.of(x));
+                                array[j++] = segment.getLine().toSpace(Vector1D.of(x));
                             }
 
                         }
                         vertices[i++] = array;
                     } else {
-                        final Point2D[] array = new Point2D[loop.size()];
+                        final Vector2D[] array = new Vector2D[loop.size()];
                         int j = 0;
                         for (Segment segment : loop) {
                             array[j++] = segment.getStart();
@@ -715,8 +715,8 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         int connected = 0;
         for (final ConnectableSegment segment : segments) {
             if (segment.getNext() == null) {
-                final BSPTree<Point2D> node = segment.getNode();
-                final BSPTree<Point2D> end  = segment.getEndNode();
+                final BSPTree<Vector2D> node = segment.getNode();
+                final BSPTree<Vector2D> end  = segment.getEndNode();
                 for (final ConnectableSegment candidateNext : segments) {
                     if (candidateNext.getPrevious()  == null &&
                         candidateNext.getNode()      == end &&
@@ -741,8 +741,8 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         int connected = 0;
         for (final ConnectableSegment segment : segments) {
             if (segment.getNext() == null) {
-                final Hyperplane<Point2D> hyperplane = segment.getNode().getCut().getHyperplane();
-                final BSPTree<Point2D> end  = segment.getEndNode();
+                final Hyperplane<Vector2D> hyperplane = segment.getNode().getCut().getHyperplane();
+                final BSPTree<Vector2D> end  = segment.getEndNode();
                 for (final ConnectableSegment candidateNext : segments) {
                     if (candidateNext.getPrevious()                      == null &&
                         candidateNext.getNode().getCut().getHyperplane() == hyperplane &&
@@ -771,7 +771,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         int connected = 0;
         for (final ConnectableSegment segment : segments) {
             if (segment.getNext() == null && segment.getEnd() != null) {
-                final Point2D end = segment.getEnd();
+                final Vector2D end = segment.getEnd();
                 ConnectableSegment selectedNext = null;
                 double min = Double.POSITIVE_INFINITY;
                 for (final ConnectableSegment candidateNext : segments) {
@@ -883,13 +883,13 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
     private static class ConnectableSegment extends Segment {
 
         /** Node containing segment. */
-        private final BSPTree<Point2D> node;
+        private final BSPTree<Vector2D> node;
 
         /** Node whose intersection with current node defines start point. */
-        private final BSPTree<Point2D> startNode;
+        private final BSPTree<Vector2D> startNode;
 
         /** Node whose intersection with current node defines end point. */
-        private final BSPTree<Point2D> endNode;
+        private final BSPTree<Vector2D> endNode;
 
         /** Previous segment. */
         private ConnectableSegment previous;
@@ -908,10 +908,10 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
          * @param startNode node whose intersection with current node defines start point
          * @param endNode node whose intersection with current node defines end point
          */
-        ConnectableSegment(final Point2D start, final Point2D end, final Line line,
-                           final BSPTree<Point2D> node,
-                           final BSPTree<Point2D> startNode,
-                           final BSPTree<Point2D> endNode) {
+        ConnectableSegment(final Vector2D start, final Vector2D end, final Line line,
+                           final BSPTree<Vector2D> node,
+                           final BSPTree<Vector2D> startNode,
+                           final BSPTree<Vector2D> endNode) {
             super(start, end, line);
             this.node      = node;
             this.startNode = startNode;
@@ -924,21 +924,21 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
         /** Get the node containing segment.
          * @return node containing segment
          */
-        public BSPTree<Point2D> getNode() {
+        public BSPTree<Vector2D> getNode() {
             return node;
         }
 
         /** Get the node whose intersection with current node defines start point.
          * @return node whose intersection with current node defines start point
          */
-        public BSPTree<Point2D> getStartNode() {
+        public BSPTree<Vector2D> getStartNode() {
             return startNode;
         }
 
         /** Get the node whose intersection with current node defines end point.
          * @return node whose intersection with current node defines end point
          */
-        public BSPTree<Point2D> getEndNode() {
+        public BSPTree<Vector2D> getEndNode() {
             return endNode;
         }
 
@@ -987,7 +987,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
     }
 
     /** Visitor building segments. */
-    private static class SegmentsBuilder implements BSPTreeVisitor<Point2D> {
+    private static class SegmentsBuilder implements BSPTreeVisitor<Vector2D> {
 
         /** Tolerance for close nodes connection. */
         private final double tolerance;
@@ -1005,16 +1005,16 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
 
         /** {@inheritDoc} */
         @Override
-        public Order visitOrder(final BSPTree<Point2D> node) {
+        public Order visitOrder(final BSPTree<Vector2D> node) {
             return Order.MINUS_SUB_PLUS;
         }
 
         /** {@inheritDoc} */
         @Override
-        public void visitInternalNode(final BSPTree<Point2D> node) {
+        public void visitInternalNode(final BSPTree<Vector2D> node) {
             @SuppressWarnings("unchecked")
-            final BoundaryAttribute<Point2D> attribute = (BoundaryAttribute<Point2D>) node.getAttribute();
-            final Iterable<BSPTree<Point2D>> splitters = attribute.getSplitters();
+            final BoundaryAttribute<Vector2D> attribute = (BoundaryAttribute<Vector2D>) node.getAttribute();
+            final Iterable<BSPTree<Vector2D>> splitters = attribute.getSplitters();
             if (attribute.getPlusOutside() != null) {
                 addContribution(attribute.getPlusOutside(), node, splitters, false);
             }
@@ -1025,7 +1025,7 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
 
         /** {@inheritDoc} */
         @Override
-        public void visitLeafNode(final BSPTree<Point2D> node) {
+        public void visitLeafNode(final BSPTree<Vector2D> node) {
         }
 
         /** Add the contribution of a boundary facet.
@@ -1034,26 +1034,26 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
          * @param splitters splitters for the boundary facet
          * @param reversed if true, the facet has the inside on its plus side
          */
-        private void addContribution(final SubHyperplane<Point2D> sub,
-                                     final BSPTree<Point2D> node,
-                                     final Iterable<BSPTree<Point2D>> splitters,
+        private void addContribution(final SubHyperplane<Vector2D> sub,
+                                     final BSPTree<Vector2D> node,
+                                     final Iterable<BSPTree<Vector2D>> splitters,
                                      final boolean reversed) {
             @SuppressWarnings("unchecked")
-            final AbstractSubHyperplane<Point2D, Point1D> absSub =
-                (AbstractSubHyperplane<Point2D, Point1D>) sub;
+            final AbstractSubHyperplane<Vector2D, Vector1D> absSub =
+                (AbstractSubHyperplane<Vector2D, Vector1D>) sub;
             final Line line      = (Line) sub.getHyperplane();
             final List<Interval> intervals = ((IntervalsSet) absSub.getRemainingRegion()).asList();
             for (final Interval i : intervals) {
 
                 // find the 2D points
-                final Point2D startV = Double.isInfinite(i.getInf()) ?
-                                        null : line.toSpace(Point1D.of(i.getInf()));
-                final Point2D endV   = Double.isInfinite(i.getSup()) ?
-                                        null : line.toSpace(Point1D.of(i.getSup()));
+                final Vector2D startV = Double.isInfinite(i.getInf()) ?
+                                        null : line.toSpace(Vector1D.of(i.getInf()));
+                final Vector2D endV   = Double.isInfinite(i.getSup()) ?
+                                        null : line.toSpace(Vector1D.of(i.getSup()));
 
                 // recover the connectivity information
-                final BSPTree<Point2D> startN = selectClosest(startV, splitters);
-                final BSPTree<Point2D> endN   = selectClosest(endV, splitters);
+                final BSPTree<Vector2D> startN = selectClosest(startV, splitters);
+                final BSPTree<Vector2D> endN   = selectClosest(endV, splitters);
 
                 if (reversed) {
                     segments.add(new ConnectableSegment(endV, startV, line.getReverse(),
@@ -1071,12 +1071,12 @@ public class PolygonsSet extends AbstractRegion<Point2D, Point1D> {
          * @param candidates candidate nodes
          * @return node closest to point, or null if point is null or no node is closer than tolerance
          */
-        private BSPTree<Point2D> selectClosest(final Point2D point, final Iterable<BSPTree<Point2D>> candidates) {
+        private BSPTree<Vector2D> selectClosest(final Vector2D point, final Iterable<BSPTree<Vector2D>> candidates) {
             if (point != null) {
-                BSPTree<Point2D> selected = null;
+                BSPTree<Vector2D> selected = null;
                 double min = Double.POSITIVE_INFINITY;
 
-                for (final BSPTree<Point2D> node : candidates) {
+                for (final BSPTree<Vector2D> node : candidates) {
                     final double distance = Math.abs(node.getCut().getHyperplane().getOffset(point));
                     if (distance < min) {
                         selected = node;
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Segment.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Segment.java
index a728d61..b2f82b3 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Segment.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Segment.java
@@ -21,10 +21,10 @@ package org.apache.commons.geometry.euclidean.twod;
 public class Segment {
 
     /** Start point of the segment. */
-    private final Point2D start;
+    private final Vector2D start;
 
     /** End point of the segment. */
-    private final Point2D end;
+    private final Vector2D end;
 
     /** Line containing the segment. */
     private final Line     line;
@@ -34,7 +34,7 @@ public class Segment {
      * @param end end point of the segment
      * @param line line containing the segment
      */
-    public Segment(final Point2D start, final Point2D end, final Line line) {
+    public Segment(final Vector2D start, final Vector2D end, final Line line) {
         this.start  = start;
         this.end    = end;
         this.line   = line;
@@ -43,14 +43,14 @@ public class Segment {
     /** Get the start point of the segment.
      * @return start point of the segment
      */
-    public Point2D getStart() {
+    public Vector2D getStart() {
         return start;
     }
 
     /** Get the end point of the segment.
      * @return end point of the segment
      */
-    public Point2D getEnd() {
+    public Vector2D getEnd() {
         return end;
     }
 
@@ -75,7 +75,7 @@ public class Segment {
      * @param p to check
      * @return distance between the instance and the point
      */
-    public double distance(final Point2D p) {
+    public double distance(final Vector2D p) {
         final double deltaX = end.getX() - start.getX();
         final double deltaY = end.getY() - start.getY();
 
@@ -100,7 +100,7 @@ public class Segment {
             final double px = start.getX() + r * deltaX;
             final double py = start.getY() + r * deltaY;
 
-            final Point2D interPt = Point2D.of(px, py);
+            final Vector2D interPt = Vector2D.of(px, py);
             return interPt.distance(p);
         }
     }
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/SubLine.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/SubLine.java
index 94d2398..acf0ea3 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/SubLine.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/SubLine.java
@@ -28,18 +28,18 @@ import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 import org.apache.commons.geometry.euclidean.oned.Interval;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
 import org.apache.commons.geometry.euclidean.oned.OrientedPoint;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 
 /** This class represents a sub-hyperplane for {@link Line}.
  */
-public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
+public class SubLine extends AbstractSubHyperplane<Vector2D, Vector1D> {
 
     /** Simple constructor.
      * @param hyperplane underlying hyperplane
      * @param remainingRegion remaining region of the hyperplane
      */
-    public SubLine(final Hyperplane<Point2D> hyperplane,
-                   final Region<Point1D> remainingRegion) {
+    public SubLine(final Hyperplane<Vector2D> hyperplane,
+                   final Region<Vector1D> remainingRegion) {
         super(hyperplane, remainingRegion);
     }
 
@@ -48,7 +48,7 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
      * @param end end point
      * @param tolerance tolerance below which points are considered identical
      */
-    public SubLine(final Point2D start, final Point2D end, final double tolerance) {
+    public SubLine(final Vector2D start, final Vector2D end, final double tolerance) {
         super(new Line(start, end, tolerance), buildIntervalSet(start, end, tolerance));
     }
 
@@ -81,8 +81,8 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
         final List<Segment> segments = new ArrayList<>(list.size());
 
         for (final Interval interval : list) {
-            final Point2D start = line.toSpace(Point1D.of(interval.getInf()));
-            final Point2D end   = line.toSpace(Point1D.of(interval.getSup()));
+            final Vector2D start = line.toSpace(Vector1D.of(interval.getInf()));
+            final Vector2D end   = line.toSpace(Vector1D.of(interval.getSup()));
             segments.add(new Segment(start, end, line));
         }
 
@@ -104,14 +104,14 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
      * 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 Point2D intersection(final SubLine subLine, final boolean includeEndPoints) {
+    public Vector2D intersection(final SubLine subLine, final boolean includeEndPoints) {
 
         // retrieve the underlying lines
         Line line1 = (Line) getHyperplane();
         Line line2 = (Line) subLine.getHyperplane();
 
         // compute the intersection on infinite line
-        Point2D v2D = line1.intersection(line2);
+        Vector2D v2D = line1.intersection(line2);
         if (v2D == null) {
             return null;
         }
@@ -136,7 +136,7 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
      * @param tolerance tolerance below which points are considered identical
      * @return an interval set
      */
-    private static IntervalsSet buildIntervalSet(final Point2D start, final Point2D end, final double tolerance) {
+    private static IntervalsSet buildIntervalSet(final Vector2D start, final Vector2D end, final double tolerance) {
         final Line line = new Line(start, end, tolerance);
         return new IntervalsSet(line.toSubSpace(start).getX(),
                                 line.toSubSpace(end).getX(),
@@ -145,18 +145,18 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
 
     /** {@inheritDoc} */
     @Override
-    protected AbstractSubHyperplane<Point2D, Point1D> buildNew(final Hyperplane<Point2D> hyperplane,
-                                                                       final Region<Point1D> remainingRegion) {
+    protected AbstractSubHyperplane<Vector2D, Vector1D> buildNew(final Hyperplane<Vector2D> hyperplane,
+                                                                       final Region<Vector1D> remainingRegion) {
         return new SubLine(hyperplane, remainingRegion);
     }
 
     /** {@inheritDoc} */
     @Override
-    public SplitSubHyperplane<Point2D> split(final Hyperplane<Point2D> hyperplane) {
+    public SplitSubHyperplane<Vector2D> split(final Hyperplane<Vector2D> hyperplane) {
 
         final Line    thisLine  = (Line) getHyperplane();
         final Line    otherLine = (Line) hyperplane;
-        final Point2D crossing = thisLine.intersection(otherLine);
+        final Vector2D crossing = thisLine.intersection(otherLine);
         final double tolerance  = thisLine.getTolerance();
 
         if (crossing == null) {
@@ -173,20 +173,20 @@ public class SubLine extends AbstractSubHyperplane<Point2D, Point1D> {
 
         // the lines do intersect
         final boolean direct = Math.sin(thisLine.getAngle() - otherLine.getAngle()) < 0;
-        final Point1D x      = thisLine.toSubSpace(crossing);
-        final SubHyperplane<Point1D> subPlus  =
+        final Vector1D x      = thisLine.toSubSpace(crossing);
+        final SubHyperplane<Vector1D> subPlus  =
                 new OrientedPoint(x, !direct, tolerance).wholeHyperplane();
-        final SubHyperplane<Point1D> subMinus =
+        final SubHyperplane<Vector1D> subMinus =
                 new OrientedPoint(x,  direct, tolerance).wholeHyperplane();
 
-        final BSPTree<Point1D> splitTree = getRemainingRegion().getTree(false).split(subMinus);
-        final BSPTree<Point1D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
-                                               new BSPTree<Point1D>(Boolean.FALSE) :
-                                               new BSPTree<>(subPlus, new BSPTree<Point1D>(Boolean.FALSE),
+        final BSPTree<Vector1D> splitTree = getRemainingRegion().getTree(false).split(subMinus);
+        final BSPTree<Vector1D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
+                                               new BSPTree<Vector1D>(Boolean.FALSE) :
+                                               new BSPTree<>(subPlus, new BSPTree<Vector1D>(Boolean.FALSE),
                                                                         splitTree.getPlus(), null);
-        final BSPTree<Point1D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
-                                               new BSPTree<Point1D>(Boolean.FALSE) :
-                                               new BSPTree<>(subMinus, new BSPTree<Point1D>(Boolean.FALSE),
+        final BSPTree<Vector1D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
+                                               new BSPTree<Vector1D>(Boolean.FALSE) :
+                                               new BSPTree<>(subMinus, new BSPTree<Vector1D>(Boolean.FALSE),
                                                                         splitTree.getMinus(), null);
         return new SplitSubHyperplane<>(new SubLine(thisLine.copySelf(), new IntervalsSet(plusTree, tolerance)),
                                                    new SubLine(thisLine.copySelf(), new IntervalsSet(minusTree, tolerance)));
diff --git a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
index a906dc7..2000c6b 100644
--- a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
+++ b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
@@ -26,7 +26,7 @@ import org.apache.commons.numbers.arrays.LinearCombination;
 /** This class represents a vector in two-dimensional Euclidean space.
  * Instances of this class are guaranteed to be immutable.
  */
-public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVector<Point2D, Vector2D> {
+public class Vector2D extends MultiDimensionalEuclideanVector<Vector2D> {
 
     /** Zero vector (coordinates: 0, 0). */
     public static final Vector2D ZERO   = new Vector2D(0, 0);
@@ -59,18 +59,80 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
     /** Serializable UID */
     private static final long serialVersionUID = 20180710L;
 
+    /** Abscissa (first coordinate) */
+    private final double x;
+
+    /** Ordinate (second coordinate) */
+    private final double y;
+
     /** Simple constructor.
      * @param x abscissa (first coordinate)
      * @param y ordinate (second coordinate)
      */
     private Vector2D(double x, double y) {
-        super(x, y);
+        this.x = x;
+        this.y = y;
+    }
+
+    /** Returns the abscissa (first coordinate value) of the instance.
+     * @return the abscissa
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** Returns the ordinate (second coordinate value) of the instance.
+     * @return the ordinate
+     */
+    public double getY() {
+        return y;
+    }
+
+    /** Return an equivalent set of coordinates in polar form.
+     * @return An equivalent set of coordinates in polar form.
+     */
+    public PolarCoordinates toPolar() {
+        return PolarCoordinates.ofCartesian(x, y);
+    }
+
+    /** Get the coordinates for this instance as a dimension 2 array.
+     * @return coordinates for this instance
+     */
+    public double[] toArray() {
+        return new double[] { x, y };
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getDimension() {
+        return 2;
+    }
+
+    /** {@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 Point2D asPoint() {
-        return Point2D.of(getX(), getY());
+    public Vector2D vectorTo(Vector2D v) {
+        return v.subtract(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Vector2D directionTo(Vector2D v) {
+        return normalize(
+                    v.x - x,
+                    v.y - y
+                );
     }
 
     /** {@inheritDoc} */
@@ -88,13 +150,13 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
     /** {@inheritDoc} */
     @Override
     public double getNorm() {
-        return Vectors.norm(getX(), getY());
+        return Vectors.norm(x, y);
     }
 
     /** {@inheritDoc} */
     @Override
     public double getNormSq() {
-        return Vectors.normSq(getX(), getY());
+        return Vectors.normSq(x, y);
     }
 
     /** {@inheritDoc} */
@@ -103,69 +165,69 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
         final double invNorm = 1.0 / getCheckedNorm();
 
         return new Vector2D(
-                    magnitude * getX() * invNorm,
-                    magnitude * getY() * invNorm
+                    magnitude * x * invNorm,
+                    magnitude * y * invNorm
                 );
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D add(Vector2D v) {
-        return new Vector2D(getX() + v.getX(), getY() + v.getY());
+        return new Vector2D(x + v.x, y + v.y);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D add(double factor, Vector2D v) {
-        return new Vector2D(getX() + (factor * v.getX()), getY() + (factor * v.getY()));
+        return new Vector2D(x + (factor * v.x), y + (factor * v.y));
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D subtract(Vector2D v) {
-        return new Vector2D(getX() - v.getX(), getY() - v.getY());
+        return new Vector2D(x - v.x, y - v.y);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D subtract(double factor, Vector2D v) {
-        return new Vector2D(getX() - (factor * v.getX()), getY() - (factor * v.getY()));
+        return new Vector2D(x - (factor * v.x), y - (factor * v.y));
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D negate() {
-        return new Vector2D(-getX(), -getY());
+        return new Vector2D(-x, -y);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D normalize() {
-        return normalize(getX(), getY());
+        return normalize(x, y);
     }
 
     /** {@inheritDoc} */
     @Override
     public Vector2D scalarMultiply(double a) {
-        return new Vector2D(a * getX(), a * getY());
+        return new Vector2D(a * x, a * y);
     }
 
     /** {@inheritDoc} */
     @Override
     public double distance(Vector2D v) {
-        return Vectors.norm(getX() - v.getX(), getY() - v.getY());
+        return Vectors.norm(x - v.x, y - v.y);
     }
 
     /** {@inheritDoc} */
     @Override
     public double distanceSq(Vector2D v) {
-        return Vectors.normSq(getX() - v.getX(), getY() - v.getY());
+        return Vectors.normSq(x - v.x, y - v.y);
     }
 
     /** {@inheritDoc} */
     @Override
     public double dotProduct(Vector2D v) {
-        return LinearCombination.value(getX(), v.getX(), getY(), v.getY());
+        return LinearCombination.value(x, v.x, y, v.y);
     }
 
     /** {@inheritDoc}
@@ -183,7 +245,7 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
         double threshold = normProduct * 0.9999;
         if ((dot < -threshold) || (dot > threshold)) {
             // the vectors are almost aligned, compute using the sine
-            final double n = Math.abs(LinearCombination.value(getX(), v.getY(), -getY(), v.getX()));
+            final double n = Math.abs(LinearCombination.value(x, v.y, -y, v.x));
             if (dot >= 0) {
                 return Math.asin(n / normProduct);
             }
@@ -217,7 +279,7 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
      */
     @Override
     public Vector2D orthogonal() {
-        return normalize(-getY(), getX());
+        return normalize(-y, x);
     }
 
     /** {@inheritDoc} */
@@ -247,10 +309,10 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
      * @see <a href="http://mathworld.wolfram.com/CrossProduct.html">Cross product (Mathworld)</a>
      */
     public double crossProduct(final Vector2D p1, final Vector2D 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();
+        final double x1 = p2.x - p1.x;
+        final double y1 = y - p1.y;
+        final double x2 = x - p1.x;
+        final double y2 = p2.y - p1.y;
         return LinearCombination.value(x1, y1, -x2, y2);
     }
 
@@ -266,7 +328,7 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
         if (isNaN()) {
             return 542;
         }
-        return 122 * (76 * Double.hashCode(getX()) +  Double.hashCode(getY()));
+        return 122 * (76 * Double.hashCode(x) +  Double.hashCode(y));
     }
 
     /**
@@ -300,11 +362,17 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
                 return this.isNaN();
             }
 
-            return (getX() == rhs.getX()) && (getY() == rhs.getY());
+            return (x == rhs.x) && (y == rhs.y);
         }
         return false;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return SimpleTupleFormat.getDefault().format(x, y);
+    }
+
     /** Returns a component of the current instance relative to the given base
      * vector. If {@code reject} is true, the vector rejection is returned; otherwise,
      * the projection is returned.
@@ -330,25 +398,16 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
 
         final double scale = aDotB / baseMagSq;
 
-        final double projX = scale * base.getX();
-        final double projY = scale * base.getY();
+        final double projX = scale * base.x;
+        final double projY = scale * base.y;
 
         if (reject) {
-            return factory.apply(getX() - projX, getY() - projY);
+            return factory.apply(x - projX, y - projY);
         }
 
         return factory.apply(projX, projY);
     }
 
-    /** Returns the vector norm value, throwing an {@link IllegalNormException} if the value
-     * is not real (ie, NaN or infinite) or zero.
-     * @return the vector norm value, guaranteed to be real and non-zero
-     * @throws IllegalNormException if the vector norm is zero, NaN, or infinite
-     */
-    private double getCheckedNorm() {
-        return Vectors.checkedNorm(getNorm());
-    }
-
     /** Returns a vector with the given coordinate values.
      * @param x abscissa (first coordinate value)
      * @param y abscissa (second coordinate value)
@@ -405,85 +464,77 @@ public class Vector2D extends Cartesian2D implements MultiDimensionalEuclideanVe
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a scale factor for first coordinate
      * @param c first coordinate
      * @return vector with coordinates calculated by {@code a * c}
      */
-    public static Vector2D linearCombination(double a, Cartesian2D c) {
-        return new Vector2D(a * c.getX(), a * c.getY());
+    public static Vector2D linearCombination(double a, Vector2D c) {
+        return new Vector2D(a * c.x, a * c.y);
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2)}
+     * @param v2 second coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2)}
      */
-    public static Vector2D linearCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2) {
+    public static Vector2D linearCombination(double a1, Vector2D v1, double a2, Vector2D v2) {
         return new Vector2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY()));
+                LinearCombination.value(a1, v1.x, a2, v2.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
-     * @return vector with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3)}
+     * @param v3 third coordinate
+     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3)}
      */
-    public static Vector2D linearCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2,
-            double a3, Cartesian2D c3) {
+    public static Vector2D linearCombination(double a1, Vector2D v1, double a2, Vector2D v2,
+            double a3, Vector2D v3) {
         return new Vector2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y, a3, v3.y));
     }
 
     /** Returns a vector consisting of the linear combination of the inputs.
      * <p>
      * A linear combination is the sum of all of the inputs multiplied by their
-     * corresponding scale factors. All inputs are interpreted as vectors. If points
-     * are to be passed, they should be viewed as representing the vector from the
-     * zero point to the given point.
+     * corresponding scale factors.
      * </p>
      *
      * @param a1 scale factor for first coordinate
-     * @param c1 first coordinate
+     * @param v1 first coordinate
      * @param a2 scale factor for second coordinate
-     * @param c2 second coordinate
+     * @param v2 second coordinate
      * @param a3 scale factor for third coordinate
-     * @param c3 third coordinate
+     * @param v3 third coordinate
      * @param a4 scale factor for fourth coordinate
-     * @param c4 fourth coordinate
-     * @return point with coordinates calculated by {@code (a1 * c1) + (a2 * c2) + (a3 * c3) + (a4 * c4)}
+     * @param v4 fourth coordinate
+     * @return point with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3) + (a4 * v4)}
      */
-    public static Vector2D linearCombination(double a1, Cartesian2D c1, double a2, Cartesian2D c2,
-            double a3, Cartesian2D c3, double a4, Cartesian2D c4) {
+    public static Vector2D linearCombination(double a1, Vector2D v1, double a2, Vector2D v2,
+            double a3, Vector2D v3, double a4, Vector2D v4) {
         return new Vector2D(
-                LinearCombination.value(a1, c1.getX(), a2, c2.getX(), a3, c3.getX(), a4, c4.getX()),
-                LinearCombination.value(a1, c1.getY(), a2, c2.getY(), a3, c3.getY(), a4, c4.getY()));
+                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x, a4, v4.x),
+                LinearCombination.value(a1, v1.y, a2, v2.y, a3, v3.y, a4, v4.y));
     }
 
     /** Private class used to represent unit vectors. This allows optimizations to be performed for certain
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/core/partitioning/CharacterizationTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/core/partitioning/CharacterizationTest.java
index dc28a43..00ab8ef 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/core/partitioning/CharacterizationTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/core/partitioning/CharacterizationTest.java
@@ -20,9 +20,9 @@ import java.util.Iterator;
 
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
 import org.apache.commons.geometry.euclidean.twod.Line;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 import org.apache.commons.geometry.euclidean.twod.SubLine;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -37,11 +37,11 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_insideLeaf() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        SubLine sub = buildSubLine(Point2D.of(0, -1), Point2D.of(0, 1));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        SubLine sub = buildSubLine(Vector2D.of(0, -1), Vector2D.of(0, 1));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -56,11 +56,11 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_outsideLeaf() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.FALSE);
-        SubLine sub = buildSubLine(Point2D.of(0, -1), Point2D.of(0, 1));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.FALSE);
+        SubLine sub = buildSubLine(Vector2D.of(0, -1), Vector2D.of(0, 1));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(false, ch.touchInside());
@@ -75,13 +75,13 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_onPlusSide() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, -1), Point2D.of(0, -2));
+        SubLine sub = buildSubLine(Vector2D.of(0, -1), Vector2D.of(0, -2));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(false, ch.touchInside());
@@ -96,13 +96,13 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_onMinusSide() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, 1), Point2D.of(0, 2));
+        SubLine sub = buildSubLine(Vector2D.of(0, 1), Vector2D.of(0, 2));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -117,13 +117,13 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_onBothSides() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, -1), Point2D.of(0, 1));
+        SubLine sub = buildSubLine(Vector2D.of(0, -1), Vector2D.of(0, 1));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -131,11 +131,11 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, 0), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 1), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, 0), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 1), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getInsideSplitters()));
-        Iterator<BSPTree<Point2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
         Assert.assertSame(tree, insideSplitterIter.next());
 
         Assert.assertEquals(true, ch.touchOutside());
@@ -143,25 +143,25 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(1, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, -1), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 0), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, -1), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 0), outside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getOutsideSplitters()));
-        Iterator<BSPTree<Point2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
         Assert.assertSame(tree, outsideSplitterIter.next());
     }
 
     @Test
     public void testCharacterize_multipleSplits_reunitedOnPlusSide() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
-        cut(tree.getMinus(), buildLine(Point2D.of(-1, 0), Point2D.of(0, 1)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
+        cut(tree.getMinus(), buildLine(Vector2D.of(-1, 0), Vector2D.of(0, 1)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, -2), Point2D.of(0, 2));
+        SubLine sub = buildSubLine(Vector2D.of(0, -2), Vector2D.of(0, 2));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -169,11 +169,11 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, 1), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 2), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, 1), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 2), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(2, size(ch.getInsideSplitters()));
-        Iterator<BSPTree<Point2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
         Assert.assertSame(tree, insideSplitterIter.next());
         Assert.assertSame(tree.getMinus(), insideSplitterIter.next());
 
@@ -182,11 +182,11 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(1, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, -2), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 1), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, -2), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 1), outside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(2, size(ch.getOutsideSplitters()));
-        Iterator<BSPTree<Point2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
         Assert.assertSame(tree, outsideSplitterIter.next());
         Assert.assertSame(tree.getMinus(), outsideSplitterIter.next());
     }
@@ -194,15 +194,15 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_multipleSplits_reunitedOnMinusSide() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
-        cut(tree.getMinus(), buildLine(Point2D.of(-1, 0), Point2D.of(0, 1)));
-        cut(tree.getMinus().getPlus(), buildLine(Point2D.of(-0.5, 0.5), Point2D.of(0, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
+        cut(tree.getMinus(), buildLine(Vector2D.of(-1, 0), Vector2D.of(0, 1)));
+        cut(tree.getMinus().getPlus(), buildLine(Vector2D.of(-0.5, 0.5), Vector2D.of(0, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, -2), Point2D.of(0, 2));
+        SubLine sub = buildSubLine(Vector2D.of(0, -2), Vector2D.of(0, 2));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -210,11 +210,11 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, 0), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 2), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, 0), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 2), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(2, size(ch.getInsideSplitters()));
-        Iterator<BSPTree<Point2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
         Assert.assertSame(tree, insideSplitterIter.next());
         Assert.assertSame(tree.getMinus(), insideSplitterIter.next());
 
@@ -223,24 +223,24 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(1, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(0, -2), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 0), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, -2), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 0), outside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getOutsideSplitters()));
-        Iterator<BSPTree<Point2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
         Assert.assertSame(tree, outsideSplitterIter.next());
     }
 
     @Test
     public void testCharacterize_onHyperplane_sameOrientation() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(0, 0), Point2D.of(1, 0));
+        SubLine sub = buildSubLine(Vector2D.of(0, 0), Vector2D.of(1, 0));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -255,13 +255,13 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_onHyperplane_oppositeOrientation() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
 
-        SubLine sub = buildSubLine(Point2D.of(1, 0), Point2D.of(0, 0));
+        SubLine sub = buildSubLine(Vector2D.of(1, 0), Vector2D.of(0, 0));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -276,14 +276,14 @@ public class CharacterizationTest {
     @Test
     public void testCharacterize_onHyperplane_multipleSplits_sameOrientation() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
-        cut(tree.getMinus(), buildLine(Point2D.of(-1, 0), Point2D.of(0, 1)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
+        cut(tree.getMinus(), buildLine(Vector2D.of(-1, 0), Vector2D.of(0, 1)));
 
-        SubLine sub = buildSubLine(Point2D.of(-2, 0), Point2D.of(2, 0));
+        SubLine sub = buildSubLine(Vector2D.of(-2, 0), Vector2D.of(2, 0));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -291,11 +291,11 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(-2, 0), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(-1, 0), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(-2, 0), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(-1, 0), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getInsideSplitters()));
-        Iterator<BSPTree<Point2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
         Assert.assertSame(tree.getMinus(), insideSplitterIter.next());
 
         Assert.assertEquals(true, ch.touchOutside());
@@ -303,25 +303,25 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(1, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(-1, 0), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(2, 0), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(-1, 0), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(2, 0), outside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getOutsideSplitters()));
-        Iterator<BSPTree<Point2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
         Assert.assertSame(tree.getMinus(), outsideSplitterIter.next());
     }
 
     @Test
     public void testCharacterize_onHyperplane_multipleSplits_oppositeOrientation() {
         // arrange
-        BSPTree<Point2D> tree = new BSPTree<>(Boolean.TRUE);
-        cut(tree, buildLine(Point2D.of(0, 0), Point2D.of(1, 0)));
-        cut(tree.getMinus(), buildLine(Point2D.of(-1, 0), Point2D.of(0, 1)));
+        BSPTree<Vector2D> tree = new BSPTree<>(Boolean.TRUE);
+        cut(tree, buildLine(Vector2D.of(0, 0), Vector2D.of(1, 0)));
+        cut(tree.getMinus(), buildLine(Vector2D.of(-1, 0), Vector2D.of(0, 1)));
 
-        SubLine sub = buildSubLine(Point2D.of(2, 0), Point2D.of(-2, 0));
+        SubLine sub = buildSubLine(Vector2D.of(2, 0), Vector2D.of(-2, 0));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -329,11 +329,11 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(-1, 0), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(-2, 0), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(-1, 0), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(-2, 0), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getInsideSplitters()));
-        Iterator<BSPTree<Point2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> insideSplitterIter = ch.getInsideSplitters().iterator();
         Assert.assertSame(tree.getMinus(), insideSplitterIter.next());
 
         Assert.assertEquals(true, ch.touchOutside());
@@ -341,11 +341,11 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(1, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(2, 0), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(-1, 0), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(2, 0), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(-1, 0), outside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(1, size(ch.getOutsideSplitters()));
-        Iterator<BSPTree<Point2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
+        Iterator<BSPTree<Vector2D>> outsideSplitterIter = ch.getOutsideSplitters().iterator();
         Assert.assertSame(tree.getMinus(), outsideSplitterIter.next());
     }
 
@@ -353,12 +353,12 @@ public class CharacterizationTest {
     public void testCharacterize_onHyperplane_box() {
         // arrange
         PolygonsSet poly = new PolygonsSet(0, 1, 0, 1, TEST_TOLERANCE);
-        BSPTree<Point2D> tree = poly.getTree(false);
+        BSPTree<Vector2D> tree = poly.getTree(false);
 
-        SubLine sub = buildSubLine(Point2D.of(2, 0), Point2D.of(-2, 0));
+        SubLine sub = buildSubLine(Vector2D.of(2, 0), Vector2D.of(-2, 0));
 
         // act
-        Characterization<Point2D> ch = new Characterization<>(tree, sub);
+        Characterization<Vector2D> ch = new Characterization<>(tree, sub);
 
         // assert
         Assert.assertEquals(true, ch.touchInside());
@@ -366,8 +366,8 @@ public class CharacterizationTest {
 
         SubLine inside = (SubLine) ch.insideTouching();
         Assert.assertEquals(1, inside.getSegments().size());
-        assertVectorEquals(Point2D.of(1, 0), inside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(0, 0), inside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(1, 0), inside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(0, 0), inside.getSegments().get(0).getEnd());
 
         Assert.assertEquals(2, size(ch.getInsideSplitters()));
 
@@ -376,15 +376,15 @@ public class CharacterizationTest {
 
         SubLine outside = (SubLine) ch.outsideTouching();
         Assert.assertEquals(2, outside.getSegments().size());
-        assertVectorEquals(Point2D.of(2, 0), outside.getSegments().get(0).getStart());
-        assertVectorEquals(Point2D.of(1, 0), outside.getSegments().get(0).getEnd());
-        assertVectorEquals(Point2D.of(0, 0), outside.getSegments().get(1).getStart());
-        assertVectorEquals(Point2D.of(-2, 0), outside.getSegments().get(1).getEnd());
+        assertVectorEquals(Vector2D.of(2, 0), outside.getSegments().get(0).getStart());
+        assertVectorEquals(Vector2D.of(1, 0), outside.getSegments().get(0).getEnd());
+        assertVectorEquals(Vector2D.of(0, 0), outside.getSegments().get(1).getStart());
+        assertVectorEquals(Vector2D.of(-2, 0), outside.getSegments().get(1).getEnd());
 
         Assert.assertEquals(2, size(ch.getOutsideSplitters()));
     }
 
-    private void cut(BSPTree<Point2D> tree, Line line) {
+    private void cut(BSPTree<Vector2D> tree, Line line) {
         if (tree.insertCut(line)) {
             tree.setAttribute(null);
             tree.getPlus().setAttribute(Boolean.FALSE);
@@ -392,8 +392,8 @@ public class CharacterizationTest {
         }
     }
 
-    private int size(NodesSet<Point2D> nodes) {
-        Iterator<BSPTree<Point2D>> it = nodes.iterator();
+    private int size(NodesSet<Vector2D> nodes) {
+        Iterator<BSPTree<Vector2D>> it = nodes.iterator();
 
         int size = 0;
         while (it.hasNext()) {
@@ -404,18 +404,18 @@ public class CharacterizationTest {
         return size;
     }
 
-    private Line buildLine(Point2D p1, Point2D p2) {
+    private Line buildLine(Vector2D p1, Vector2D p2) {
         return new Line(p1, p2, TEST_TOLERANCE);
     }
 
-    private SubLine buildSubLine(Point2D start, Point2D end) {
+    private SubLine buildSubLine(Vector2D start, Vector2D end) {
         Line line = new Line(start, end, TEST_TOLERANCE);
         double lower = (line.toSubSpace(start)).getX();
         double upper = (line.toSubSpace(end)).getX();
         return new SubLine(line, new IntervalsSet(lower, upper, TEST_TOLERANCE));
     }
 
-    private void assertVectorEquals(Point2D expected, Point2D actual) {
+    private void assertVectorEquals(Vector2D expected, Vector2D actual) {
         String msg = "Expected vector to equal " + expected + " but was " + actual + ";";
         Assert.assertEquals(msg, expected.getX(), actual.getX(), TEST_TOLERANCE);
         Assert.assertEquals(msg, expected.getY(), actual.getY(), TEST_TOLERANCE);
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/EuclideanTestUtils.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/EuclideanTestUtils.java
index e3ebdf9..959a75f 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/EuclideanTestUtils.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/EuclideanTestUtils.java
@@ -27,22 +27,18 @@ import org.apache.commons.geometry.core.partitioning.Hyperplane;
 import org.apache.commons.geometry.core.partitioning.TreeBuilder;
 import org.apache.commons.geometry.core.partitioning.TreeDumper;
 import org.apache.commons.geometry.core.partitioning.TreePrinter;
-import org.apache.commons.geometry.euclidean.oned.Cartesian1D;
 import org.apache.commons.geometry.euclidean.oned.IntervalsSet;
 import org.apache.commons.geometry.euclidean.oned.OrientedPoint;
-import org.apache.commons.geometry.euclidean.oned.Point1D;
 import org.apache.commons.geometry.euclidean.oned.SubOrientedPoint;
-import org.apache.commons.geometry.euclidean.threed.Cartesian3D;
+import org.apache.commons.geometry.euclidean.oned.Vector1D;
 import org.apache.commons.geometry.euclidean.threed.Plane;
-import org.apache.commons.geometry.euclidean.threed.Point3D;
 import org.apache.commons.geometry.euclidean.threed.PolyhedronsSet;
 import org.apache.commons.geometry.euclidean.threed.SubPlane;
 import org.apache.commons.geometry.euclidean.threed.Vector3D;
-import org.apache.commons.geometry.euclidean.twod.Cartesian2D;
 import org.apache.commons.geometry.euclidean.twod.Line;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 import org.apache.commons.geometry.euclidean.twod.SubLine;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.junit.Assert;
 
 /** Class containing various euclidean-related test utilities.
@@ -55,7 +51,7 @@ public class EuclideanTestUtils {
      * @param actual
      * @param tolerance
      */
-    public static void assertCoordinatesEqual(Cartesian1D expected, Cartesian1D actual, double tolerance) {
+    public static void assertCoordinatesEqual(Vector1D expected, Vector1D actual, double tolerance) {
         String msg = "Expected coordinates to equal " + expected + " but was " + actual + ";";
         Assert.assertEquals(msg, expected.getX(), actual.getX(), tolerance);
     }
@@ -66,7 +62,7 @@ public class EuclideanTestUtils {
      * @param actual
      * @param tolerance
      */
-    public static void assertCoordinatesEqual(Cartesian2D expected, Cartesian2D actual, double tolerance) {
+    public static void assertCoordinatesEqual(Vector2D expected, Vector2D actual, double tolerance) {
         String msg = "Expected coordinates to equal " + expected + " but was " + actual + ";";
         Assert.assertEquals(msg, expected.getX(), actual.getX(), tolerance);
         Assert.assertEquals(msg, expected.getY(), actual.getY(), tolerance);
@@ -78,7 +74,7 @@ public class EuclideanTestUtils {
      * @param actual
      * @param tolerance
      */
-    public static void assertCoordinatesEqual(Cartesian3D expected, Cartesian3D actual, double tolerance) {
+    public static void assertCoordinatesEqual(Vector3D expected, Vector3D actual, double tolerance) {
         String msg = "Expected coordinates to equal " + expected + " but was " + actual + ";";
         Assert.assertEquals(msg, expected.getX(), actual.getX(), tolerance);
         Assert.assertEquals(msg, expected.getY(), actual.getY(), tolerance);
@@ -108,11 +104,11 @@ public class EuclideanTestUtils {
      * @return string representation of the region
      */
     public static String dump(final IntervalsSet intervalsSet) {
-        final TreeDumper<Point1D> visitor = new TreeDumper<Point1D>("IntervalsSet", intervalsSet.getTolerance()) {
+        final TreeDumper<Vector1D> visitor = new TreeDumper<Vector1D>("IntervalsSet", intervalsSet.getTolerance()) {
 
             /** {@inheritDoc} */
             @Override
-            protected void formatHyperplane(final Hyperplane<Point1D> hyperplane) {
+            protected void formatHyperplane(final Hyperplane<Vector1D> hyperplane) {
                 final OrientedPoint h = (OrientedPoint) hyperplane;
                 getFormatter().format("%22.15e %b %22.15e",
                                       h.getLocation().getX(), h.isDirect(), h.getTolerance());
@@ -128,13 +124,13 @@ public class EuclideanTestUtils {
      * @return string representation of the region
      */
     public static String dump(final PolygonsSet polygonsSet) {
-        final TreeDumper<Point2D> visitor = new TreeDumper<Point2D>("PolygonsSet", polygonsSet.getTolerance()) {
+        final TreeDumper<Vector2D> visitor = new TreeDumper<Vector2D>("PolygonsSet", polygonsSet.getTolerance()) {
 
             /** {@inheritDoc} */
             @Override
-            protected void formatHyperplane(final Hyperplane<Point2D> hyperplane) {
+            protected void formatHyperplane(final Hyperplane<Vector2D> hyperplane) {
                 final Line h = (Line) hyperplane;
-                final Point2D p = h.toSpace(Point1D.ZERO);
+                final Vector2D p = h.toSpace(Vector1D.ZERO);
                 getFormatter().format("%22.15e %22.15e %22.15e %22.15e",
                                       p.getX(), p.getY(), h.getAngle(), h.getTolerance());
             }
@@ -149,13 +145,13 @@ public class EuclideanTestUtils {
      * @return string representation of the region
      */
     public static String dump(final PolyhedronsSet polyhedronsSet) {
-        final TreeDumper<Point3D> visitor = new TreeDumper<Point3D>("PolyhedronsSet", polyhedronsSet.getTolerance()) {
+        final TreeDumper<Vector3D> visitor = new TreeDumper<Vector3D>("PolyhedronsSet", polyhedronsSet.getTolerance()) {
 
             /** {@inheritDoc} */
             @Override
-            protected void formatHyperplane(final Hyperplane<Point3D> hyperplane) {
+            protected void formatHyperplane(final Hyperplane<Vector3D> hyperplane) {
                 final Plane h = (Plane) hyperplane;
-                final Point3D p = h.toSpace(Point2D.ZERO);
+                final Vector3D p = h.toSpace(Vector2D.ZERO);
                 getFormatter().format("%22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e",
                                       p.getX(), p.getY(), p.getZ(),
                                       h.getNormal().getX(), h.getNormal().getY(), h.getNormal().getZ(),
@@ -175,13 +171,13 @@ public class EuclideanTestUtils {
      */
     public static IntervalsSet parseIntervalsSet(final String s)
         throws IOException, ParseException {
-        final TreeBuilder<Point1D> builder = new TreeBuilder<Point1D>("IntervalsSet", s) {
+        final TreeBuilder<Vector1D> builder = new TreeBuilder<Vector1D>("IntervalsSet", s) {
 
             /** {@inheritDoc} */
             @Override
             public OrientedPoint parseHyperplane()
                 throws IOException, ParseException {
-                return new OrientedPoint(Point1D.of(getNumber()), getBoolean(), getNumber());
+                return new OrientedPoint(Vector1D.of(getNumber()), getBoolean(), getNumber());
             }
 
         };
@@ -196,13 +192,13 @@ public class EuclideanTestUtils {
      */
     public static PolygonsSet parsePolygonsSet(final String s)
         throws IOException, ParseException {
-        final TreeBuilder<Point2D> builder = new TreeBuilder<Point2D>("PolygonsSet", s) {
+        final TreeBuilder<Vector2D> builder = new TreeBuilder<Vector2D>("PolygonsSet", s) {
 
             /** {@inheritDoc} */
             @Override
             public Line parseHyperplane()
                 throws IOException, ParseException {
-                return new Line(Point2D.of(getNumber(), getNumber()), getNumber(), getNumber());
+                return new Line(Vector2D.of(getNumber(), getNumber()), getNumber(), getNumber());
             }
 
         };
@@ -217,13 +213,13 @@ public class EuclideanTestUtils {
      */
     public static PolyhedronsSet parsePolyhedronsSet(final String s)
         throws IOException, ParseException {
-        final TreeBuilder<Point3D> builder = new TreeBuilder<Point3D>("PolyhedronsSet", s) {
+        final TreeBuilder<Vector3D> builder = new TreeBuilder<Vector3D>("PolyhedronsSet", s) {
 
             /** {@inheritDoc} */
             @Override
             public Plane parseHyperplane()
                 throws IOException, ParseException {
-                return new Plane(Point3D.of(getNumber(), getNumber(), getNumber()),
+                return new Plane(Vector3D.of(getNumber(), getNumber(), getNumber()),
                                  Vector3D.of(getNumber(), getNumber(), getNumber()),
                                  getNumber());
             }
@@ -238,7 +234,7 @@ public class EuclideanTestUtils {
      * the console. This is intended for quick debugging of small trees.
      * @param tree
      */
-    public static void printTree1D(BSPTree<Point1D> tree) {
+    public static void printTree1D(BSPTree<Vector1D> tree) {
         TreePrinter1D printer = new TreePrinter1D();
         System.out.println(printer.writeAsString(tree));
     }
@@ -247,7 +243,7 @@ public class EuclideanTestUtils {
      * the console. This is intended for quick debugging of small trees.
      * @param tree
      */
-    public static void printTree2D(BSPTree<Point2D> tree) {
+    public static void printTree2D(BSPTree<Vector2D> tree) {
         TreePrinter2D printer = new TreePrinter2D();
         System.out.println(printer.writeAsString(tree));
     }
@@ -256,7 +252,7 @@ public class EuclideanTestUtils {
      * the console. This is intended for quick debugging of small trees.
      * @param tree
      */
-    public static void printTree3D(BSPTree<Point3D> tree) {
+    public static void printTree3D(BSPTree<Vector3D> tree) {
         TreePrinter3D printer = new TreePrinter3D();
         System.out.println(printer.writeAsString(tree));
     }
@@ -264,11 +260,11 @@ public class EuclideanTestUtils {
 
     /** Class for creating string representations of 1D {@link BSPTree}s.
      */
-    public static class TreePrinter1D extends TreePrinter<Point1D> {
+    public static class TreePrinter1D extends TreePrinter<Vector1D> {
 
         /** {@inheritDoc} */
         @Override
-        protected void writeInternalNode(BSPTree<Point1D> node) {
+        protected void writeInternalNode(BSPTree<Vector1D> node) {
             SubOrientedPoint cut = (SubOrientedPoint) node.getCut();
 
             OrientedPoint hyper = (OrientedPoint) cut.getHyperplane();
@@ -304,16 +300,16 @@ public class EuclideanTestUtils {
 
     /** Class for creating string representations of 2D {@link BSPTree}s.
      */
-    public static class TreePrinter2D extends TreePrinter<Point2D> {
+    public static class TreePrinter2D extends TreePrinter<Vector2D> {
 
         /** {@inheritDoc} */
         @Override
-        protected void writeInternalNode(BSPTree<Point2D> node) {
+        protected void writeInternalNode(BSPTree<Vector2D> node) {
             SubLine cut = (SubLine) node.getCut();
             Line line = (Line) cut.getHyperplane();
             IntervalsSet remainingRegion = (IntervalsSet) cut.getRemainingRegion();
 
-            write("cut = { angle: " + Math.toDegrees(line.getAngle()) + ", origin: " + line.toSpace(Point1D.ZERO) + "}");
+            write("cut = { angle: " + Math.toDegrees(line.getAngle()) + ", origin: " + line.toSpace(Vector1D.ZERO) + "}");
             write(", remainingRegion: [");
 
             boolean isFirst = true;
@@ -333,11 +329,11 @@ public class EuclideanTestUtils {
 
     /** Class for creating string representations of 3D {@link BSPTree}s.
      */
-    public static class TreePrinter3D extends TreePrinter<Point3D> {
+    public static class TreePrinter3D extends TreePrinter<Vector3D> {
 
         /** {@inheritDoc} */
         @Override
-        protected void writeInternalNode(BSPTree<Point3D> node) {
+        protected void writeInternalNode(BSPTree<Vector3D> node) {
             SubPlane cut = (SubPlane) node.getCut();
             Plane plane = (Plane) cut.getHyperplane();
             PolygonsSet polygon = (PolygonsSet) cut.getRemainingRegion();
@@ -346,10 +342,10 @@ public class EuclideanTestUtils {
             write(", remainingRegion = [");
 
             boolean isFirst = true;
-            for (Point2D[] loop : polygon.getVertices()) {
+            for (Vector2D[] loop : polygon.getVertices()) {
                 // convert to 3-space for easier debugging
-                List<Point3D> loop3 = new ArrayList<>();
-                for (Point2D vertex : loop) {
+                List<Vector3D> loop3 = new ArrayList<>();
+                for (Vector2D vertex : loop) {
                     if (vertex != null) {
                         loop3.add(plane.toSpace(vertex));
                     }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/internal/VectorsTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/internal/VectorsTest.java
index 2264641..e9ba2f3 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/internal/VectorsTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/internal/VectorsTest.java
@@ -29,7 +29,7 @@ public class VectorsTest {
     private static final double EPS = Math.ulp(1d);
 
     @Test
-    public void testIsFiniteNonZero() {
+    public void testIsRealNonZero() {
         // act/assert
         Assert.assertTrue(Vectors.isRealNonZero(1e-20));
         Assert.assertTrue(Vectors.isRealNonZero(1e20));
@@ -37,6 +37,7 @@ public class VectorsTest {
         Assert.assertTrue(Vectors.isRealNonZero(-1e20));
 
         Assert.assertFalse(Vectors.isRealNonZero(0.0));
+        Assert.assertFalse(Vectors.isRealNonZero(-0.0));
         Assert.assertFalse(Vectors.isRealNonZero(Double.NaN));
         Assert.assertFalse(Vectors.isRealNonZero(Double.POSITIVE_INFINITY));
         Assert.assertFalse(Vectors.isRealNonZero(Double.NEGATIVE_INFINITY));
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Cartesian1DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Cartesian1DTest.java
deleted file mode 100644
index afd6ca8..0000000
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Cartesian1DTest.java
+++ /dev/null
@@ -1,90 +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.geometry.euclidean.oned;
-
-import java.util.regex.Pattern;
-
-import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class Cartesian1DTest {
-
-    private static final double TEST_TOLERANCE = 1e-15;
-
-    @Test
-    public void testCoordinates() {
-        // act/assert
-        Assert.assertEquals(0.0, new StubCartesian1D(0.0).getX(), TEST_TOLERANCE);
-        Assert.assertEquals(-1.0, new StubCartesian1D(-1.0).getX(), TEST_TOLERANCE);
-        Assert.assertEquals(1.0, new StubCartesian1D(1.0).getX(), TEST_TOLERANCE);
-
-        Assert.assertEquals(Double.NaN, new StubCartesian1D(Double.NaN).getX(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertNegativeInfinity(new StubCartesian1D(Double.NEGATIVE_INFINITY).getX());
-        EuclideanTestUtils.assertPositiveInfinity(new StubCartesian1D(Double.POSITIVE_INFINITY).getX());
-    }
-
-    @Test
-    public void testDimension() {
-        // arrange
-        Cartesian1D c = new StubCartesian1D(0.0);
-
-        // act/assert
-        Assert.assertEquals(1, c.getDimension());
-    }
-
-    @Test
-    public void testNaN() {
-        // act/assert
-        Assert.assertTrue(new StubCartesian1D(Double.NaN).isNaN());
-
-        Assert.assertFalse(new StubCartesian1D(1).isNaN());
-        Assert.assertFalse(new StubCartesian1D(Double.NEGATIVE_INFINITY).isNaN());
-    }
-
-    @Test
-    public void testInfinite() {
-        // act/assert
-        Assert.assertTrue(new StubCartesian1D(Double.NEGATIVE_INFINITY).isInfinite());
-        Assert.assertTrue(new StubCartesian1D(Double.POSITIVE_INFINITY).isInfinite());
-
-        Assert.assertFalse(new StubCartesian1D(1).isInfinite());
-        Assert.assertFalse(new StubCartesian1D(Double.NaN).isInfinite());
-    }
-
-    @Test
-    public void testToString() {
-        // arrange
-        StubCartesian1D c = new StubCartesian1D(1);
-        Pattern pattern = Pattern.compile("\\(1.{0,2}\\)");
-
-        // act
-        String str = c.toString();
-
-        // assert
-        Assert.assertTrue("Expected string " + str + " to match regex " + pattern,
-                    pattern.matcher(str).matches());
-    }
-
-    private static class StubCartesian1D extends Cartesian1D {
-        private static final long serialVersionUID = 1L;
-
-        public StubCartesian1D(double x) {
-            super(x);
-        }
-    }
-}
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/IntervalsSetTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/IntervalsSetTest.java
index f032f7b..a72f280 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/IntervalsSetTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/IntervalsSetTest.java
@@ -44,9 +44,9 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
-        BSPTree<Point1D> tree = set.getTree(true);
+        BSPTree<Vector1D> tree = set.getTree(true);
         Assert.assertEquals(Boolean.TRUE, tree.getAttribute());
         Assert.assertNull(tree.getCut());
         Assert.assertNull(tree.getMinus());
@@ -72,9 +72,9 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
-        BSPTree<Point1D> tree = set.getTree(true);
+        BSPTree<Vector1D> tree = set.getTree(true);
         Assert.assertEquals(Boolean.TRUE, tree.getAttribute());
         Assert.assertNull(tree.getCut());
         Assert.assertNull(tree.getMinus());
@@ -100,7 +100,7 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -125,7 +125,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(9.0, set.getSup(), TEST_TOLERANCE);
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -150,7 +150,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(9.0, set.getSup(), TEST_TOLERANCE);
         Assert.assertEquals(10.0, set.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.of(4.0), set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(4.0), set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -176,7 +176,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(1.0, set.getSup(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, set.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.of(1.0), set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1.0), set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -192,7 +192,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_wholeNumberLine() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
 
         // act
         IntervalsSet set = new IntervalsSet(boundaries, TEST_TOLERANCE);
@@ -203,9 +203,9 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
-        BSPTree<Point1D> tree = set.getTree(true);
+        BSPTree<Vector1D> tree = set.getTree(true);
         Assert.assertEquals(Boolean.TRUE, tree.getAttribute());
         Assert.assertNull(tree.getCut());
         Assert.assertNull(tree.getMinus());
@@ -223,7 +223,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_openInterval_positive() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(9.0, false));
 
         // act
@@ -235,7 +235,7 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -252,7 +252,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_openInterval_negative() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(9.0, true));
 
         // act
@@ -264,7 +264,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(9.0, set.getSup(), TEST_TOLERANCE);
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -281,7 +281,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_singleClosedInterval() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(-1.0, false));
         boundaries.add(subOrientedPoint(9.0, true));
 
@@ -294,7 +294,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(9.0, set.getSup(), TEST_TOLERANCE);
         Assert.assertEquals(10.0, set.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.of(4.0), set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(4.0), set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -312,7 +312,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_multipleClosedIntervals() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(-1.0, false));
         boundaries.add(subOrientedPoint(2.0, true));
         boundaries.add(subOrientedPoint(5.0, false));
@@ -327,7 +327,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(9.0, set.getSup(), TEST_TOLERANCE);
         Assert.assertEquals(7.0, set.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.of(29.5 / 7.0), set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(29.5 / 7.0), set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(2, intervals.size());
@@ -348,7 +348,7 @@ public class IntervalsSetTest {
     @Test
     public void testFromBoundaries_mixedOpenAndClosedIntervals() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(-2.0, true));
         boundaries.add(subOrientedPoint(-1.0, false));
         boundaries.add(subOrientedPoint(2.0, true));
@@ -365,7 +365,7 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.of(Double.NaN), set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(Double.NaN), set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(4, intervals.size());
@@ -393,7 +393,7 @@ public class IntervalsSetTest {
         double tolerance = 1e-3;
         double first = 1.0;
         double second = 1.0 + tolerance;
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(first, true, tolerance));
         boundaries.add(subOrientedPoint(second, false, tolerance));
 
@@ -406,7 +406,7 @@ public class IntervalsSetTest {
         Assert.assertEquals(first, set.getSup(), TEST_TOLERANCE);
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -423,7 +423,7 @@ public class IntervalsSetTest {
         double tolerance = 1e-3;
         double first = 1.0;
         double second = 1.0 - 1e-4;
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(first, false, tolerance));
         boundaries.add(subOrientedPoint(second, true, tolerance));
 
@@ -436,7 +436,7 @@ public class IntervalsSetTest {
         EuclideanTestUtils.assertPositiveInfinity(set.getSup());
         EuclideanTestUtils.assertPositiveInfinity(set.getSize());
         Assert.assertEquals(0.0, set.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector1D.NaN, set.getBarycenter(), TEST_TOLERANCE);
 
         List<Interval> intervals = set.asList();
         Assert.assertEquals(1, intervals.size());
@@ -450,7 +450,7 @@ public class IntervalsSetTest {
     @Test
     public void testProjectToBoundary() {
         // arrange
-        List<SubHyperplane<Point1D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector1D>> boundaries = new ArrayList<>();
         boundaries.add(subOrientedPoint(-2.0, true));
         boundaries.add(subOrientedPoint(-1.0, false));
         boundaries.add(subOrientedPoint(2.0, true));
@@ -461,31 +461,31 @@ public class IntervalsSetTest {
         IntervalsSet set = new IntervalsSet(boundaries, TEST_TOLERANCE);
 
         // act/assert
-        assertProjection(Point1D.of(-2), -1, set, Point1D.of(-3));
-        assertProjection(Point1D.of(-2), 0, set, Point1D.of(-2));
-        assertProjection(Point1D.of(-2), 0.1, set, Point1D.of(-1.9));
+        assertProjection(Vector1D.of(-2), -1, set, Vector1D.of(-3));
+        assertProjection(Vector1D.of(-2), 0, set, Vector1D.of(-2));
+        assertProjection(Vector1D.of(-2), 0.1, set, Vector1D.of(-1.9));
 
-        assertProjection(Point1D.of(-1), 0.5, set, Point1D.of(-1.5));
-        assertProjection(Point1D.of(-1), 0.1, set, Point1D.of(-1.1));
-        assertProjection(Point1D.of(-1), 0, set, Point1D.of(-1));
-        assertProjection(Point1D.of(-1), -1, set, Point1D.of(0));
+        assertProjection(Vector1D.of(-1), 0.5, set, Vector1D.of(-1.5));
+        assertProjection(Vector1D.of(-1), 0.1, set, Vector1D.of(-1.1));
+        assertProjection(Vector1D.of(-1), 0, set, Vector1D.of(-1));
+        assertProjection(Vector1D.of(-1), -1, set, Vector1D.of(0));
 
-        assertProjection(Point1D.of(2), -1, set, Point1D.of(1));
-        assertProjection(Point1D.of(2), 0, set, Point1D.of(2));
-        assertProjection(Point1D.of(2), 1, set, Point1D.of(3));
+        assertProjection(Vector1D.of(2), -1, set, Vector1D.of(1));
+        assertProjection(Vector1D.of(2), 0, set, Vector1D.of(2));
+        assertProjection(Vector1D.of(2), 1, set, Vector1D.of(3));
 
-        assertProjection(Point1D.of(5), 1, set, Point1D.of(4));
-        assertProjection(Point1D.of(5), 0, set, Point1D.of(5));
+        assertProjection(Vector1D.of(5), 1, set, Vector1D.of(4));
+        assertProjection(Vector1D.of(5), 0, set, Vector1D.of(5));
 
-        assertProjection(Point1D.of(5), -1, set, Point1D.of(6));
-        assertProjection(Point1D.of(5), -2, set, Point1D.of(7));
+        assertProjection(Vector1D.of(5), -1, set, Vector1D.of(6));
+        assertProjection(Vector1D.of(5), -2, set, Vector1D.of(7));
 
-        assertProjection(Point1D.of(9), -1, set, Point1D.of(8));
-        assertProjection(Point1D.of(9), 0, set, Point1D.of(9));
-        assertProjection(Point1D.of(9), 0.1, set, Point1D.of(9.1));
+        assertProjection(Vector1D.of(9), -1, set, Vector1D.of(8));
+        assertProjection(Vector1D.of(9), 0, set, Vector1D.of(9));
+        assertProjection(Vector1D.of(9), 0.1, set, Vector1D.of(9.1));
 
-        assertProjection(Point1D.of(10), 0, set, Point1D.of(10));
-        assertProjection(Point1D.of(10), -1, set, Point1D.of(11));
+        assertProjection(Vector1D.of(10), 0, set, Vector1D.of(10));
+        assertProjection(Vector1D.of(10), -1, set, Vector1D.of(11));
     }
 
     @Test
@@ -493,11 +493,11 @@ public class IntervalsSetTest {
         IntervalsSet set = new IntervalsSet(2.3, 5.7, 1.0e-10);
         Assert.assertEquals(3.4, set.getSize(), 1.0e-10);
         Assert.assertEquals(4.0, set.getBarycenter().getX(), 1.0e-10);
-        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Point1D.of(2.3)));
-        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Point1D.of(5.7)));
-        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Point1D.of(1.2)));
-        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Point1D.of(8.7)));
-        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(Point1D.of(3.0)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Vector1D.of(2.3)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Vector1D.of(5.7)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Vector1D.of(1.2)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Vector1D.of(8.7)));
+        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(Vector1D.of(3.0)));
         Assert.assertEquals(2.3, set.getInf(), 1.0e-10);
         Assert.assertEquals(5.7, set.getSup(), 1.0e-10);
     }
@@ -505,17 +505,17 @@ public class IntervalsSetTest {
     @Test
     public void testInfinite() {
         IntervalsSet set = new IntervalsSet(9.0, Double.POSITIVE_INFINITY, 1.0e-10);
-        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Point1D.of(9.0)));
-        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Point1D.of(8.4)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(Vector1D.of(9.0)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(Vector1D.of(8.4)));
         for (double e = 1.0; e <= 6.0; e += 1.0) {
             Assert.assertEquals(Region.Location.INSIDE,
-                                set.checkPoint(Point1D.of(Math.pow(10.0, e))));
+                                set.checkPoint(Vector1D.of(Math.pow(10.0, e))));
         }
         Assert.assertTrue(Double.isInfinite(set.getSize()));
         Assert.assertEquals(9.0, set.getInf(), 1.0e-10);
         Assert.assertTrue(Double.isInfinite(set.getSup()));
 
-        set = (IntervalsSet) new RegionFactory<Point1D>().getComplement(set);
+        set = (IntervalsSet) new RegionFactory<Vector1D>().getComplement(set);
         Assert.assertEquals(9.0, set.getSup(), 1.0e-10);
         Assert.assertTrue(Double.isInfinite(set.getInf()));
 
@@ -524,7 +524,7 @@ public class IntervalsSetTest {
     @Test
     public void testBooleanOperations() {
         // arrange
-        RegionFactory<Point1D> factory = new RegionFactory<>();
+        RegionFactory<Vector1D> factory = new RegionFactory<>();
 
         // act
         IntervalsSet set = (IntervalsSet)
@@ -558,7 +558,7 @@ public class IntervalsSetTest {
     }
 
     private void assertLocation(Region.Location location, IntervalsSet set, double pt) {
-        Assert.assertEquals(location, set.checkPoint(Point1D.of(pt)));
+        Assert.assertEquals(location, set.checkPoint(Vector1D.of(pt)));
     }
 
     private void assertInterval(double expectedInf, double expectedSup, Interval actual, double tolerance) {
@@ -566,9 +566,9 @@ public class IntervalsSetTest {
         Assert.assertEquals(expectedSup, actual.getSup(), tolerance);
     }
 
-    private void assertProjection(Point1D expectedProjection, double expectedOffset,
-            IntervalsSet set, Point1D toProject) {
-        BoundaryProjection<Point1D> proj = set.projectToBoundary(toProject);
+    private void assertProjection(Vector1D expectedProjection, double expectedOffset,
+            IntervalsSet set, Vector1D toProject) {
+        BoundaryProjection<Vector1D> proj = set.projectToBoundary(toProject);
 
         EuclideanTestUtils.assertCoordinatesEqual(toProject, proj.getOriginal(), TEST_TOLERANCE);
         EuclideanTestUtils.assertCoordinatesEqual(expectedProjection, proj.getProjected(), TEST_TOLERANCE);
@@ -581,6 +581,6 @@ public class IntervalsSetTest {
 
     private SubOrientedPoint subOrientedPoint(double location, boolean direct, double tolerance) {
         // the remaining region isn't necessary for creating 1D boundaries so we can set it to null here
-        return new SubOrientedPoint(new OrientedPoint(Point1D.of(location), direct, tolerance), null);
+        return new SubOrientedPoint(new OrientedPoint(Vector1D.of(location), direct, tolerance), null);
     }
 }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/OrientedPointTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/OrientedPointTest.java
index 37140ca..764ac26 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/OrientedPointTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/OrientedPointTest.java
@@ -26,7 +26,7 @@ public class OrientedPointTest {
     @Test
     public void testConstructor() {
         // act
-        OrientedPoint pt = new OrientedPoint(Point1D.of(2.0), true, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(2.0), true, 1e-5);
 
         // assert
         Assert.assertEquals(2.0, pt.getLocation().getX(), Precision.EPSILON);
@@ -37,7 +37,7 @@ public class OrientedPointTest {
     @Test
     public void testCopySelf() {
         // arrange
-        OrientedPoint orig = new OrientedPoint(Point1D.of(2.0), true, 1e-5);
+        OrientedPoint orig = new OrientedPoint(Vector1D.of(2.0), true, 1e-5);
 
         // act
         OrientedPoint copy = orig.copySelf();
@@ -52,37 +52,37 @@ public class OrientedPointTest {
     @Test
     public void testGetOffset_direct_point() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(-1.0), true, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(-1.0), true, 1e-5);
 
         // act/assert
-        Assert.assertEquals(-99, pt.getOffset(Point1D.of(-100)), Precision.EPSILON);
-        Assert.assertEquals(-1, pt.getOffset(Point1D.of(-2)), Precision.EPSILON);
-        Assert.assertEquals(-0.01, pt.getOffset(Point1D.of(-1.01)), Precision.EPSILON);
-        Assert.assertEquals(0.0, pt.getOffset(Point1D.of(-1.0)), Precision.EPSILON);
-        Assert.assertEquals(0.01, pt.getOffset(Point1D.of(-0.99)), Precision.EPSILON);
-        Assert.assertEquals(1, pt.getOffset(Point1D.of(0)), Precision.EPSILON);
-        Assert.assertEquals(101, pt.getOffset(Point1D.of(100)), Precision.EPSILON);
+        Assert.assertEquals(-99, pt.getOffset(Vector1D.of(-100)), Precision.EPSILON);
+        Assert.assertEquals(-1, pt.getOffset(Vector1D.of(-2)), Precision.EPSILON);
+        Assert.assertEquals(-0.01, pt.getOffset(Vector1D.of(-1.01)), Precision.EPSILON);
+        Assert.assertEquals(0.0, pt.getOffset(Vector1D.of(-1.0)), Precision.EPSILON);
+        Assert.assertEquals(0.01, pt.getOffset(Vector1D.of(-0.99)), Precision.EPSILON);
+        Assert.assertEquals(1, pt.getOffset(Vector1D.of(0)), Precision.EPSILON);
+        Assert.assertEquals(101, pt.getOffset(Vector1D.of(100)), Precision.EPSILON);
     }
 
     @Test
     public void testGetOffset_notDirect_point() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(-1.0), false, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(-1.0), false, 1e-5);
 
         // act/assert
-        Assert.assertEquals(99, pt.getOffset(Point1D.of(-100)), Precision.EPSILON);
-        Assert.assertEquals(1, pt.getOffset(Point1D.of(-2)), Precision.EPSILON);
-        Assert.assertEquals(0.01, pt.getOffset(Point1D.of(-1.01)), Precision.EPSILON);
-        Assert.assertEquals(0.0, pt.getOffset(Point1D.of(-1.0)), Precision.EPSILON);
-        Assert.assertEquals(-0.01, pt.getOffset(Point1D.of(-0.99)), Precision.EPSILON);
-        Assert.assertEquals(-1, pt.getOffset(Point1D.of(0)), Precision.EPSILON);
-        Assert.assertEquals(-101, pt.getOffset(Point1D.of(100)), Precision.EPSILON);
+        Assert.assertEquals(99, pt.getOffset(Vector1D.of(-100)), Precision.EPSILON);
+        Assert.assertEquals(1, pt.getOffset(Vector1D.of(-2)), Precision.EPSILON);
+        Assert.assertEquals(0.01, pt.getOffset(Vector1D.of(-1.01)), Precision.EPSILON);
+        Assert.assertEquals(0.0, pt.getOffset(Vector1D.of(-1.0)), Precision.EPSILON);
+        Assert.assertEquals(-0.01, pt.getOffset(Vector1D.of(-0.99)), Precision.EPSILON);
+        Assert.assertEquals(-1, pt.getOffset(Vector1D.of(0)), Precision.EPSILON);
+        Assert.assertEquals(-101, pt.getOffset(Vector1D.of(100)), Precision.EPSILON);
     }
 
     @Test
     public void testWholeHyperplane() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(1.0), false, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(1.0), false, 1e-5);
 
         // act
         SubOrientedPoint subPt = pt.wholeHyperplane();
@@ -95,7 +95,7 @@ public class OrientedPointTest {
     @Test
     public void testWholeSpace() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(1.0), false, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(1.0), false, 1e-5);
 
         // act
         IntervalsSet set = pt.wholeSpace();
@@ -108,10 +108,10 @@ public class OrientedPointTest {
     @Test
     public void testSameOrientationAs() {
         // arrange
-        OrientedPoint notDirect1 = new OrientedPoint(Point1D.of(1.0), false, 1e-5);
-        OrientedPoint notDirect2 = new OrientedPoint(Point1D.of(1.0), false, 1e-5);
-        OrientedPoint direct1 = new OrientedPoint(Point1D.of(1.0), true, 1e-5);
-        OrientedPoint direct2 = new OrientedPoint(Point1D.of(1.0), true, 1e-5);
+        OrientedPoint notDirect1 = new OrientedPoint(Vector1D.of(1.0), false, 1e-5);
+        OrientedPoint notDirect2 = new OrientedPoint(Vector1D.of(1.0), false, 1e-5);
+        OrientedPoint direct1 = new OrientedPoint(Vector1D.of(1.0), true, 1e-5);
+        OrientedPoint direct2 = new OrientedPoint(Vector1D.of(1.0), true, 1e-5);
 
         // act/assert
         Assert.assertTrue(notDirect1.sameOrientationAs(notDirect1));
@@ -129,19 +129,19 @@ public class OrientedPointTest {
     @Test
     public void testProject() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(1.0), true, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(1.0), true, 1e-5);
 
         // act/assert
-        Assert.assertEquals(1.0, pt.project(Point1D.of(-1.0)).getX(), Precision.EPSILON);
-        Assert.assertEquals(1.0, pt.project(Point1D.of(0.0)).getX(), Precision.EPSILON);
-        Assert.assertEquals(1.0, pt.project(Point1D.of(1.0)).getX(), Precision.EPSILON);
-        Assert.assertEquals(1.0, pt.project(Point1D.of(100.0)).getX(), Precision.EPSILON);
+        Assert.assertEquals(1.0, pt.project(Vector1D.of(-1.0)).getX(), Precision.EPSILON);
+        Assert.assertEquals(1.0, pt.project(Vector1D.of(0.0)).getX(), Precision.EPSILON);
+        Assert.assertEquals(1.0, pt.project(Vector1D.of(1.0)).getX(), Precision.EPSILON);
+        Assert.assertEquals(1.0, pt.project(Vector1D.of(100.0)).getX(), Precision.EPSILON);
     }
 
     @Test
     public void testRevertSelf() {
         // arrange
-        OrientedPoint pt = new OrientedPoint(Point1D.of(2.0), true, 1e-5);
+        OrientedPoint pt = new OrientedPoint(Vector1D.of(2.0), true, 1e-5);
 
         // act
         pt.revertSelf();
@@ -151,7 +151,7 @@ public class OrientedPointTest {
         Assert.assertFalse(pt.isDirect());
         Assert.assertEquals(1e-5, pt.getTolerance(), Precision.EPSILON);
 
-        Assert.assertEquals(1, pt.getOffset(Point1D.of(1.0)), Precision.EPSILON);
-        Assert.assertEquals(-1, pt.getOffset(Point1D.of(3.0)), Precision.EPSILON);
+        Assert.assertEquals(1, pt.getOffset(Vector1D.of(1.0)), Precision.EPSILON);
+        Assert.assertEquals(-1, pt.getOffset(Vector1D.of(3.0)), Precision.EPSILON);
     }
 }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Point1DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Point1DTest.java
deleted file mode 100644
index 1b40bf2..0000000
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Point1DTest.java
+++ /dev/null
@@ -1,333 +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.geometry.euclidean.oned;
-
-import java.util.regex.Pattern;
-
-import org.apache.commons.geometry.core.GeometryTestUtils;
-import org.apache.commons.geometry.core.exception.IllegalNormException;
-import org.apache.commons.numbers.core.Precision;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class Point1DTest {
-
-    private static final double TEST_TOLERANCE = 1e-15;
-
-    @Test
-    public void testConstants() {
-        // act/assert
-        checkPoint(Point1D.ZERO, 0.0);
-        checkPoint(Point1D.ONE, 1.0);
-        checkPoint(Point1D.MINUS_ONE, -1.0);
-        checkPoint(Point1D.NaN, Double.NaN);
-        checkPoint(Point1D.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-        checkPoint(Point1D.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-    }
-
-    @Test
-    public void testAsVector() {
-        // act/assert
-        checkVector(Point1D.of(0).asVector(), 0.0);
-        checkVector(Point1D.of(1).asVector(), 1.0);
-        checkVector(Point1D.of(-1).asVector(), -1.0);
-        checkVector(Point1D.NaN.asVector(), Double.NaN);
-        checkVector(Point1D.POSITIVE_INFINITY.asVector(), Double.POSITIVE_INFINITY);
-        checkVector(Point1D.NEGATIVE_INFINITY.asVector(), Double.NEGATIVE_INFINITY);
-    }
-
-    @Test
-    public void testDistance() {
-        // arrange
-        Point1D p1 = Point1D.of(1);
-        Point1D p2 = Point1D.of(-4);
-        Point1D p3 = Point1D.of(10);
-
-        // act/assert
-        Assert.assertEquals(0.0, p1.distance(p1), TEST_TOLERANCE);
-        Assert.assertEquals(0.0, p2.distance(p2), TEST_TOLERANCE);
-        Assert.assertEquals(0.0, p3.distance(p3), TEST_TOLERANCE);
-
-        Assert.assertEquals(5.0, p1.distance(p2), TEST_TOLERANCE);
-        Assert.assertEquals(5.0, p2.distance(p1), TEST_TOLERANCE);
-
-        Assert.assertEquals(9.0, p1.distance(p3), TEST_TOLERANCE);
-        Assert.assertEquals(9.0, p3.distance(p1), TEST_TOLERANCE);
-
-        Assert.assertEquals(14.0, p2.distance(p3), TEST_TOLERANCE);
-        Assert.assertEquals(14.0, p3.distance(p2), TEST_TOLERANCE);
-
-        Assert.assertEquals(0.0, Point1D.of(-1).distance(Point1D.of(-1)), TEST_TOLERANCE);
-    }
-
-    @Test
-    public void testSubtract() {
-        // arrange
-        Point1D p1 = Point1D.of(1);
-        Point1D p2 = Point1D.of(-4);
-        Point1D p3 = Point1D.of(10);
-
-        // act/assert
-        checkVector(p1.subtract(p1), 0.0);
-        checkVector(p2.subtract(p2), 0.0);
-        checkVector(p3.subtract(p3), 0.0);
-
-        checkVector(p1.subtract(p2), 5.0);
-        checkVector(p2.subtract(p1), -5.0);
-
-        checkVector(p1.subtract(p3), -9.0);
-        checkVector(p3.subtract(p1), 9.0);
-
-        checkVector(p2.subtract(p3), -14.0);
-        checkVector(p3.subtract(p2), 14.0);
-    }
-
-    @Test
-    public void testVectorTo() {
-        // arrange
-        Point1D p1 = Point1D.of(1);
-        Point1D p2 = Point1D.of(-4);
-        Point1D p3 = Point1D.of(10);
-
-        // act/assert
-        checkVector(p1.vectorTo(p1), 0.0);
-        checkVector(p2.vectorTo(p2), 0.0);
-        checkVector(p3.vectorTo(p3), 0.0);
-
-        checkVector(p1.vectorTo(p2), -5.0);
-        checkVector(p2.vectorTo(p1), 5.0);
-
-        checkVector(p1.vectorTo(p3), 9.0);
-        checkVector(p3.vectorTo(p1), -9.0);
-
-        checkVector(p2.vectorTo(p3), 14.0);
-        checkVector(p3.vectorTo(p2), -14.0);
-    }
-
-    @Test
-    public void testDirectionTo() {
-        // act/assert
-        Point1D p1 = Point1D.of(1);
-        Point1D p2 = Point1D.of(5);
-        Point1D p3 = Point1D.of(-2);
-
-        // act/assert
-        checkVector(p1.directionTo(p2), 1);
-        checkVector(p2.directionTo(p1), -1);
-
-        checkVector(p1.directionTo(p3), -1);
-        checkVector(p3.directionTo(p1), 1);
-    }
-
-    @Test
-    public void testDirectionTo_illegalNorm() {
-        // arrange
-        Point1D p = Point1D.of(2);
-
-        // act/assert
-        GeometryTestUtils.assertThrows(() -> Point1D.ZERO.directionTo(Point1D.ZERO),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(p),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(Point1D.NaN),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> Point1D.NEGATIVE_INFINITY.directionTo(p),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(Point1D.POSITIVE_INFINITY),
-                IllegalNormException.class);
-    }
-
-    @Test
-    public void testLerp() {
-        // arrange
-        Point1D p1 = Point1D.of(1);
-        Point1D p2 = Point1D.of(-4);
-        Point1D p3 = Point1D.of(10);
-
-        // act/assert
-        checkPoint(p1.lerp(p1, 0), 1);
-        checkPoint(p1.lerp(p1, 1), 1);
-
-        checkPoint(p1.lerp(p2, -0.25), 2.25);
-        checkPoint(p1.lerp(p2, 0), 1);
-        checkPoint(p1.lerp(p2, 0.25), -0.25);
-        checkPoint(p1.lerp(p2, 0.5), -1.5);
-        checkPoint(p1.lerp(p2, 0.75), -2.75);
-        checkPoint(p1.lerp(p2, 1), -4);
-        checkPoint(p1.lerp(p2, 1.25), -5.25);
-
-        checkPoint(p1.lerp(p3, 0), 1);
-        checkPoint(p1.lerp(p3, 0.25), 3.25);
-        checkPoint(p1.lerp(p3, 0.5), 5.5);
-        checkPoint(p1.lerp(p3, 0.75), 7.75);
-        checkPoint(p1.lerp(p3, 1), 10);
-    }
-
-    @Test
-    public void testAdd() {
-        // arrange
-        Point1D p1 = Point1D.of(2.0);
-        Point1D p2 = Point1D.of(-2.0);
-
-        // act/assert
-        checkPoint(p1.add(Vector1D.ZERO), 2.0);
-        checkPoint(p1.add(Vector1D.of(1)), 3.0);
-        checkPoint(p1.add(Vector1D.of(-1)), 1.0);
-
-        checkPoint(p2.add(Vector1D.ZERO), -2.0);
-        checkPoint(p2.add(Vector1D.of(1)), -1.0);
-        checkPoint(p2.add(Vector1D.of(-1)), -3.0);
-    }
-
-    @Test
-    public void testHashCode() {
-        // arrange
-        Point1D u = Point1D.of(1);
-        Point1D v = Point1D.of(1 + 10 * Precision.EPSILON);
-        Point1D w = Point1D.of(1);
-
-        // act/assert
-        Assert.assertTrue(u.hashCode() != v.hashCode());
-        Assert.assertEquals(u.hashCode(), w.hashCode());
-
-        Assert.assertEquals(Point1D.of(Double.NaN).hashCode(), Point1D.NaN.hashCode());
-        Assert.assertEquals(Point1D.of(Double.NaN).hashCode(), Point1D.of(Double.NaN).hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        // arrange
-        Point1D u1 = Point1D.of(1);
-        Point1D u2 = Point1D.of(1);
-
-        // act/assert
-        Assert.assertFalse(u1.equals(null));
-        Assert.assertFalse(u1.equals(new Object()));
-
-        Assert.assertTrue(u1.equals(u1));
-        Assert.assertTrue(u1.equals(u2));
-
-        Assert.assertFalse(u1.equals(Point1D.of(-1)));
-        Assert.assertFalse(u1.equals(Point1D.of(1 + 10 * Precision.EPSILON)));
-
-        Assert.assertTrue(Point1D.of(Double.NaN).equals(Point1D.of(Double.NaN)));
-        Assert.assertTrue(Point1D.of(Double.POSITIVE_INFINITY).equals(Point1D.of(Double.POSITIVE_INFINITY)));
-        Assert.assertTrue(Point1D.of(Double.NEGATIVE_INFINITY).equals(Point1D.of(Double.NEGATIVE_INFINITY)));
-    }
-
-    @Test
-    public void testToString() {
-        // arrange
-        Point1D p = Point1D.of(3);
-        Pattern pattern = Pattern.compile("\\(3.{0,2}\\)");
-
-        // act
-        String str = p.toString();
-
-        // assert
-        Assert.assertTrue("Expected string " + str + " to match regex " + pattern,
-                    pattern.matcher(str).matches());
-    }
-
-    @Test
-    public void testParse() {
-        // act/assert
-        checkPoint(Point1D.parse("(1)"), 1);
-        checkPoint(Point1D.parse("(-1)"), -1);
-
-        checkPoint(Point1D.parse("(0.01)"), 1e-2);
-        checkPoint(Point1D.parse("(-1e-3)"), -1e-3);
-
-        checkPoint(Point1D.parse("(NaN)"), Double.NaN);
-
-        checkPoint(Point1D.parse(Point1D.ZERO.toString()), 0);
-        checkPoint(Point1D.parse(Point1D.ONE.toString()), 1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testParse_failure() {
-        // act/assert
-        Point1D.parse("abc");
-    }
-
-    @Test
-    public void testOf() {
-        // act/assert
-        checkPoint(Point1D.of(0), 0.0);
-        checkPoint(Point1D.of(-1), -1.0);
-        checkPoint(Point1D.of(1), 1.0);
-        checkPoint(Point1D.of(Math.PI), Math.PI);
-        checkPoint(Point1D.of(Double.NaN), Double.NaN);
-        checkPoint(Point1D.of(Double.NEGATIVE_INFINITY), Double.NEGATIVE_INFINITY);
-        checkPoint(Point1D.of(Double.POSITIVE_INFINITY), Double.POSITIVE_INFINITY);
-    }
-
-    @Test
-    public void testVectorCombination() {
-        // act/assert
-        checkPoint(Point1D.vectorCombination(2, Point1D.of(3)), 6);
-        checkPoint(Point1D.vectorCombination(-2, Point1D.of(3)), -6);
-    }
-
-    @Test
-    public void testVectorCombination2() {
-        // act/assert
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                5, Point1D.of(7)), 41);
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                -5, Point1D.of(7)),-29);
-    }
-
-    @Test
-    public void testVectorCombination3() {
-        // act/assert
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                5, Point1D.of(7),
-                11, Point1D.of(13)), 184);
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                5, Point1D.of(7),
-                -11, Point1D.of(13)), -102);
-    }
-
-    @Test
-    public void testVectorCombination4() {
-        // act/assert
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                5, Point1D.of(7),
-                11, Point1D.of(13),
-                17, Point1D.of(19)), 507);
-        checkPoint(Point1D.vectorCombination(
-                2, Point1D.of(3),
-                5, Point1D.of(7),
-                11, Point1D.of(13),
-                -17, Point1D.of(19)), -139);
-    }
-
-    private void checkPoint(Point1D p, double x) {
-        Assert.assertEquals(x, p.getX(), TEST_TOLERANCE);
-    }
-
-    private void checkVector(Vector1D v, double x) {
-        Assert.assertEquals(x, v.getX(), TEST_TOLERANCE);
-    }
-}
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPointTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPointTest.java
index ab3c9d9..14d7286 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPointTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/SubOrientedPointTest.java
@@ -28,7 +28,7 @@ public class SubOrientedPointTest {
     @Test
     public void testGetSize() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         SubOrientedPoint pt = hyperplane.wholeHyperplane();
 
         // act/assert
@@ -38,7 +38,7 @@ public class SubOrientedPointTest {
     @Test
     public void testIsEmpty() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         SubOrientedPoint pt = hyperplane.wholeHyperplane();
 
         // act/assert
@@ -48,14 +48,14 @@ public class SubOrientedPointTest {
     @Test
     public void testBuildNew() {
         // arrange
-        OrientedPoint originalHyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint originalHyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         SubOrientedPoint pt = originalHyperplane.wholeHyperplane();
 
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(2), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(2), true, TEST_TOLERANCE);
         IntervalsSet intervals = new IntervalsSet(2, 3, TEST_TOLERANCE);
 
         // act
-        SubHyperplane<Point1D> result = pt.buildNew(hyperplane, intervals);
+        SubHyperplane<Vector1D> result = pt.buildNew(hyperplane, intervals);
 
         // assert
         Assert.assertTrue(result instanceof SubOrientedPoint);
@@ -66,14 +66,14 @@ public class SubOrientedPointTest {
     @Test
     public void testSplit_resultOnMinusSide() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         IntervalsSet interval = new IntervalsSet(TEST_TOLERANCE);
         SubOrientedPoint pt = new SubOrientedPoint(hyperplane, interval);
 
-        OrientedPoint splitter = new OrientedPoint(Point1D.of(2), true, TEST_TOLERANCE);
+        OrientedPoint splitter = new OrientedPoint(Vector1D.of(2), true, TEST_TOLERANCE);
 
         // act
-        SplitSubHyperplane<Point1D> split = pt.split(splitter);
+        SplitSubHyperplane<Vector1D> split = pt.split(splitter);
 
         // assert
         Assert.assertEquals(Side.MINUS, split.getSide());
@@ -92,14 +92,14 @@ public class SubOrientedPointTest {
     @Test
     public void testSplit_resultOnPlusSide() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         IntervalsSet interval = new IntervalsSet(TEST_TOLERANCE);
         SubOrientedPoint pt = new SubOrientedPoint(hyperplane, interval);
 
-        OrientedPoint splitter = new OrientedPoint(Point1D.of(0), true, TEST_TOLERANCE);
+        OrientedPoint splitter = new OrientedPoint(Vector1D.of(0), true, TEST_TOLERANCE);
 
         // act
-        SplitSubHyperplane<Point1D> split = pt.split(splitter);
+        SplitSubHyperplane<Vector1D> split = pt.split(splitter);
 
         // assert
         Assert.assertEquals(Side.PLUS, split.getSide());
@@ -118,14 +118,14 @@ public class SubOrientedPointTest {
     @Test
     public void testSplit_equivalentHyperplanes() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
         IntervalsSet interval = new IntervalsSet(TEST_TOLERANCE);
         SubOrientedPoint pt = new SubOrientedPoint(hyperplane, interval);
 
-        OrientedPoint splitter = new OrientedPoint(Point1D.of(1), true, TEST_TOLERANCE);
+        OrientedPoint splitter = new OrientedPoint(Vector1D.of(1), true, TEST_TOLERANCE);
 
         // act
-        SplitSubHyperplane<Point1D> split = pt.split(splitter);
+        SplitSubHyperplane<Vector1D> split = pt.split(splitter);
 
         // assert
         Assert.assertEquals(Side.HYPER, split.getSide());
@@ -137,23 +137,23 @@ public class SubOrientedPointTest {
     @Test
     public void testSplit_usesToleranceFromParentHyperplane() {
         // arrange
-        OrientedPoint hyperplane = new OrientedPoint(Point1D.of(1), true, 0.1);
+        OrientedPoint hyperplane = new OrientedPoint(Vector1D.of(1), true, 0.1);
         SubOrientedPoint pt = hyperplane.wholeHyperplane();
 
         // act/assert
-        SplitSubHyperplane<Point1D> plusSplit = pt.split(new OrientedPoint(Point1D.of(0.899), true, 1e-10));
+        SplitSubHyperplane<Vector1D> plusSplit = pt.split(new OrientedPoint(Vector1D.of(0.899), true, 1e-10));
         Assert.assertNull(plusSplit.getMinus());
         Assert.assertNotNull(plusSplit.getPlus());
 
-        SplitSubHyperplane<Point1D> lowWithinTolerance = pt.split(new OrientedPoint(Point1D.of(0.901), true, 1e-10));
+        SplitSubHyperplane<Vector1D> lowWithinTolerance = pt.split(new OrientedPoint(Vector1D.of(0.901), true, 1e-10));
         Assert.assertNull(lowWithinTolerance.getMinus());
         Assert.assertNull(lowWithinTolerance.getPlus());
 
-        SplitSubHyperplane<Point1D> highWithinTolerance = pt.split(new OrientedPoint(Point1D.of(1.09), true, 1e-10));
+        SplitSubHyperplane<Vector1D> highWithinTolerance = pt.split(new OrientedPoint(Vector1D.of(1.09), true, 1e-10));
         Assert.assertNull(highWithinTolerance.getMinus());
         Assert.assertNull(highWithinTolerance.getPlus());
 
-        SplitSubHyperplane<Point1D> minusSplit = pt.split(new OrientedPoint(Point1D.of(1.101), true, 1e-10));
+        SplitSubHyperplane<Vector1D> minusSplit = pt.split(new OrientedPoint(Vector1D.of(1.101), true, 1e-10));
         Assert.assertNotNull(minusSplit.getMinus());
         Assert.assertNull(minusSplit.getPlus());
     }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
index df90a7a..60241e6 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
@@ -57,14 +57,39 @@ public class Vector1DTest {
     }
 
     @Test
-    public void testAsPoint() {
+    public void testCoordinates() {
         // act/assert
-        checkPoint(Vector1D.of(0.0).asPoint(), 0.0);
-        checkPoint(Vector1D.of(1.0).asPoint(), 1.0);
-        checkPoint(Vector1D.of(-1.0).asPoint(), -1.0);
-        checkPoint(Vector1D.of(Double.NaN).asPoint(), Double.NaN);
-        checkPoint(Vector1D.of(Double.NEGATIVE_INFINITY).asPoint(), Double.NEGATIVE_INFINITY);
-        checkPoint(Vector1D.of(Double.POSITIVE_INFINITY).asPoint(), Double.POSITIVE_INFINITY);
+        Assert.assertEquals(-1, Vector1D.of(-1).getX(), 0.0);
+        Assert.assertEquals(0, Vector1D.of(0).getX(), 0.0);
+        Assert.assertEquals(1, Vector1D.of(1).getX(), 0.0);
+    }
+
+    @Test
+    public void testDimension() {
+        // arrange
+        Vector1D v = Vector1D.of(2);
+
+        // act/assert
+        Assert.assertEquals(1, v.getDimension());
+    }
+
+    @Test
+    public void testNaN() {
+        // act/assert
+        Assert.assertTrue(Vector1D.of(Double.NaN).isNaN());
+
+        Assert.assertFalse(Vector1D.of(1).isNaN());
+        Assert.assertFalse(Vector1D.of(Double.NEGATIVE_INFINITY).isNaN());
+    }
+
+    @Test
+    public void testInfinite() {
+        // act/assert
+        Assert.assertTrue(Vector1D.of(Double.NEGATIVE_INFINITY).isInfinite());
+        Assert.assertTrue(Vector1D.of(Double.POSITIVE_INFINITY).isInfinite());
+
+        Assert.assertFalse(Vector1D.of(1).isInfinite());
+        Assert.assertFalse(Vector1D.of(Double.NaN).isInfinite());
     }
 
     @Test
@@ -74,7 +99,7 @@ public class Vector1DTest {
 
         // assert
         checkVector(zero, 0.0);
-        checkPoint(Point1D.ONE.add(zero), 1.0);
+        checkVector(Vector1D.ONE.add(zero), 1.0);
     }
 
     @Test
@@ -343,6 +368,61 @@ public class Vector1DTest {
     }
 
     @Test
+    public void testVectorTo() {
+        // arrange
+        Vector1D v1 = Vector1D.of(1);
+        Vector1D v2 = Vector1D.of(-4);
+        Vector1D v3 = Vector1D.of(10);
+
+        // act/assert
+        checkVector(v1.vectorTo(v1), 0.0);
+        checkVector(v2.vectorTo(v2), 0.0);
+        checkVector(v3.vectorTo(v3), 0.0);
+
+        checkVector(v1.vectorTo(v2), -5.0);
+        checkVector(v2.vectorTo(v1), 5.0);
+
+        checkVector(v1.vectorTo(v3), 9.0);
+        checkVector(v3.vectorTo(v1), -9.0);
+
+        checkVector(v2.vectorTo(v3), 14.0);
+        checkVector(v3.vectorTo(v2), -14.0);
+    }
+
+    @Test
+    public void testDirectionTo() {
+        // act/assert
+        Vector1D v1 = Vector1D.of(1);
+        Vector1D v2 = Vector1D.of(5);
+        Vector1D v3 = Vector1D.of(-2);
+
+        // act/assert
+        checkVector(v1.directionTo(v2), 1);
+        checkVector(v2.directionTo(v1), -1);
+
+        checkVector(v1.directionTo(v3), -1);
+        checkVector(v3.directionTo(v1), 1);
+    }
+
+    @Test
+    public void testDirectionTo_illegalNorm() {
+        // arrange
+        Vector1D v = Vector1D.of(2);
+
+        // act/assert
+        GeometryTestUtils.assertThrows(() -> Vector1D.ZERO.directionTo(Vector1D.ZERO),
+                IllegalNormException.class);
+        GeometryTestUtils.assertThrows(() -> v.directionTo(v),
+                IllegalNormException.class);
+        GeometryTestUtils.assertThrows(() -> v.directionTo(Vector1D.NaN),
+                IllegalNormException.class);
+        GeometryTestUtils.assertThrows(() -> Vector1D.NEGATIVE_INFINITY.directionTo(v),
+                IllegalNormException.class);
+        GeometryTestUtils.assertThrows(() -> v.directionTo(Vector1D.POSITIVE_INFINITY),
+                IllegalNormException.class);
+    }
+
+    @Test
     public void testLerp() {
         // arrange
         Vector1D v1 = Vector1D.of(1);
@@ -516,10 +596,6 @@ public class Vector1DTest {
                 -17, Vector1D.of(19)), -139);
     }
 
-    private void checkPoint(Point1D p, double x) {
-        Assert.assertEquals(x, p.getX(), TEST_TOLERANCE);
-    }
-
     private void checkVector(Vector1D v, double x) {
         Assert.assertEquals(x, v.getX(), TEST_TOLERANCE);
     }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java
deleted file mode 100644
index 8d47105..0000000
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Cartesian3DTest.java
+++ /dev/null
@@ -1,144 +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.geometry.euclidean.threed;
-
-import java.util.regex.Pattern;
-
-import org.apache.commons.geometry.core.Geometry;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class Cartesian3DTest {
-
-    private static final double TEST_TOLERANCE = 1e-15;
-
-    @Test
-    public void testCoordinates() {
-        // arrange
-        Cartesian3D c = new StubCartesian3D(1, 2, 3);
-
-        // act/assert
-        Assert.assertEquals(1.0, c.getX(), TEST_TOLERANCE);
-        Assert.assertEquals(2.0, c.getY(), TEST_TOLERANCE);
-        Assert.assertEquals(3.0, c.getZ(), TEST_TOLERANCE);
-    }
-
-    @Test
-    public void testToArray() {
-        // arrange
-        Cartesian3D c = new StubCartesian3D(1, 2, 3);
-
-        // act
-        double[] arr = c.toArray();
-
-        // assert
-        Assert.assertEquals(3, arr.length);
-        Assert.assertEquals(1.0, arr[0], TEST_TOLERANCE);
-        Assert.assertEquals(2.0, arr[1], TEST_TOLERANCE);
-        Assert.assertEquals(3.0, arr[2], TEST_TOLERANCE);
-    }
-
-
-    @Test
-    public void testToSpherical() {
-        // arrange
-        double sqrt3 = Math.sqrt(3);
-
-        // act/assert
-        checkSpherical(new StubCartesian3D(0, 0, 0).toSpherical(), 0, 0, 0);
-
-        checkSpherical(new StubCartesian3D(0.1, 0, 0).toSpherical(), 0.1, 0, Geometry.HALF_PI);
-        checkSpherical(new StubCartesian3D(-0.1, 0, 0).toSpherical(), 0.1, Geometry.PI, Geometry.HALF_PI);
-
-        checkSpherical(new StubCartesian3D(0, 0.1, 0).toSpherical(), 0.1, Geometry.HALF_PI, Geometry.HALF_PI);
-        checkSpherical(new StubCartesian3D(0, -0.1, 0).toSpherical(), 0.1, Geometry.PI + Geometry.HALF_PI, Geometry.HALF_PI);
-
-        checkSpherical(new StubCartesian3D(0, 0, 0.1).toSpherical(), 0.1, 0, 0);
-        checkSpherical(new StubCartesian3D(0, 0, -0.1).toSpherical(), 0.1, 0, Geometry.PI);
-
-        checkSpherical(new StubCartesian3D(1, 1, 1).toSpherical(), sqrt3, 0.25 * Geometry.PI, Math.acos(1 / sqrt3));
-        checkSpherical(new StubCartesian3D(-1, -1, -1).toSpherical(), sqrt3, 1.25 * Geometry.PI, Math.acos(-1 / sqrt3));
-    }
-
-    @Test
-    public void testDimension() {
-        // arrange
-        Cartesian3D c = new StubCartesian3D(1, 2, 3);
-
-        // act/assert
-        Assert.assertEquals(3, c.getDimension());
-    }
-
-    @Test
-    public void testNaN() {
-        // act/assert
-        Assert.assertTrue(new StubCartesian3D(0, 0, Double.NaN).isNaN());
-        Assert.assertTrue(new StubCartesian3D(0, Double.NaN, 0).isNaN());
-        Assert.assertTrue(new StubCartesian3D(Double.NaN, 0, 0).isNaN());
-
-        Assert.assertFalse(new StubCartesian3D(1, 1, 1).isNaN());
-        Assert.assertFalse(new StubCartesian3D(1, 1, Double.NEGATIVE_INFINITY).isNaN());
-        Assert.assertFalse(new StubCartesian3D(1, Double.POSITIVE_INFINITY, 1).isNaN());
-        Assert.assertFalse(new StubCartesian3D(Double.NEGATIVE_INFINITY, 1, 1).isNaN());
-    }
-
-    @Test
-    public void testInfinite() {
-        // act/assert
-        Assert.assertTrue(new StubCartesian3D(0, 0, Double.NEGATIVE_INFINITY).isInfinite());
-        Assert.assertTrue(new StubCartesian3D(0, Double.NEGATIVE_INFINITY, 0).isInfinite());
-        Assert.assertTrue(new StubCartesian3D(Double.NEGATIVE_INFINITY, 0, 0).isInfinite());
-        Assert.assertTrue(new StubCartesian3D(0, 0, Double.POSITIVE_INFINITY).isInfinite());
-        Assert.assertTrue(new StubCartesian3D(0, Double.POSITIVE_INFINITY, 0).isInfinite());
-        Assert.assertTrue(new StubCartesian3D(Double.POSITIVE_INFINITY, 0, 0).isInfinite());
-
-        Assert.assertFalse(new StubCartesian3D(1, 1, 1).isInfinite());
-        Assert.assertFalse(new StubCartesian3D(0, 0, Double.NaN).isInfinite());
-        Assert.assertFalse(new StubCartesian3D(0, Double.NEGATIVE_INFINITY, Double.NaN).isInfinite());
-        Assert.assertFalse(new StubCartesian3D(Double.NaN, 0, Double.NEGATIVE_INFINITY).isInfinite());
-        Assert.assertFalse(new StubCartesian3D(Double.POSITIVE_INFINITY, Double.NaN, 0).isInfinite());
-        Assert.assertFalse(new StubCartesian3D(0, Double.NaN, Double.POSITIVE_INFINITY).isInfinite());
-    }
-
-    @Test
-    public void testToString() {
-        // arrange
-        StubCartesian3D c = new StubCartesian3D(1, 2, 3);
-        Pattern pattern = Pattern.compile("\\(1.{0,2}, 2.{0,2}, 3.{0,2}\\)");
-
-        // act
-        String str = c.toString();
-
-        // assert
-        Assert.assertTrue("Expected string " + str + " to match regex " + pattern,
-                    pattern.matcher(str).matches());
-    }
-
-    private void checkSpherical(SphericalCoordinates c, double radius, double azimuth, double polar) {
-        Assert.assertEquals(radius, c.getRadius(), TEST_TOLERANCE);
-        Assert.assertEquals(azimuth, c.getAzimuth(), TEST_TOLERANCE);
-        Assert.assertEquals(polar, c.getPolar(), TEST_TOLERANCE);
-    }
-
-    private static class StubCartesian3D extends Cartesian3D {
-        private static final long serialVersionUID = 1L;
-
-        public StubCartesian3D(double x, double y, double z) {
-            super(x, y, z);
-        }
-    }
-}
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/LineTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/LineTest.java
index e49c61b..b0cd043 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/LineTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/LineTest.java
@@ -23,10 +23,10 @@ public class LineTest {
 
     @Test
     public void testContains() {
-        Point3D p1 = Point3D.of(0, 0, 1);
-        Line l = new Line(p1, Point3D.of(0, 0, 2), 1.0e-10);
+        Vector3D p1 = Vector3D.of(0, 0, 1);
+        Line l = new Line(p1, Vector3D.of(0, 0, 2), 1.0e-10);
         Assert.assertTrue(l.contains(p1));
-        Assert.assertTrue(l.contains(Point3D.vectorCombination(1.0, p1, 0.3, l.getDirection())));
+        Assert.assertTrue(l.contains(Vector3D.linearCombination(1.0, p1, 0.3, l.getDirection())));
         Vector3D u = l.getDirection().orthogonal();
         Vector3D v = l.getDirection().crossProduct(u);
         for (double alpha = 0; alpha < 2 * Math.PI; alpha += 0.3) {
@@ -37,8 +37,8 @@ public class LineTest {
 
     @Test
     public void testSimilar() {
-        Point3D p1  = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2  = Point3D.of(3.4, -5.8, 1.2);
+        Vector3D p1  = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2  = Vector3D.of(3.4, -5.8, 1.2);
         Line     lA  = new Line(p1, p2, 1.0e-10);
         Line     lB  = new Line(p2, p1, 1.0e-10);
         Assert.assertTrue(lA.isSimilarTo(lB));
@@ -47,89 +47,89 @@ public class LineTest {
 
     @Test
     public void testPointDistance() {
-        Line l = new Line(Point3D.of(0, 1, 1), Point3D.of(0, 2, 2), 1.0e-10);
-        Assert.assertEquals(Math.sqrt(3.0 / 2.0), l.distance(Point3D.of(1, 0, 1)), 1.0e-10);
-        Assert.assertEquals(0, l.distance(Point3D.of(0, -4, -4)), 1.0e-10);
+        Line l = new Line(Vector3D.of(0, 1, 1), Vector3D.of(0, 2, 2), 1.0e-10);
+        Assert.assertEquals(Math.sqrt(3.0 / 2.0), l.distance(Vector3D.of(1, 0, 1)), 1.0e-10);
+        Assert.assertEquals(0, l.distance(Vector3D.of(0, -4, -4)), 1.0e-10);
     }
 
     @Test
     public void testLineDistance() {
-        Line l = new Line(Point3D.of(0, 1, 1), Point3D.of(0, 2, 2), 1.0e-10);
+        Line l = new Line(Vector3D.of(0, 1, 1), Vector3D.of(0, 2, 2), 1.0e-10);
         Assert.assertEquals(1.0,
-                            l.distance(new Line(Point3D.of(1, 0, 1), Point3D.of(1, 0, 2), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(1, 0, 1), Vector3D.of(1, 0, 2), 1.0e-10)),
                             1.0e-10);
         Assert.assertEquals(0.5,
-                            l.distance(new Line(Point3D.of(-0.5, 0, 0), Point3D.of(-0.5, -1, -1), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(-0.5, 0, 0), Vector3D.of(-0.5, -1, -1), 1.0e-10)),
                             1.0e-10);
         Assert.assertEquals(0.0,
                             l.distance(l),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.distance(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -5, -5), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -5, -5), 1.0e-10)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.distance(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -3, -4), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -3, -4), 1.0e-10)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.distance(new Line(Point3D.of(0, -4, -4), Point3D.of(1, -4, -4), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(0, -4, -4), Vector3D.of(1, -4, -4), 1.0e-10)),
                             1.0e-10);
         Assert.assertEquals(Math.sqrt(8),
-                            l.distance(new Line(Point3D.of(0, -4, 0), Point3D.of(1, -4, 0), 1.0e-10)),
+                            l.distance(new Line(Vector3D.of(0, -4, 0), Vector3D.of(1, -4, 0), 1.0e-10)),
                             1.0e-10);
     }
 
     @Test
     public void testClosest() {
-        Line l = new Line(Point3D.of(0, 1, 1), Point3D.of(0, 2, 2), 1.0e-10);
+        Line l = new Line(Vector3D.of(0, 1, 1), Vector3D.of(0, 2, 2), 1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(new Line(Point3D.of(1, 0, 1), Point3D.of(1, 0, 2), 1.0e-10)).distance(Point3D.of(0, 0, 0)),
+                            l.closestPoint(new Line(Vector3D.of(1, 0, 1), Vector3D.of(1, 0, 2), 1.0e-10)).distance(Vector3D.of(0, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.5,
-                            l.closestPoint(new Line(Point3D.of(-0.5, 0, 0), Point3D.of(-0.5, -1, -1), 1.0e-10)).distance(Point3D.of(-0.5, 0, 0)),
+                            l.closestPoint(new Line(Vector3D.of(-0.5, 0, 0), Vector3D.of(-0.5, -1, -1), 1.0e-10)).distance(Vector3D.of(-0.5, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(l).distance(Point3D.of(0, 0, 0)),
+                            l.closestPoint(l).distance(Vector3D.of(0, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -5, -5), 1.0e-10)).distance(Point3D.of(0, 0, 0)),
+                            l.closestPoint(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -5, -5), 1.0e-10)).distance(Vector3D.of(0, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -3, -4), 1.0e-10)).distance(Point3D.of(0, -4, -4)),
+                            l.closestPoint(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -3, -4), 1.0e-10)).distance(Vector3D.of(0, -4, -4)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(new Line(Point3D.of(0, -4, -4), Point3D.of(1, -4, -4), 1.0e-10)).distance(Point3D.of(0, -4, -4)),
+                            l.closestPoint(new Line(Vector3D.of(0, -4, -4), Vector3D.of(1, -4, -4), 1.0e-10)).distance(Vector3D.of(0, -4, -4)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.closestPoint(new Line(Point3D.of(0, -4, 0), Point3D.of(1, -4, 0), 1.0e-10)).distance(Point3D.of(0, -2, -2)),
+                            l.closestPoint(new Line(Vector3D.of(0, -4, 0), Vector3D.of(1, -4, 0), 1.0e-10)).distance(Vector3D.of(0, -2, -2)),
                             1.0e-10);
     }
 
     @Test
     public void testIntersection() {
-        Line l = new Line(Point3D.of(0, 1, 1), Point3D.of(0, 2, 2), 1.0e-10);
-        Assert.assertNull(l.intersection(new Line(Point3D.of(1, 0, 1), Point3D.of(1, 0, 2), 1.0e-10)));
-        Assert.assertNull(l.intersection(new Line(Point3D.of(-0.5, 0, 0), Point3D.of(-0.5, -1, -1), 1.0e-10)));
+        Line l = new Line(Vector3D.of(0, 1, 1), Vector3D.of(0, 2, 2), 1.0e-10);
+        Assert.assertNull(l.intersection(new Line(Vector3D.of(1, 0, 1), Vector3D.of(1, 0, 2), 1.0e-10)));
+        Assert.assertNull(l.intersection(new Line(Vector3D.of(-0.5, 0, 0), Vector3D.of(-0.5, -1, -1), 1.0e-10)));
         Assert.assertEquals(0.0,
-                            l.intersection(l).distance(Point3D.of(0, 0, 0)),
+                            l.intersection(l).distance(Vector3D.of(0, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.intersection(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -5, -5), 1.0e-10)).distance(Point3D.of(0, 0, 0)),
+                            l.intersection(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -5, -5), 1.0e-10)).distance(Vector3D.of(0, 0, 0)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.intersection(new Line(Point3D.of(0, -4, -4), Point3D.of(0, -3, -4), 1.0e-10)).distance(Point3D.of(0, -4, -4)),
+                            l.intersection(new Line(Vector3D.of(0, -4, -4), Vector3D.of(0, -3, -4), 1.0e-10)).distance(Vector3D.of(0, -4, -4)),
                             1.0e-10);
         Assert.assertEquals(0.0,
-                            l.intersection(new Line(Point3D.of(0, -4, -4), Point3D.of(1, -4, -4), 1.0e-10)).distance(Point3D.of(0, -4, -4)),
+                            l.intersection(new Line(Vector3D.of(0, -4, -4), Vector3D.of(1, -4, -4), 1.0e-10)).distance(Vector3D.of(0, -4, -4)),
                             1.0e-10);
-        Assert.assertNull(l.intersection(new Line(Point3D.of(0, -4, 0), Point3D.of(1, -4, 0), 1.0e-10)));
+        Assert.assertNull(l.intersection(new Line(Vector3D.of(0, -4, 0), Vector3D.of(1, -4, 0), 1.0e-10)));
     }
 
     @Test
     public void testRevert() {
 
         // setup
-        Line line = new Line(Point3D.of(1653345.6696423641, 6170370.041579291, 90000),
-                             Point3D.of(1650757.5050732433, 6160710.879908984, 0.9),
+        Line line = new Line(Vector3D.of(1653345.6696423641, 6170370.041579291, 90000),
+                             Vector3D.of(1650757.5050732433, 6160710.879908984, 0.9),
                              1.0e-10);
         Vector3D expected = line.getDirection().negate();
 
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/OBJWriter.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/OBJWriter.java
index cb3f861..b1bccca 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/OBJWriter.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/OBJWriter.java
@@ -31,8 +31,8 @@ import java.util.TreeMap;
 import org.apache.commons.geometry.core.partitioning.BSPTree;
 import org.apache.commons.geometry.core.partitioning.BSPTreeVisitor;
 import org.apache.commons.geometry.core.partitioning.BoundaryAttribute;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 
 /** This class creates simple OBJ files from {@link PolyhedronsSet} instances.
  * The output files can be opened in a 3D viewer for visual debugging of 3D
@@ -76,10 +76,10 @@ public class OBJWriter {
      * @param vertices
      * @throws IOException
      */
-    private static void writeVertices(Writer writer, List<Point3D> vertices) throws IOException {
+    private static void writeVertices(Writer writer, List<Vector3D> vertices) throws IOException {
         DecimalFormat df = new DecimalFormat("0.######");
 
-        for (Point3D v : vertices) {
+        for (Vector3D v : vertices) {
             writer.write("v ");
             writer.write(df.format(v.getX()));
             writer.write(" ");
@@ -112,7 +112,7 @@ public class OBJWriter {
      * other, then the vertices are considered equal. This helps to avoid
      * writing duplicate vertices in the OBJ output.
      */
-    private static class VertexComparator implements Comparator<Point3D> {
+    private static class VertexComparator implements Comparator<Vector3D> {
 
         /** Geometric tolerance value */
         private double tolerance;
@@ -126,7 +126,7 @@ public class OBJWriter {
 
         /** {@inheritDoc} */
         @Override
-        public int compare(Point3D a, Point3D b) {
+        public int compare(Vector3D a, Vector3D b) {
             int result = compareDoubles(a.getX(), b.getX());
             if (result == 0) {
                 result = compareDoubles(a.getY(), b.getY());
@@ -159,16 +159,16 @@ public class OBJWriter {
     /** Class for converting a 3D BSPTree into a list of vertices
      * and face vertex indices.
      */
-    private static class MeshBuilder implements BSPTreeVisitor<Point3D> {
+    private static class MeshBuilder implements BSPTreeVisitor<Vector3D> {
 
         /** Geometric tolerance */
         private final double tolerance;
 
         /** Map of vertices to their index in the vertices list */
-        private Map<Point3D, Integer> vertexIndexMap;
+        private Map<Vector3D, Integer> vertexIndexMap;
 
         /** List of unique vertices in the BSPTree boundary */
-        private List<Point3D> vertices;
+        private List<Vector3D> vertices;
 
         /**
          * List of face vertex indices. Each face will have 3 indices. Indices
@@ -189,7 +189,7 @@ public class OBJWriter {
         /** Returns the list of unique vertices found in the BSPTree.
          * @return
          */
-        public List<Point3D> getVertices() {
+        public List<Vector3D> getVertices() {
             return vertices;
         }
 
@@ -203,15 +203,15 @@ public class OBJWriter {
 
         /** {@inheritDoc} */
         @Override
-        public Order visitOrder(BSPTree<Point3D> node) {
+        public Order visitOrder(BSPTree<Vector3D> node) {
             return Order.SUB_MINUS_PLUS;
         }
 
         /** {@inheritDoc} */
         @SuppressWarnings("unchecked")
         @Override
-        public void visitInternalNode(BSPTree<Point3D> node) {
-            BoundaryAttribute<Point3D> attr = (BoundaryAttribute<Point3D>) node.getAttribute();
+        public void visitInternalNode(BSPTree<Vector3D> node) {
+            BoundaryAttribute<Vector3D> attr = (BoundaryAttribute<Vector3D>) node.getAttribute();
 
             if (attr.getPlusOutside() != null) {
                 addBoundary((SubPlane) attr.getPlusOutside());
@@ -223,7 +223,7 @@ public class OBJWriter {
 
         /** {@inheritDoc} */
         @Override
-        public void visitLeafNode(BSPTree<Point3D> node) {
+        public void visitLeafNode(BSPTree<Vector3D> node) {
             // do nothing
         }
 
@@ -238,8 +238,8 @@ public class OBJWriter {
             TriangleExtractor triExtractor = new TriangleExtractor(tolerance);
             poly.getTree(true).visit(triExtractor);
 
-            Point3D v1, v2, v3;
-            for (Point2D[] tri : triExtractor.getTriangles()) {
+            Vector3D v1, v2, v3;
+            for (Vector2D[] tri : triExtractor.getTriangles()) {
                 v1 = plane.toSpace(tri[0]);
                 v2 = plane.toSpace(tri[1]);
                 v3 = plane.toSpace(tri[2]);
@@ -258,7 +258,7 @@ public class OBJWriter {
          * @param vertex
          * @return
          */
-        private int getVertexIndex(Point3D vertex) {
+        private int getVertexIndex(Vector3D vertex) {
             Integer idx = vertexIndexMap.get(vertex);
             if (idx == null) {
                 idx = vertices.size();
@@ -272,13 +272,13 @@ public class OBJWriter {
 
     /** Visitor for extracting a collection of triangles from a 2D BSPTree.
      */
-    private static class TriangleExtractor implements BSPTreeVisitor<Point2D> {
+    private static class TriangleExtractor implements BSPTreeVisitor<Vector2D> {
 
         /** Geometric tolerance */
         private double tolerance;
 
         /** List of extracted triangles */
-        private List<Point2D[]> triangles = new ArrayList<>();
+        private List<Vector2D[]> triangles = new ArrayList<>();
 
         /** Creates a new instance with the given geometric tolerance.
          * @param tolerance
@@ -290,30 +290,30 @@ public class OBJWriter {
         /** Returns the list of extracted triangles.
          * @return
          */
-        public List<Point2D[]> getTriangles() {
+        public List<Vector2D[]> getTriangles() {
             return triangles;
         }
 
         /** {@inheritDoc} */
         @Override
-        public Order visitOrder(BSPTree<Point2D> node) {
+        public Order visitOrder(BSPTree<Vector2D> node) {
             return Order.SUB_MINUS_PLUS;
         }
 
         /** {@inheritDoc} */
         @Override
-        public void visitInternalNode(BSPTree<Point2D> node) {
+        public void visitInternalNode(BSPTree<Vector2D> node) {
             // do nothing
         }
 
         /** {@inheritDoc} */
         @Override
-        public void visitLeafNode(BSPTree<Point2D> node) {
+        public void visitLeafNode(BSPTree<Vector2D> node) {
             if ((Boolean) node.getAttribute()) {
                 PolygonsSet convexPoly = new PolygonsSet(node.pruneAroundConvexCell(Boolean.TRUE,
                         Boolean.FALSE, null), tolerance);
 
-                for (Point2D[] loop : convexPoly.getVertices()) {
+                for (Vector2D[] loop : convexPoly.getVertices()) {
                     if (loop.length > 0 && loop[0] != null) { // skip unclosed loops
                         addTriangles(loop);
                     }
@@ -325,10 +325,10 @@ public class OBJWriter {
          * triangles and adds them to the internal list.
          * @param vertices
          */
-        private void addTriangles(Point2D[] vertices) {
+        private void addTriangles(Vector2D[] vertices) {
             // use a triangle fan to add the convex region
             for (int i=2; i<vertices.length; ++i) {
-                triangles.add(new Point2D[] { vertices[0], vertices[i-1], vertices[i] });
+                triangles.add(new Vector2D[] { vertices[0], vertices[i-1], vertices[i] });
             }
         }
     }
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PLYParser.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PLYParser.java
index 8a26afa..b1d6e35 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PLYParser.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PLYParser.java
@@ -39,7 +39,7 @@ import org.apache.commons.numbers.core.Precision;
 public class PLYParser {
 
     /** Parsed vertices. */
-    private Point3D[] vertices;
+    private Vector3D[] vertices;
 
     /** Parsed faces. */
     private int[][] faces;
@@ -166,7 +166,7 @@ public class PLYParser {
             ++vPropertiesNumber;
 
             // parse vertices
-            vertices = new Point3D[nbVertices];
+            vertices = new Vector3D[nbVertices];
             for (int i = 0; i < nbVertices; ++i) {
                 fields = parseNextLine();
                 if (fields.size() != vPropertiesNumber ||
@@ -175,7 +175,7 @@ public class PLYParser {
                     fields.get(zIndex).getToken() != Token.UNKNOWN) {
                     complain();
                 }
-                vertices[i] = Point3D.of(Double.parseDouble(fields.get(xIndex).getValue()),
+                vertices[i] = Vector3D.of(Double.parseDouble(fields.get(xIndex).getValue()),
                                            Double.parseDouble(fields.get(yIndex).getValue()),
                                            Double.parseDouble(fields.get(zIndex).getValue()));
             }
@@ -228,7 +228,7 @@ public class PLYParser {
     /** Get the parsed vertices.
      * @return parsed vertices
      */
-    public List<Point3D> getVertices() {
+    public List<Vector3D> getVertices() {
         return Arrays.asList(vertices);
     }
 
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
index d6e3039..92c6da1 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PlaneTest.java
@@ -19,7 +19,7 @@ package org.apache.commons.geometry.euclidean.threed;
 import org.apache.commons.geometry.euclidean.threed.Line;
 import org.apache.commons.geometry.euclidean.threed.Plane;
 import org.apache.commons.geometry.euclidean.threed.Rotation;
-import org.apache.commons.geometry.euclidean.threed.Point3D;
+import org.apache.commons.geometry.euclidean.threed.Vector3D;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -27,37 +27,37 @@ public class PlaneTest {
 
     @Test
     public void testContains() {
-        Plane p = new Plane(Point3D.of(0, 0, 1), Vector3D.of(0, 0, 1), 1.0e-10);
-        Assert.assertTrue(p.contains(Point3D.of(0, 0, 1)));
-        Assert.assertTrue(p.contains(Point3D.of(17, -32, 1)));
-        Assert.assertTrue(! p.contains(Point3D.of(17, -32, 1.001)));
+        Plane p = new Plane(Vector3D.of(0, 0, 1), Vector3D.of(0, 0, 1), 1.0e-10);
+        Assert.assertTrue(p.contains(Vector3D.of(0, 0, 1)));
+        Assert.assertTrue(p.contains(Vector3D.of(17, -32, 1)));
+        Assert.assertTrue(! p.contains(Vector3D.of(17, -32, 1.001)));
     }
 
     @Test
     public void testOffset() {
-        Point3D p1 = Point3D.of(1, 1, 1);
+        Vector3D p1 = Vector3D.of(1, 1, 1);
         Plane p = new Plane(p1, Vector3D.of(0.2, 0, 0), 1.0e-10);
-        Assert.assertEquals(-5.0, p.getOffset(Point3D.of(-4, 0, 0)), 1.0e-10);
-        Assert.assertEquals(+5.0, p.getOffset(Point3D.of(6, 10, -12)), 1.0e-10);
+        Assert.assertEquals(-5.0, p.getOffset(Vector3D.of(-4, 0, 0)), 1.0e-10);
+        Assert.assertEquals(+5.0, p.getOffset(Vector3D.of(6, 10, -12)), 1.0e-10);
         Assert.assertEquals(0.3,
-                            p.getOffset(Point3D.vectorCombination(1.0, p1, 0.3, p.getNormal())),
+                            p.getOffset(Vector3D.linearCombination(1.0, p1, 0.3, p.getNormal())),
                             1.0e-10);
         Assert.assertEquals(-0.3,
-                            p.getOffset(Point3D.vectorCombination(1.0, p1, -0.3, p.getNormal())),
+                            p.getOffset(Vector3D.linearCombination(1.0, p1, -0.3, p.getNormal())),
                             1.0e-10);
     }
 
     @Test
     public void testPoint() {
-        Plane p = new Plane(Point3D.of(2, -3, 1), Vector3D.of(1, 4, 9), 1.0e-10);
+        Plane p = new Plane(Vector3D.of(2, -3, 1), Vector3D.of(1, 4, 9), 1.0e-10);
         Assert.assertTrue(p.contains(p.getOrigin()));
     }
 
     @Test
     public void testThreePoints() {
-        Point3D p1 = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2 = Point3D.of(3.4, -5.8, 1.2);
-        Point3D p3 = Point3D.of(-2.0, 4.3, 0.7);
+        Vector3D p1 = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2 = Vector3D.of(3.4, -5.8, 1.2);
+        Vector3D p3 = Vector3D.of(-2.0, 4.3, 0.7);
         Plane    p  = new Plane(p1, p2, p3, 1.0e-10);
         Assert.assertTrue(p.contains(p1));
         Assert.assertTrue(p.contains(p2));
@@ -66,9 +66,9 @@ public class PlaneTest {
 
     @Test
     public void testRotate() {
-        Point3D p1 = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2 = Point3D.of(3.4, -5.8, 1.2);
-        Point3D p3 = Point3D.of(-2.0, 4.3, 0.7);
+        Vector3D p1 = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2 = Vector3D.of(3.4, -5.8, 1.2);
+        Vector3D p3 = Vector3D.of(-2.0, 4.3, 0.7);
         Plane    p  = new Plane(p1, p2, p3, 1.0e-10);
         Vector3D oldNormal = p.getNormal();
 
@@ -91,9 +91,9 @@ public class PlaneTest {
 
     @Test
     public void testTranslate() {
-        Point3D p1 = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2 = Point3D.of(3.4, -5.8, 1.2);
-        Point3D p3 = Point3D.of(-2.0, 4.3, 0.7);
+        Vector3D p1 = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2 = Vector3D.of(3.4, -5.8, 1.2);
+        Vector3D p3 = Vector3D.of(-2.0, 4.3, 0.7);
         Plane    p  = new Plane(p1, p2, p3, 1.0e-10);
 
         p = p.translate(Vector3D.linearCombination(2.0, p.getU(), -1.5, p.getV()));
@@ -115,22 +115,22 @@ public class PlaneTest {
 
     @Test
     public void testIntersection() {
-        Plane p = new Plane(Point3D.of(1, 2, 3), Vector3D.of(-4, 1, -5), 1.0e-10);
-        Line  l = new Line(Point3D.of(0.2, -3.5, 0.7), Point3D.of(1.2, -2.5, -0.3), 1.0e-10);
-        Point3D point = p.intersection(l);
+        Plane p = new Plane(Vector3D.of(1, 2, 3), Vector3D.of(-4, 1, -5), 1.0e-10);
+        Line  l = new Line(Vector3D.of(0.2, -3.5, 0.7), Vector3D.of(1.2, -2.5, -0.3), 1.0e-10);
+        Vector3D point = p.intersection(l);
         Assert.assertTrue(p.contains(point));
         Assert.assertTrue(l.contains(point));
-        Assert.assertNull(p.intersection(new Line(Point3D.of(10, 10, 10),
-                                                  Point3D.of(10, 10, 10).add(p.getNormal().orthogonal()),
+        Assert.assertNull(p.intersection(new Line(Vector3D.of(10, 10, 10),
+                                                  Vector3D.of(10, 10, 10).add(p.getNormal().orthogonal()),
                                                   1.0e-10)));
     }
 
     @Test
     public void testIntersection2() {
-        Point3D p1  = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2  = Point3D.of(3.4, -5.8, 1.2);
-        Plane    pA  = new Plane(p1, p2, Point3D.of(-2.0, 4.3, 0.7), 1.0e-10);
-        Plane    pB  = new Plane(p1, Point3D.of(11.4, -3.8, 5.1), p2, 1.0e-10);
+        Vector3D p1  = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2  = Vector3D.of(3.4, -5.8, 1.2);
+        Plane    pA  = new Plane(p1, p2, Vector3D.of(-2.0, 4.3, 0.7), 1.0e-10);
+        Plane    pB  = new Plane(p1, Vector3D.of(11.4, -3.8, 5.1), p2, 1.0e-10);
         Line     l   = pA.intersection(pB);
         Assert.assertTrue(l.contains(p1));
         Assert.assertTrue(l.contains(p2));
@@ -139,11 +139,11 @@ public class PlaneTest {
 
     @Test
     public void testIntersection3() {
-        Point3D reference = Point3D.of(1.2, 3.4, -5.8);
+        Vector3D reference = Vector3D.of(1.2, 3.4, -5.8);
         Plane p1 = new Plane(reference, Vector3D.of(1, 3, 3), 1.0e-10);
         Plane p2 = new Plane(reference, Vector3D.of(-2, 4, 0), 1.0e-10);
         Plane p3 = new Plane(reference, Vector3D.of(7, 0, -4), 1.0e-10);
-        Point3D p = Plane.intersection(p1, p2, p3);
+        Vector3D p = Plane.intersection(p1, p2, p3);
         Assert.assertEquals(reference.getX(), p.getX(), 1.0e-10);
         Assert.assertEquals(reference.getY(), p.getY(), 1.0e-10);
         Assert.assertEquals(reference.getZ(), p.getZ(), 1.0e-10);
@@ -151,11 +151,11 @@ public class PlaneTest {
 
     @Test
     public void testSimilar() {
-        Point3D p1  = Point3D.of(1.2, 3.4, -5.8);
-        Point3D p2  = Point3D.of(3.4, -5.8, 1.2);
-        Point3D p3  = Point3D.of(-2.0, 4.3, 0.7);
+        Vector3D p1  = Vector3D.of(1.2, 3.4, -5.8);
+        Vector3D p2  = Vector3D.of(3.4, -5.8, 1.2);
+        Vector3D p3  = Vector3D.of(-2.0, 4.3, 0.7);
         Plane    pA  = new Plane(p1, p2, p3, 1.0e-10);
-        Plane    pB  = new Plane(p1, Point3D.of(11.4, -3.8, 5.1), p2, 1.0e-10);
+        Plane    pB  = new Plane(p1, Vector3D.of(11.4, -3.8, 5.1), p2, 1.0e-10);
         Assert.assertTrue(! pA.isSimilarTo(pB));
         Assert.assertTrue(pA.isSimilarTo(pA));
         Assert.assertTrue(pA.isSimilarTo(new Plane(p1, p3, p2, 1.0e-10)));
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java
deleted file mode 100644
index e1cd149..0000000
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Point3DTest.java
+++ /dev/null
@@ -1,380 +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.geometry.euclidean.threed;
-
-import java.util.regex.Pattern;
-
-import org.apache.commons.geometry.core.Geometry;
-import org.apache.commons.geometry.core.GeometryTestUtils;
-import org.apache.commons.geometry.core.exception.IllegalNormException;
-import org.apache.commons.numbers.core.Precision;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class Point3DTest {
-
-    private static final double EPS = 1e-15;
-
-    @Test
-    public void testConstants() {
-        // act/assert
-        checkPoint(Point3D.ZERO, 0, 0, 0);
-        checkPoint(Point3D.NaN, Double.NaN, Double.NaN, Double.NaN);
-        checkPoint(Point3D.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
-        checkPoint(Point3D.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-    }
-
-    @Test
-    public void testAsVector() {
-        // act/assert
-        checkVector(Point3D.of(1, 2, 3).asVector(), 1, 2, 3);
-        checkVector(Point3D.of(-1, -2, -3).asVector(), -1, -2, -3);
-        checkVector(Point3D.of(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY).asVector(),
-                Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
-    }
-
-    @Test
-    public void testDistance() {
-        // act/assert
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(4, 5, 6);
-        Point3D p3 = Point3D.of(-7, -8, -9);
-
-        // act/assert
-        Assert.assertEquals(0,  p1.distance(p1), EPS);
-        Assert.assertEquals(0,  p2.distance(p2), EPS);
-        Assert.assertEquals(0,  p3.distance(p3), EPS);
-
-        Assert.assertEquals(Math.sqrt(27), p1.distance(p2), EPS);
-        Assert.assertEquals(Math.sqrt(27), p2.distance(p1), EPS);
-
-        Assert.assertEquals(Math.sqrt(308), p1.distance(p3), EPS);
-        Assert.assertEquals(Math.sqrt(308), p3.distance(p1), EPS);
-    }
-
-    @Test
-    public void testSubtract() {
-        // act/assert
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(4, 5, 6);
-        Point3D p3 = Point3D.of(-7, -8, -9);
-
-        // act/assert
-        checkVector(p1.subtract(p1), 0, 0, 0);
-        checkVector(p2.subtract(p2), 0, 0, 0);
-        checkVector(p3.subtract(p3), 0, 0, 0);
-
-        checkVector(p1.subtract(p2), -3, -3, -3);
-        checkVector(p2.subtract(p1), 3, 3, 3);
-
-        checkVector(p1.subtract(p3), 8, 10, 12);
-        checkVector(p3.subtract(p1), -8, -10,-12);
-    }
-
-    @Test
-    public void testVectorTo() {
-        // act/assert
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(4, 5, 6);
-        Point3D p3 = Point3D.of(-7, -8, -9);
-
-        // act/assert
-        checkVector(p1.vectorTo(p1), 0, 0, 0);
-        checkVector(p2.vectorTo(p2), 0, 0, 0);
-        checkVector(p3.vectorTo(p3), 0, 0, 0);
-
-        checkVector(p1.vectorTo(p2), 3, 3, 3);
-        checkVector(p2.vectorTo(p1), -3, -3, -3);
-
-        checkVector(p1.vectorTo(p3), -8, -10, -12);
-        checkVector(p3.vectorTo(p1), 8, 10, 12);
-    }
-
-    @Test
-    public void testDirectionTo() {
-        // act/assert
-        double invSqrt3 = 1.0 / Math.sqrt(3);
-
-        Point3D p1 = Point3D.of(1, 1, 1);
-        Point3D p2 = Point3D.of(1, 5, 1);
-        Point3D p3 = Point3D.of(-2, -2, -2);
-
-        // act/assert
-        checkVector(p1.directionTo(p2), 0, 1, 0);
-        checkVector(p2.directionTo(p1), 0, -1, 0);
-
-        checkVector(p1.directionTo(p3), -invSqrt3, -invSqrt3, -invSqrt3);
-        checkVector(p3.directionTo(p1), invSqrt3, invSqrt3, invSqrt3);
-    }
-
-    @Test
-    public void testDirectionTo_illegalNorm() {
-        // arrange
-        Point3D p = Point3D.of(1, 2, 3);
-
-        // act/assert
-        GeometryTestUtils.assertThrows(() -> Point3D.ZERO.directionTo(Point3D.ZERO),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(p),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(Point3D.NaN),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> Point3D.NEGATIVE_INFINITY.directionTo(p),
-                IllegalNormException.class);
-        GeometryTestUtils.assertThrows(() -> p.directionTo(Point3D.POSITIVE_INFINITY),
-                IllegalNormException.class);
-    }
-
-    @Test
-    public void testLerp() {
-        // arrange
-        Point3D p1 = Point3D.of(1, -5, 2);
-        Point3D p2 = Point3D.of(-4, 0, 2);
-        Point3D p3 = Point3D.of(10, -4, 0);
-
-        // act/assert
-        checkPoint(p1.lerp(p1, 0), 1, -5, 2);
-        checkPoint(p1.lerp(p1, 1), 1, -5, 2);
-
-        checkPoint(p1.lerp(p2, -0.25), 2.25, -6.25, 2);
-        checkPoint(p1.lerp(p2, 0), 1, -5, 2);
-        checkPoint(p1.lerp(p2, 0.25), -0.25, -3.75, 2);
-        checkPoint(p1.lerp(p2, 0.5), -1.5, -2.5, 2);
-        checkPoint(p1.lerp(p2, 0.75), -2.75, -1.25, 2);
-        checkPoint(p1.lerp(p2, 1), -4, 0, 2);
-        checkPoint(p1.lerp(p2, 1.25), -5.25, 1.25, 2);
-
-        checkPoint(p1.lerp(p3, 0), 1, -5, 2);
-        checkPoint(p1.lerp(p3, 0.25), 3.25, -4.75, 1.5);
-        checkPoint(p1.lerp(p3, 0.5), 5.5, -4.5, 1);
-        checkPoint(p1.lerp(p3, 0.75), 7.75, -4.25, 0.5);
-        checkPoint(p1.lerp(p3, 1), 10, -4, 0);
-    }
-
-    @Test
-    public void testAdd() {
-        // act/assert
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(-4, -5, -6);
-
-        // act/assert
-        checkPoint(p1.add(Vector3D.ZERO), 1, 2, 3);
-        checkPoint(p1.add(Vector3D.of(4, 5, 6)), 5, 7, 9);
-        checkPoint(p1.add(Vector3D.of(-4, -5, -6)), -3, -3, -3);
-
-        checkPoint(p2.add(Vector3D.ZERO), -4, -5, -6);
-        checkPoint(p2.add(Vector3D.of(1, 0, 0)), -3, -5, -6);
-        checkPoint(p2.add(Vector3D.of(0, -1, 0)), -4, -6, -6);
-        checkPoint(p2.add(Vector3D.of(0, 0, 1)), -4, -5, -5);
-    }
-
-    @Test
-    public void testHashCode() {
-        // arrange
-        double delta = 10 * Precision.EPSILON;
-
-        Point3D u = Point3D.of(1, 1, 1);
-        Point3D v = Point3D.of(1 + delta, 1 + delta, 1 + delta);
-        Point3D w = Point3D.of(1, 1, 1);
-
-        // act/assert
-        Assert.assertTrue(u.hashCode() != v.hashCode());
-        Assert.assertEquals(u.hashCode(), w.hashCode());
-
-        Assert.assertEquals(Point3D.of(0, 0, Double.NaN).hashCode(), Point3D.NaN.hashCode());
-        Assert.assertEquals(Point3D.of(0, Double.NaN, 0).hashCode(), Point3D.NaN.hashCode());
-        Assert.assertEquals(Point3D.of(Double.NaN, 0, 0).hashCode(), Point3D.NaN.hashCode());
-        Assert.assertEquals(Point3D.of(0, Double.NaN, 0).hashCode(), Point3D.of(Double.NaN, 0, 0).hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        // arrange
-        double delta = 10 * Precision.EPSILON;
-
-        Point3D u1 = Point3D.of(1, 2, 3);
-        Point3D u2 = Point3D.of(1, 2, 3);
-
-        // act/assert
-        Assert.assertFalse(u1.equals(null));
-        Assert.assertFalse(u1.equals(new Object()));
-
-        Assert.assertTrue(u1.equals(u1));
-        Assert.assertTrue(u1.equals(u2));
-
-        Assert.assertFalse(u1.equals(Point3D.of(-1, -2, -3)));
-        Assert.assertFalse(u1.equals(Point3D.of(1 + delta, 2, 3)));
-        Assert.assertFalse(u1.equals(Point3D.of(1, 2 + delta, 3)));
-        Assert.assertFalse(u1.equals(Point3D.of(1, 2, 3 + delta)));
-
-        Assert.assertTrue(Point3D.of(Double.NaN, 0, 0).equals(Point3D.of(0, Double.NaN, 0)));
-        Assert.assertTrue(Point3D.of(0, 0, Double.NaN).equals(Point3D.of(Double.NaN, 0, 0)));
-
-        Assert.assertTrue(Point3D.of(0, 0, Double.NEGATIVE_INFINITY).equals(Point3D.of(0, 0, Double.NEGATIVE_INFINITY)));
-        Assert.assertFalse(Point3D.of(0, 0, Double.NEGATIVE_INFINITY).equals(Point3D.of(0, Double.NEGATIVE_INFINITY, 0)));
-        Assert.assertFalse(Point3D.of(0, 0, Double.NEGATIVE_INFINITY).equals(Point3D.of(Double.NEGATIVE_INFINITY, 0, 0)));
-
-        Assert.assertTrue(Point3D.of(0, 0, Double.POSITIVE_INFINITY).equals(Point3D.of(0, 0, Double.POSITIVE_INFINITY)));
-        Assert.assertFalse(Point3D.of(0, 0, Double.POSITIVE_INFINITY).equals(Point3D.of(0, Double.POSITIVE_INFINITY, 0)));
-        Assert.assertFalse(Point3D.of(0, 0, Double.POSITIVE_INFINITY).equals(Point3D.of(Double.POSITIVE_INFINITY, 0, 0)));
-    }
-
-    @Test
-    public void testToString() {
-        // arrange
-        Point3D p = Point3D.of(1, 2, 3);
-        Pattern pattern = Pattern.compile("\\(1.{0,2}, 2.{0,2}, 3.{0,2}\\)");
-
-        // act
-        String str = p.toString();
-
-        // assert
-        Assert.assertTrue("Expected string " + str + " to match regex " + pattern,
-                    pattern.matcher(str).matches());
-    }
-
-    @Test
-    public void testParse() {
-        // act/assert
-        checkPoint(Point3D.parse("(1, 2, 0)"), 1, 2, 0);
-        checkPoint(Point3D.parse("(-1, -2, 0)"), -1, -2, 0);
-
-        checkPoint(Point3D.parse("(0.01, -1e-3, 1e3)"), 1e-2, -1e-3, 1e3);
-
-        checkPoint(Point3D.parse("(NaN, -Infinity, Infinity)"), Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
-
-        checkPoint(Point3D.parse(Point3D.ZERO.toString()), 0, 0, 0);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testParse_failure() {
-        // act/assert
-        Point3D.parse("abc");
-    }
-
-    @Test
-    public void testOf() {
-        // act/assert
-        checkPoint(Point3D.of(1, 2, 3), 1, 2, 3);
-        checkPoint(Point3D.of(-1, -2, -3), -1, -2, -3);
-        checkPoint(Point3D.of(Math.PI, Double.NaN, Double.POSITIVE_INFINITY),
-                Math.PI, Double.NaN, Double.POSITIVE_INFINITY);
-        checkPoint(Point3D.of(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.E),
-                Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.E);
-    }
-
-    @Test
-    public void testOf_arrayArg() {
-        // act/assert
-        checkPoint(Point3D.ofArray(new double[] { 1, 2, 3 }), 1, 2, 3);
-        checkPoint(Point3D.ofArray(new double[] { -1, -2, -3 }), -1, -2, -3);
-        checkPoint(Point3D.ofArray(new double[] { Math.PI, Double.NaN, Double.POSITIVE_INFINITY }),
-                Math.PI, Double.NaN, Double.POSITIVE_INFINITY);
-        checkPoint(Point3D.ofArray(new double[] { Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.E}),
-                Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.E);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testOf_arrayArg_invalidDimensions() {
-        // act/assert
-        Point3D.ofArray(new double[] { 0.0, 0.0 });
-    }
-
-    @Test
-    public void testOfSpherical() {
-        // arrange
-        double sqrt3 = Math.sqrt(3);
-
-        // act/assert
-        checkPoint(Point3D.ofSpherical(0, 0, 0), 0, 0, 0);
-
-        checkPoint(Point3D.ofSpherical(1, 0, Geometry.HALF_PI), 1, 0, 0);
-        checkPoint(Point3D.ofSpherical(1, Geometry.PI, Geometry.HALF_PI), -1, 0, 0);
-
-        checkPoint(Point3D.ofSpherical(2, Geometry.HALF_PI, Geometry.HALF_PI), 0, 2, 0);
-        checkPoint(Point3D.ofSpherical(2, Geometry.MINUS_HALF_PI, Geometry.HALF_PI), 0, -2, 0);
-
-        checkPoint(Point3D.ofSpherical(3, 0, 0), 0, 0, 3);
-        checkPoint(Point3D.ofSpherical(3, 0, Geometry.PI), 0, 0, -3);
-
-        checkPoint(Point3D.ofSpherical(sqrt3, 0.25 * Geometry.PI, Math.acos(1 / sqrt3)), 1, 1, 1);
-        checkPoint(Point3D.ofSpherical(sqrt3, -0.75 * Geometry.PI, Math.acos(-1 / sqrt3)), -1, -1, -1);
-    }
-
-    @Test
-    public void testVectorCombination1() {
-        // arrange
-        Point3D p1 = Point3D.of(1, 2, 3);
-
-        // act/assert
-        checkPoint(Point3D.vectorCombination(0, p1), 0, 0, 0);
-
-        checkPoint(Point3D.vectorCombination(1, p1), 1, 2, 3);
-        checkPoint(Point3D.vectorCombination(-1, p1), -1, -2, -3);
-
-        checkPoint(Point3D.vectorCombination(0.5, p1), 0.5, 1, 1.5);
-        checkPoint(Point3D.vectorCombination(-0.5, p1), -0.5, -1, -1.5);
-    }
-
-    @Test
-    public void testVectorCombination2() {
-        // arrange
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(-3, -4, -5);
-
-        // act/assert
-        checkPoint(Point3D.vectorCombination(2, p1, -3, p2), 11, 16, 21);
-        checkPoint(Point3D.vectorCombination(-3, p1, 2, p2), -9, -14, -19);
-    }
-
-    @Test
-    public void testVectorCombination3() {
-        // arrange
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(-3, -4, -5);
-        Point3D p3 = Point3D.of(5, 6, 7);
-
-        // act/assert
-        checkPoint(Point3D.vectorCombination(2, p1, -3, p2, 4, p3), 31, 40, 49);
-        checkPoint(Point3D.vectorCombination(-3, p1, 2, p2, -4, p3), -29, -38, -47);
-    }
-
-    @Test
-    public void testVectorCombination4() {
-        // arrange
-        Point3D p1 = Point3D.of(1, 2, 3);
-        Point3D p2 = Point3D.of(-3, -4, -5);
-        Point3D p3 = Point3D.of(5, 6, 7);
-        Point3D p4 = Point3D.of(-7, -8, 9);
-
-        // act/assert
-        checkPoint(Point3D.vectorCombination(2, p1, -3, p2, 4, p3, -5, p4), 66, 80, 4);
-        checkPoint(Point3D.vectorCombination(-3, p1, 2, p2, -4, p3, 5, p4), -64, -78, -2);
-    }
-
-    private void checkVector(Vector3D v, double x, double y, double z) {
-        Assert.assertEquals(x, v.getX(), EPS);
-        Assert.assertEquals(y, v.getY(), EPS);
-        Assert.assertEquals(z, v.getZ(), EPS);
-    }
-
-    private void checkPoint(Point3D p, double x, double y, double z) {
-        Assert.assertEquals(x, p.getX(), EPS);
-        Assert.assertEquals(y, p.getY(), EPS);
-        Assert.assertEquals(z, p.getZ(), EPS);
-    }
-}
diff --git a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
index fe6c74d..cd58e21 100644
--- a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
+++ b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
@@ -33,9 +33,9 @@ import org.apache.commons.geometry.core.partitioning.Region;
 import org.apache.commons.geometry.core.partitioning.RegionFactory;
 import org.apache.commons.geometry.core.partitioning.SubHyperplane;
 import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
-import org.apache.commons.geometry.euclidean.twod.Point2D;
 import org.apache.commons.geometry.euclidean.twod.PolygonsSet;
 import org.apache.commons.geometry.euclidean.twod.SubLine;
+import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.numbers.core.Precision;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.simple.RandomSource;
@@ -55,44 +55,44 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         EuclideanTestUtils.assertPositiveInfinity(polySet.getSize());
         Assert.assertEquals(0.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertTrue(polySet.isFull());
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
-                Point3D.of(-100, -100, -100),
-                Point3D.of(0, 0, 0),
-                Point3D.of(100, 100, 100),
-                Point3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
+                Vector3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
+                Vector3D.of(-100, -100, -100),
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(100, 100, 100),
+                Vector3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
     }
 
     @Test
     public void testEmptyRegion() {
         // act
-        PolyhedronsSet polySet = new PolyhedronsSet(new BSPTree<Point3D>(Boolean.FALSE), TEST_TOLERANCE);
+        PolyhedronsSet polySet = new PolyhedronsSet(new BSPTree<Vector3D>(Boolean.FALSE), TEST_TOLERANCE);
 
         // assert
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(0.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(0.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertTrue(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
-                Point3D.of(-100, -100, -100),
-                Point3D.of(0, 0, 0),
-                Point3D.of(100, 100, 100),
-                Point3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
+                Vector3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
+                Vector3D.of(-100, -100, -100),
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(100, 100, 100),
+                Vector3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
     }
 
     @Test
     public void testHalfSpace() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.add(new SubPlane(new Plane(Point3D.ZERO, Vector3D.PLUS_Y, TEST_TOLERANCE),
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.add(new SubPlane(new Plane(Vector3D.ZERO, Vector3D.PLUS_Y, TEST_TOLERANCE),
                 new PolygonsSet(TEST_TOLERANCE)));
 
         // act
@@ -102,49 +102,49 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         EuclideanTestUtils.assertPositiveInfinity(polySet.getSize());
         EuclideanTestUtils.assertPositiveInfinity(polySet.getBoundarySize());
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
-                Point3D.of(-100, -100, -100));
-        checkPoints(Region.Location.BOUNDARY, polySet, Point3D.of(0, 0, 0));
+                Vector3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
+                Vector3D.of(-100, -100, -100));
+        checkPoints(Region.Location.BOUNDARY, polySet, Vector3D.of(0, 0, 0));
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(100, 100, 100),
-                Point3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
+                Vector3D.of(100, 100, 100),
+                Vector3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
     }
 
     @Test
     public void testInvertedRegion() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = createBoxBoundaries(Point3D.ZERO, 1.0, TEST_TOLERANCE);
+        List<SubHyperplane<Vector3D>> boundaries = createBoxBoundaries(Vector3D.ZERO, 1.0, TEST_TOLERANCE);
         PolyhedronsSet box = new PolyhedronsSet(boundaries, TEST_TOLERANCE);;
 
         // act
-        PolyhedronsSet polySet = (PolyhedronsSet) new RegionFactory<Point3D>().getComplement(box);
+        PolyhedronsSet polySet = (PolyhedronsSet) new RegionFactory<Vector3D>().getComplement(box);
 
         // assert
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         EuclideanTestUtils.assertPositiveInfinity(polySet.getSize());
         Assert.assertEquals(6, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
-                Point3D.of(-100, -100, -100),
-                Point3D.of(100, 100, 100),
-                Point3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
+                Vector3D.of(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE),
+                Vector3D.of(-100, -100, -100),
+                Vector3D.of(100, 100, 100),
+                Vector3D.of(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE));
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(0, 0, 0));
+                Vector3D.of(0, 0, 0));
     }
 
     @Test
     public void testCreateFromBoundaries_noBoundaries_treeRepresentsWholeSpace() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -153,7 +153,7 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         EuclideanTestUtils.assertPositiveInfinity(polySet.getSize());
         Assert.assertEquals(0.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.NaN, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertTrue(polySet.isFull());
     }
@@ -161,7 +161,7 @@ public class PolyhedronsSetTest {
     @Test
     public void testCreateFromBoundaries_unitBox() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = createBoxBoundaries(Point3D.ZERO, 1.0, TEST_TOLERANCE);
+        List<SubHyperplane<Vector3D>> boundaries = createBoxBoundaries(Vector3D.ZERO, 1.0, TEST_TOLERANCE);
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -170,63 +170,63 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(1.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(6.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.ZERO, polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.ZERO, polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(1, 0, 0),
-                Point3D.of(0, -1, 0),
-                Point3D.of(0, 1, 0),
-                Point3D.of(0, 0, -1),
-                Point3D.of(0, 0, 1),
-
-                Point3D.of(1, 1, 1),
-                Point3D.of(1, 1, -1),
-                Point3D.of(1, -1, 1),
-                Point3D.of(1, -1, -1),
-                Point3D.of(-1, 1, 1),
-                Point3D.of(-1, 1, -1),
-                Point3D.of(-1, -1, 1),
-                Point3D.of(-1, -1, -1));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(1, 0, 0),
+                Vector3D.of(0, -1, 0),
+                Vector3D.of(0, 1, 0),
+                Vector3D.of(0, 0, -1),
+                Vector3D.of(0, 0, 1),
+
+                Vector3D.of(1, 1, 1),
+                Vector3D.of(1, 1, -1),
+                Vector3D.of(1, -1, 1),
+                Vector3D.of(1, -1, -1),
+                Vector3D.of(-1, 1, 1),
+                Vector3D.of(-1, 1, -1),
+                Vector3D.of(-1, -1, 1),
+                Vector3D.of(-1, -1, -1));
 
         checkPoints(Region.Location.BOUNDARY, polySet,
-                Point3D.of(0.5, 0, 0),
-                Point3D.of(-0.5, 0, 0),
-                Point3D.of(0, 0.5, 0),
-                Point3D.of(0, -0.5, 0),
-                Point3D.of(0, 0, 0.5),
-                Point3D.of(0, 0, -0.5),
-
-                Point3D.of(0.5, 0.5, 0.5),
-                Point3D.of(0.5, 0.5, -0.5),
-                Point3D.of(0.5, -0.5, 0.5),
-                Point3D.of(0.5, -0.5, -0.5),
-                Point3D.of(-0.5, 0.5, 0.5),
-                Point3D.of(-0.5, 0.5, -0.5),
-                Point3D.of(-0.5, -0.5, 0.5),
-                Point3D.of(-0.5, -0.5, -0.5));
+                Vector3D.of(0.5, 0, 0),
+                Vector3D.of(-0.5, 0, 0),
+                Vector3D.of(0, 0.5, 0),
+                Vector3D.of(0, -0.5, 0),
+                Vector3D.of(0, 0, 0.5),
+                Vector3D.of(0, 0, -0.5),
+
+                Vector3D.of(0.5, 0.5, 0.5),
+                Vector3D.of(0.5, 0.5, -0.5),
+                Vector3D.of(0.5, -0.5, 0.5),
+                Vector3D.of(0.5, -0.5, -0.5),
+                Vector3D.of(-0.5, 0.5, 0.5),
+                Vector3D.of(-0.5, 0.5, -0.5),
+                Vector3D.of(-0.5, -0.5, 0.5),
+                Vector3D.of(-0.5, -0.5, -0.5));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-
-                Point3D.of(0.4, 0.4, 0.4),
-                Point3D.of(0.4, 0.4, -0.4),
-                Point3D.of(0.4, -0.4, 0.4),
-                Point3D.of(0.4, -0.4, -0.4),
-                Point3D.of(-0.4, 0.4, 0.4),
-                Point3D.of(-0.4, 0.4, -0.4),
-                Point3D.of(-0.4, -0.4, 0.4),
-                Point3D.of(-0.4, -0.4, -0.4));
+                Vector3D.of(0, 0, 0),
+
+                Vector3D.of(0.4, 0.4, 0.4),
+                Vector3D.of(0.4, 0.4, -0.4),
+                Vector3D.of(0.4, -0.4, 0.4),
+                Vector3D.of(0.4, -0.4, -0.4),
+                Vector3D.of(-0.4, 0.4, 0.4),
+                Vector3D.of(-0.4, 0.4, -0.4),
+                Vector3D.of(-0.4, -0.4, 0.4),
+                Vector3D.of(-0.4, -0.4, -0.4));
     }
 
     @Test
     public void testCreateFromBoundaries_twoBoxes_disjoint() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.addAll(createBoxBoundaries(Point3D.ZERO, 1.0, TEST_TOLERANCE));
-        boundaries.addAll(createBoxBoundaries(Point3D.of(2, 0, 0), 1.0, TEST_TOLERANCE));
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.addAll(createBoxBoundaries(Vector3D.ZERO, 1.0, TEST_TOLERANCE));
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(2, 0, 0), 1.0, TEST_TOLERANCE));
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -235,26 +235,26 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(2.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(12.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(1, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(1, 0, 0),
-                Point3D.of(3, 0, 0));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(1, 0, 0),
+                Vector3D.of(3, 0, 0));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-                Point3D.of(2, 0, 0));
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(2, 0, 0));
     }
 
     @Test
     public void testCreateFromBoundaries_twoBoxes_sharedSide() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.addAll(createBoxBoundaries(Point3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
-        boundaries.addAll(createBoxBoundaries(Point3D.of(1, 0, 0), 1.0, TEST_TOLERANCE));
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(1, 0, 0), 1.0, TEST_TOLERANCE));
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -263,26 +263,26 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(2.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(10.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(0.5, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0.5, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(2, 0, 0));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(2, 0, 0));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-                Point3D.of(1, 0, 0));
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(1, 0, 0));
     }
 
     @Test
     public void testCreateFromBoundaries_twoBoxes_separationLessThanTolerance() {
         // arrange
         double tolerance = 1e-6;
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.addAll(createBoxBoundaries(Point3D.of(0, 0, 0), 1.0, tolerance));
-        boundaries.addAll(createBoxBoundaries(Point3D.of(1 + 1e-7, 0, 0), 1.0, tolerance));
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(0, 0, 0), 1.0, tolerance));
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(1 + 1e-7, 0, 0), 1.0, tolerance));
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, tolerance);
@@ -291,25 +291,25 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(tolerance, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(2.0, polySet.getSize(), tolerance);
         Assert.assertEquals(10.0, polySet.getBoundarySize(), tolerance);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(0.5 + 5e-8, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0.5 + 5e-8, 0, 0), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(2, 0, 0));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(2, 0, 0));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-                Point3D.of(1, 0, 0));
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(1, 0, 0));
     }
 
     @Test
     public void testCreateFromBoundaries_twoBoxes_sharedEdge() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.addAll(createBoxBoundaries(Point3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
-        boundaries.addAll(createBoxBoundaries(Point3D.of(1, 1, 0), 1.0, TEST_TOLERANCE));
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(1, 1, 0), 1.0, TEST_TOLERANCE));
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -318,27 +318,27 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(2.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(12.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(0.5, 0.5, 0), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0.5, 0.5, 0), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(1, 0, 0),
-                Point3D.of(0, 1, 0),
-                Point3D.of(2, 1, 0));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(1, 0, 0),
+                Vector3D.of(0, 1, 0),
+                Vector3D.of(2, 1, 0));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-                Point3D.of(1, 1, 0));
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(1, 1, 0));
     }
 
     @Test
     public void testCreateFromBoundaries_twoBoxes_sharedPoint() {
         // arrange
-        List<SubHyperplane<Point3D>> boundaries = new ArrayList<>();
-        boundaries.addAll(createBoxBoundaries(Point3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
-        boundaries.addAll(createBoxBoundaries(Point3D.of(1, 1, 1), 1.0, TEST_TOLERANCE));
+        List<SubHyperplane<Vector3D>> boundaries = new ArrayList<>();
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(0, 0, 0), 1.0, TEST_TOLERANCE));
+        boundaries.addAll(createBoxBoundaries(Vector3D.of(1, 1, 1), 1.0, TEST_TOLERANCE));
 
         // act
         PolyhedronsSet polySet = new PolyhedronsSet(boundaries, TEST_TOLERANCE);
@@ -347,19 +347,19 @@ public class PolyhedronsSetTest {
         Assert.assertEquals(TEST_TOLERANCE, polySet.getTolerance(), Precision.EPSILON);
         Assert.assertEquals(2.0, polySet.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(12.0, polySet.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(0.5, 0.5, 0.5), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0.5, 0.5, 0.5), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-1, 0, 0),
-                Point3D.of(1, 0, 0),
-                Point3D.of(0, 1, 1),
-                Point3D.of(2, 1, 1));
+                Vector3D.of(-1, 0, 0),
+                Vector3D.of(1, 0, 0),
+                Vector3D.of(0, 1, 1),
+                Vector3D.of(2, 1, 1));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(0, 0, 0),
-                Point3D.of(1, 1, 1));
+                Vector3D.of(0, 0, 0),
+                Vector3D.of(1, 1, 1));
     }
 
     @Test
@@ -370,7 +370,7 @@ public class PolyhedronsSetTest {
         // assert
         Assert.assertEquals(1.0, tree.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(6.0, tree.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(0.5, 0.5, 0.5), tree.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0.5, 0.5, 0.5), tree.getBarycenter(), TEST_TOLERANCE);
 
         for (double x = -0.25; x < 1.25; x += 0.1) {
             boolean xOK = (x >= 0.0) && (x <= 1.0);
@@ -380,25 +380,25 @@ public class PolyhedronsSetTest {
                     boolean zOK = (z >= 0.0) && (z <= 1.0);
                     Region.Location expected =
                         (xOK && yOK && zOK) ? Region.Location.INSIDE : Region.Location.OUTSIDE;
-                    Assert.assertEquals(expected, tree.checkPoint(Point3D.of(x, y, z)));
+                    Assert.assertEquals(expected, tree.checkPoint(Vector3D.of(x, y, z)));
                 }
             }
         }
-        checkPoints(Region.Location.BOUNDARY, tree, new Point3D[] {
-            Point3D.of(0.0, 0.5, 0.5),
-            Point3D.of(1.0, 0.5, 0.5),
-            Point3D.of(0.5, 0.0, 0.5),
-            Point3D.of(0.5, 1.0, 0.5),
-            Point3D.of(0.5, 0.5, 0.0),
-            Point3D.of(0.5, 0.5, 1.0)
+        checkPoints(Region.Location.BOUNDARY, tree, new Vector3D[] {
+            Vector3D.of(0.0, 0.5, 0.5),
+            Vector3D.of(1.0, 0.5, 0.5),
+            Vector3D.of(0.5, 0.0, 0.5),
+            Vector3D.of(0.5, 1.0, 0.5),
+            Vector3D.of(0.5, 0.5, 0.0),
+            Vector3D.of(0.5, 0.5, 1.0)
         });
-        checkPoints(Region.Location.OUTSIDE, tree, new Point3D[] {
-            Point3D.of(0.0, 1.2, 1.2),
-            Point3D.of(1.0, 1.2, 1.2),
-            Point3D.of(1.2, 0.0, 1.2),
-            Point3D.of(1.2, 1.0, 1.2),
-            Point3D.of(1.2, 1.2, 0.0),
-            Point3D.of(1.2, 1.2, 1.0)
+        checkPoints(Region.Location.OUTSIDE, tree, new Vector3D[] {
+            Vector3D.of(0.0, 1.2, 1.2),
+            Vector3D.of(1.0, 1.2, 1.2),
+            Vector3D.of(1.2, 0.0, 1.2),
+            Vector3D.of(1.2, 1.0, 1.2),
+            Vector3D.of(1.2, 1.2, 0.0),
+            Vector3D.of(1.2, 1.2, 1.0)
         });
     }
 
@@ -408,13 +408,13 @@ public class PolyhedronsSetTest {
         PolyhedronsSet tree = new PolyhedronsSet(0, 1, 0, 1, 0, 1, 1.0e-10);
 
         // act
-        tree = (PolyhedronsSet) new RegionFactory<Point3D>().getComplement(tree);
+        tree = (PolyhedronsSet) new RegionFactory<Vector3D>().getComplement(tree);
 
         // assert
         EuclideanTestUtils.assertPositiveInfinity(tree.getSize());
         Assert.assertEquals(6.0, tree.getBoundarySize(), 1.0e-10);
 
-        Point3D barycenter = tree.getBarycenter();
+        Vector3D barycenter = tree.getBarycenter();
         Assert.assertTrue(Double.isNaN(barycenter.getX()));
         Assert.assertTrue(Double.isNaN(barycenter.getY()));
         Assert.assertTrue(Double.isNaN(barycenter.getZ()));
@@ -427,39 +427,39 @@ public class PolyhedronsSetTest {
                     boolean zOK = (z < 0.0) || (z > 1.0);
                     Region.Location expected =
                         (xOK || yOK || zOK) ? Region.Location.INSIDE : Region.Location.OUTSIDE;
-                    Assert.assertEquals(expected, tree.checkPoint(Point3D.of(x, y, z)));
+                    Assert.assertEquals(expected, tree.checkPoint(Vector3D.of(x, y, z)));
                 }
             }
         }
-        checkPoints(Region.Location.BOUNDARY, tree, new Point3D[] {
-            Point3D.of(0.0, 0.5, 0.5),
-            Point3D.of(1.0, 0.5, 0.5),
-            Point3D.of(0.5, 0.0, 0.5),
-            Point3D.of(0.5, 1.0, 0.5),
-            Point3D.of(0.5, 0.5, 0.0),
-            Point3D.of(0.5, 0.5, 1.0)
+        checkPoints(Region.Location.BOUNDARY, tree, new Vector3D[] {
+            Vector3D.of(0.0, 0.5, 0.5),
+            Vector3D.of(1.0, 0.5, 0.5),
+            Vector3D.of(0.5, 0.0, 0.5),
+            Vector3D.of(0.5, 1.0, 0.5),
+            Vector3D.of(0.5, 0.5, 0.0),
+            Vector3D.of(0.5, 0.5, 1.0)
         });
-        checkPoints(Region.Location.INSIDE, tree, new Point3D[] {
-            Point3D.of(0.0, 1.2, 1.2),
-            Point3D.of(1.0, 1.2, 1.2),
-            Point3D.of(1.2, 0.0, 1.2),
-            Point3D.of(1.2, 1.0, 1.2),
-            Point3D.of(1.2, 1.2, 0.0),
-            Point3D.of(1.2, 1.2, 1.0)
+        checkPoints(Region.Location.INSIDE, tree, new Vector3D[] {
+            Vector3D.of(0.0, 1.2, 1.2),
+            Vector3D.of(1.0, 1.2, 1.2),
+            Vector3D.of(1.2, 0.0, 1.2),
+            Vector3D.of(1.2, 1.0, 1.2),
+            Vector3D.of(1.2, 1.2, 0.0),
+            Vector3D.of(1.2, 1.2, 1.0)
         });
     }
 
     @Test
     public void testTetrahedron() {
         // arrange
-        Point3D vertex1 = Point3D.of(1, 2, 3);
-        Point3D vertex2 = Point3D.of(2, 2, 4);
-        Point3D vertex3 = Point3D.of(2, 3, 3);
-        Point3D vertex4 = Point3D.of(1, 3, 4);
+        Vector3D vertex1 = Vector3D.of(1, 2, 3);
+        Vector3D vertex2 = Vector3D.of(2, 2, 4);
+        Vector3D vertex3 = Vector3D.of(2, 3, 3);
+        Vector3D vertex4 = Vector3D.of(1, 3, 4);
 
         // act
         PolyhedronsSet tree =
-            (PolyhedronsSet) new RegionFactory<Point3D>().buildConvex(
+            (PolyhedronsSet) new RegionFactory<Vector3D>().buildConvex(
                 new Plane(vertex3, vertex2, vertex1, TEST_TOLERANCE),
                 new Plane(vertex2, vertex3, vertex4, TEST_TOLERANCE),
                 new Plane(vertex4, vertex3, vertex1, TEST_TOLERANCE),
@@ -468,21 +468,21 @@ public class PolyhedronsSetTest {
         // assert
         Assert.assertEquals(1.0 / 3.0, tree.getSize(), TEST_TOLERANCE);
         Assert.assertEquals(2.0 * Math.sqrt(3.0), tree.getBoundarySize(), TEST_TOLERANCE);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(1.5, 2.5, 3.5), tree.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1.5, 2.5, 3.5), tree.getBarycenter(), TEST_TOLERANCE);
 
         double third = 1.0 / 3.0;
-        checkPoints(Region.Location.BOUNDARY, tree, new Point3D[] {
+        checkPoints(Region.Location.BOUNDARY, tree, new Vector3D[] {
             vertex1, vertex2, vertex3, vertex4,
-            Point3D.vectorCombination(third, vertex1, third, vertex2, third, vertex3),
-            Point3D.vectorCombination(third, vertex2, third, vertex3, third, vertex4),
-            Point3D.vectorCombination(third, vertex3, third, vertex4, third, vertex1),
-            Point3D.vectorCombination(third, vertex4, third, vertex1, third, vertex2)
+            Vector3D.linearCombination(third, vertex1, third, vertex2, third, vertex3),
+            Vector3D.linearCombination(third, vertex2, third, vertex3, third, vertex4),
+            Vector3D.linearCombination(third, vertex3, third, vertex4, third, vertex1),
+            Vector3D.linearCombination(third, vertex4, third, vertex1, third, vertex2)
         });
-        checkPoints(Region.Location.OUTSIDE, tree, new Point3D[] {
-            Point3D.of(1, 2, 4),
-            Point3D.of(2, 2, 3),
-            Point3D.of(2, 3, 4),
-            Point3D.of(1, 3, 3)
+        checkPoints(Region.Location.OUTSIDE, tree, new Vector3D[] {
+            Vector3D.of(1, 2, 4),
+            Vector3D.of(2, 2, 3),
+            Vector3D.of(2, 3, 4),
+            Vector3D.of(1, 3, 3)
         });
     }
 
@@ -494,93 +494,93 @@ public class PolyhedronsSetTest {
         double radius = 1.0;
 
         // act
-        PolyhedronsSet polySet = createSphere(Point3D.of(1, 2, 3), radius, 8, 16);
+        PolyhedronsSet polySet = createSphere(Vector3D.of(1, 2, 3), radius, 8, 16);
 
         // assert
         Assert.assertEquals(sphereVolume(radius), polySet.getSize(), approximationTolerance);
         Assert.assertEquals(sphereSurface(radius), polySet.getBoundarySize(), approximationTolerance);
-        EuclideanTestUtils.assertCoordinatesEqual(Point3D.of(1, 2, 3), polySet.getBarycenter(), TEST_TOLERANCE);
+        EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 2, 3), polySet.getBarycenter(), TEST_TOLERANCE);
         Assert.assertFalse(polySet.isEmpty());
         Assert.assertFalse(polySet.isFull());
 
         checkPoints(Region.Location.OUTSIDE, polySet,
-                Point3D.of(-0.1, 2, 3),
-                Point3D.of(2.1, 2, 3),
-                Point3D.of(1, 0.9, 3),
-                Point3D.of(1, 3.1, 3),
-                Point3D.of(1, 2, 1.9),
-                Point3D.of(1, 2, 4.1),
-                Point3D.of(1.6, 2.6, 3.6));
+                Vector3D.of(-0.1, 2, 3),
+                Vector3D.of(2.1, 2, 3),
+                Vector3D.of(1, 0.9, 3),
+                Vector3D.of(1, 3.1, 3),
+                Vector3D.of(1, 2, 1.9),
+                Vector3D.of(1, 2, 4.1),
+                Vector3D.of(1.6, 2.6, 3.6));
 
         checkPoints(Region.Location.INSIDE, polySet,
-                Point3D.of(1, 2, 3),
-                Point3D.of(0.1, 2, 3),
-                Point3D.of(1.9, 2, 3),
-                Point3D.of(1, 2.1, 3),
-                Point3D.of(1, 2.9, 3),
-                Point3D.of(1, 2, 2.1),
-                Point3D.of(1, 2, 3.9),
-                Point3D.of(1.5, 2.5, 3.5));
+                Vector3D.of(1, 2, 3),
+                Vector3D.of(0.1, 2, 3),
+                Vector3D.of(1.9, 2, 3),
+                Vector3D.of(1, 2.1, 3),
+                Vector3D.of(1, 2.9, 3),
+                Vector3D.of(1, 2, 2.1),
+                Vector3D.of(1, 2, 3.9),
+                Vector3D.of(1.5, 2.5, 3.5));
     }
 
     @Test
     public void testIsometry() {
         // arrange
-        Point3D vertex1 = Point3D.of(1.1, 2.2, 3.3);
-        Point3D vertex2 = Point3D.of(2.0, 2.4, 4.2);
-        Point3D vertex3 = Point3D.of(2.8, 3.3, 3.7);
-        Point3D vertex4 = Point3D.of(1.0, 3.6, 4.5);
+        Vector3D vertex1 = Vector3D.of(1.1, 2.2, 3.3);
+        Vector3D vertex2 = Vector3D.of(2.0, 2.4, 4.2);
+        Vector3D vertex3 = Vector3D.of(2.8, 3.3, 3.7);
+        Vector3D vertex4 = Vector3D.of(1.0, 3.6, 4.5);
 
         // act
         PolyhedronsSet tree =
-            (PolyhedronsSet) new RegionFactory<Point3D>().buildConvex(
+            (PolyhedronsSet) new RegionFactory<Vector3D>().buildConvex(
                 new Plane(vertex3, vertex2, vertex1, TEST_TOLERANCE),
                 new Plane(vertex2, vertex3, vertex4, TEST_TOLERANCE),
                 new Plane(vertex4, vertex3, vertex1, TEST_TOLERANCE),
                 new Plane(vertex1, vertex2, vertex4, TEST_TOLERANCE));
 
         // assert
-        Point3D barycenter = tree.getBarycenter();
+        Vector3D barycenter = tree.getBarycenter();
         Vector3D s = Vector3D.of(10.2, 4.3, -6.7);
-        Point3D c = Point3D.of(-0.2, 2.1, -3.2);
+        Vector3D c = Vector3D.of(-0.2, 2.1, -3.2);
         Rotation r = new Rotation(Vector3D.of(6.2, -4.4, 2.1), 0.12, RotationConvention.VECTOR_OPERATOR);
 
         tree = tree.rotate(c, r).translate(s);
 
-        Point3D newB =
-                Point3D.vectorCombination(1.0, s,
+        Vector3D newB =
+                Vector3D.linearCombination(1.0, s,
                          1.0, c,
                          1.0, r.applyTo(barycenter.subtract(c)));
         Assert.assertEquals(0.0,
                             newB.subtract(tree.getBarycenter()).getNorm(),
                             TEST_TOLERANCE);
 
-        final Point3D[] expectedV = new Point3D[] {
-                Point3D.vectorCombination(1.0, s,
+        final Vector3D[] expectedV = new Vector3D[] {
+                Vector3D.linearCombination(1.0, s,
                          1.0, c,
                          1.0, r.applyTo(vertex1.subtract(c))),
-                            Point3D.vectorCombination(1.0, s,
... 5835 lines suppressed ...