View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.geometry.euclidean.threed;
    18
    19  import java.util.Arrays;
    20  import java.util.List;
    21  import java.util.regex.Pattern;
    22
    23  import org.apache.commons.geometry.core.GeometryTestUtils;
    24  import org.apache.commons.geometry.core.RegionLocation;
    25  import org.apache.commons.geometry.core.partitioning.Split;
    26  import org.apache.commons.geometry.core.partitioning.SplitLocation;
    27  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    28  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
    29  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    30  import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
    31  import org.apache.commons.geometry.euclidean.twod.ConvexArea;
    32  import org.apache.commons.geometry.euclidean.twod.Lines;
    33  import org.apache.commons.geometry.euclidean.twod.Vector2D;
    34  import org.apache.commons.geometry.euclidean.twod.path.LinePath;
    35  import org.apache.commons.geometry.euclidean.twod.shape.Parallelogram;
    36  import org.apache.commons.numbers.angle.PlaneAngleRadians;
    37  import org.junit.Assert;
    38  import org.junit.Test;
    39
    40  public class EmbeddedAreaPlaneConvexSubsetTest {
    41
    42      private static final double TEST_EPS = 1e-10;
    43
    44      private static final DoublePrecisionContext TEST_PRECISION =
    45              new EpsilonDoublePrecisionContext(TEST_EPS);
    46
    47      private static final EmbeddingPlane XY_PLANE_Z1 = Planes.fromPointAndPlaneVectors(Vector3D.of(0, 0, 1),
    48              Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
    49
    50      @Test
    51      public void testSpaceConversion() {
    52          // arrange
    53          final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 0, 0),
    54                  Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z, TEST_PRECISION);
    55
    56          final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(plane, ConvexArea.full());
    57
    58          // act/assert
    59          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2), ps.toSubspace(Vector3D.of(-5, 1, 2)), TEST_EPS);
    60          EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, -2, 4), ps.toSpace(Vector2D.of(-2, 4)), TEST_EPS);
    61      }
    62
    63      @Test
    64      public void testProperties_infinite() {
    65          // arrange
    66          final ConvexArea area = ConvexArea.full();
    67
    68          // act
    69          final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1, area);
    70
    71          // assert
    72          Assert.assertTrue(ps.isFull());
    73          Assert.assertFalse(ps.isEmpty());
    74          Assert.assertFalse(ps.isFinite());
    75          Assert.assertTrue(ps.isInfinite());
    76
    77          GeometryTestUtils.assertPositiveInfinity(ps.getSize());
    78
    79          Assert.assertSame(XY_PLANE_Z1, ps.getPlane());
    80          Assert.assertSame(area, ps.getSubspaceRegion());
    81
    82          Assert.assertEquals(0, ps.getVertices().size());
    83      }
    84
    85      @Test
    86      public void testProperties_finite() {
    87          // arrange
    88          final ConvexArea area = ConvexArea.convexPolygonFromPath(LinePath.builder(TEST_PRECISION)
    89                  .appendVertices(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1))
    90                  .build(true));
    91
    92          // act
    93          final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1, area);
    94
    95          // assert
    96          Assert.assertFalse(ps.isFull());
    97          Assert.assertFalse(ps.isEmpty());
    98          Assert.assertTrue(ps.isFinite());
    99          Assert.assertFalse(ps.isInfinite());
    100
    101         Assert.assertEquals(0.5, ps.getSize(), TEST_EPS);
    102
    103         Assert.assertSame(XY_PLANE_Z1, ps.getPlane());
    104         Assert.assertSame(area, ps.getSubspaceRegion());
    105
    106         EuclideanTestUtils.assertVertexLoopSequence(
    107                 Arrays.asList(Vector3D.of(0, 0, 1), Vector3D.of(1, 0, 1), Vector3D.of(0, 1, 1)),
    108                 ps.getVertices(), TEST_PRECISION);
    109     }
    110
    111     @Test
    112     public void testGetVertices_twoParallelLines() {
    113         // arrange
    114         final EmbeddingPlane plane = Planes.fromNormal(Vector3D.Unit.PLUS_Z, TEST_PRECISION).getEmbedding();
    115         final PlaneConvexSubset sp = new EmbeddedAreaPlaneConvexSubset(plane, ConvexArea.fromBounds(
    116                     Lines.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION),
    117                     Lines.fromPointAndAngle(Vector2D.of(0, -1), 0.0, TEST_PRECISION)
    118                 ));
    119
    120         // act
    121         final List<Vector3D> vertices = sp.getVertices();
    122
    123         // assert
    124         Assert.assertEquals(0, vertices.size());
    125     }
    126
    127     @Test
    128     public void testGetVertices_infiniteWithVertices() {
    129         // arrange
    130         final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(0, 0, 1), Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
    131         final PlaneConvexSubset sp = new EmbeddedAreaPlaneConvexSubset(plane, ConvexArea.fromBounds(
    132                     Lines.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION),
    133                     Lines.fromPointAndAngle(Vector2D.of(0, -1), 0.0, TEST_PRECISION),
    134                     Lines.fromPointAndAngle(Vector2D.of(1, 0), PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION)
    135                 ));
    136
    137         // act
    138         final List<Vector3D> vertices = sp.getVertices();
    139
    140         // assert
    141         Assert.assertEquals(2, vertices.size());
    142
    143         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, -1, 1), vertices.get(0), TEST_EPS);
    144         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 1, 1), vertices.get(1), TEST_EPS);
    145     }
    146     @Test
    147     public void testToTriangles_infinite() {
    148         // arrange
    149         final Pattern pattern = Pattern.compile("^Cannot convert infinite plane subset to triangles: .*");
    150
    151         // act/assert
    152         GeometryTestUtils.assertThrows(() -> {
    153             new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1, ConvexArea.full()).toTriangles();
    154         }, IllegalStateException.class, pattern);
    155
    156         GeometryTestUtils.assertThrows(() -> {
    157             final ConvexArea area = ConvexArea.fromBounds(Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION));
    158             final EmbeddedAreaPlaneConvexSubset halfSpace = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1, area);
    159
    160             halfSpace.toTriangles();
    161         }, IllegalStateException.class, pattern);
    162
    163         GeometryTestUtils.assertThrows(() -> {
    164             final ConvexArea area = ConvexArea.fromBounds(
    165                     Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION),
    166                     Lines.fromPointAndAngle(Vector2D.ZERO, 0.5 * Math.PI, TEST_PRECISION));
    167
    168             final EmbeddedAreaPlaneConvexSubset halfSpaceWithVertices = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1, area);
    169
    170             halfSpaceWithVertices.toTriangles();
    171         }, IllegalStateException.class, pattern);
    172     }
    173
    174     @Test
    175     public void testToTriangles_finite() {
    176         // arrange
    177         final Vector3D p1 = Vector3D.of(0, 0, 1);
    178         final Vector3D p2 = Vector3D.of(1, 0, 1);
    179         final Vector3D p3 = Vector3D.of(2, 1, 1);
    180         final Vector3D p4 = Vector3D.of(1.5, 1, 1);
    181
    182         final List<Vector2D> subPts = XY_PLANE_Z1.toSubspace(Arrays.asList(p1, p2, p3, p4));
    183
    184         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    185                 ConvexArea.convexPolygonFromVertices(subPts, TEST_PRECISION));
    186
    187         // act
    188         final List<Triangle3D> tris = ps.toTriangles();
    189
    190         // assert
    191         Assert.assertEquals(2, tris.size());
    192
    193         EuclideanTestUtils.assertVertexLoopSequence(Arrays.asList(p4, p1, p2),
    194                 tris.get(0).getVertices(), TEST_PRECISION);
    195         EuclideanTestUtils.assertVertexLoopSequence(Arrays.asList(p4, p2, p3),
    196                 tris.get(1).getVertices(), TEST_PRECISION);
    197     }
    198
    199     @Test
    200     public void testClassify() {
    201         // arrange
    202         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    203                 Parallelogram.builder(TEST_PRECISION)
    204                     .setPosition(Vector2D.of(2, 3))
    205                     .setScale(2, 2)
    206                     .build());
    207
    208         // act/assert
    209         checkPoints(ps, RegionLocation.INSIDE, Vector3D.of(2, 3, 1));
    210         checkPoints(ps, RegionLocation.BOUNDARY,
    211                 Vector3D.of(1, 3, 1), Vector3D.of(3, 3, 1),
    212                 Vector3D.of(2, 2, 1), Vector3D.of(2, 4, 1));
    213         checkPoints(ps, RegionLocation.OUTSIDE,
    214                 Vector3D.of(2, 3, 0), Vector3D.of(2, 3, 2),
    215                 Vector3D.of(0, 3, 1), Vector3D.of(4, 3, 1),
    216                 Vector3D.of(2, 1, 1), Vector3D.of(2, 5, 1));
    217     }
    218
    219     @Test
    220     public void testClosest() {
    221         // arrange
    222         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    223                 Parallelogram.builder(TEST_PRECISION)
    224                     .setPosition(Vector2D.of(2, 3))
    225                     .setScale(2, 2)
    226                     .build());
    227
    228         // act/assert
    229         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(2, 3, 1), ps.closest(Vector3D.of(2, 3, 1)), TEST_EPS);
    230         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(2, 3, 1), ps.closest(Vector3D.of(2, 3, 100)), TEST_EPS);
    231         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 2, 1),
    232                 ps.closest(Vector3D.of(-100, -100, -100)), TEST_EPS);
    233         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(3, 3.5, 1),
    234                 ps.closest(Vector3D.of(100, 3.5, 100)), TEST_EPS);
    235     }
    236
    237     @Test
    238     public void testGetBounds_noBounds() {
    239         // arrange
    240         final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(0, 0, 1),
    241                 Vector3D.Unit.PLUS_Y, Vector3D.Unit.MINUS_X, TEST_PRECISION);
    242
    243         final EmbeddedAreaPlaneConvexSubset full = new EmbeddedAreaPlaneConvexSubset(plane, ConvexArea.full());
    244         final EmbeddedAreaPlaneConvexSubset halfPlane = new EmbeddedAreaPlaneConvexSubset(plane,
    245                 ConvexArea.fromBounds(Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION)));
    246
    247         // act/assert
    248         Assert.assertNull(full.getBounds());
    249         Assert.assertNull(halfPlane.getBounds());
    250     }
    251
    252     @Test
    253     public void testGetBounds_hasBounds() {
    254         // arrange
    255         final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(0, 0, 1),
    256                 Vector3D.Unit.PLUS_Y, Vector3D.Unit.MINUS_X, TEST_PRECISION);
    257
    258         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(plane,
    259                 ConvexArea.convexPolygonFromVertices(Arrays.asList(
    260                     Vector2D.of(1, 1), Vector2D.of(2, 1), Vector2D.of(1, 2)
    261                 ), TEST_PRECISION));
    262
    263         // act
    264         final Bounds3D bounds = ps.getBounds();
    265
    266         // assert
    267         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-2, 1, 1), bounds.getMin(), TEST_EPS);
    268         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-1, 2, 1), bounds.getMax(), TEST_EPS);
    269     }
    270
    271     @Test
    272     public void testTransform() {
    273         // arrange
    274         final AffineTransformMatrix3D t = AffineTransformMatrix3D.identity()
    275                 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, -PlaneAngleRadians.PI_OVER_TWO))
    276                 .scale(1, 1, 2)
    277                 .translate(Vector3D.of(1, 0, 0));
    278
    279         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    280                 Parallelogram.builder(TEST_PRECISION)
    281                     .setPosition(Vector2D.of(2, 3))
    282                     .setScale(2, 2)
    283                     .build());
    284
    285         // act
    286         final EmbeddedAreaPlaneConvexSubset result = ps.transform(t);
    287
    288         // assert
    289         Assert.assertFalse(result.isFull());
    290         Assert.assertFalse(result.isEmpty());
    291         Assert.assertTrue(result.isFinite());
    292         Assert.assertFalse(result.isInfinite());
    293
    294         Assert.assertEquals(8, result.getSize(), TEST_EPS);
    295
    296         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_X, result.getPlane().getNormal(), TEST_EPS);
    297         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Z, result.getPlane().getU(), TEST_EPS);
    298
    299         EuclideanTestUtils.assertVertexLoopSequence(
    300                 Arrays.asList(Vector3D.of(0, 2, 2), Vector3D.of(0, 2, 6), Vector3D.of(0, 4, 6), Vector3D.of(0, 4, 2)),
    301                 result.getVertices(), TEST_PRECISION);
    302     }
    303
    304     @Test
    305     public void testReverse() {
    306         // arrange
    307         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    308                 Parallelogram.builder(TEST_PRECISION)
    309                     .setPosition(Vector2D.of(2, 3))
    310                     .setScale(2, 2)
    311                     .build());
    312
    313         // act
    314         final EmbeddedAreaPlaneConvexSubset result = ps.reverse();
    315
    316         // assert
    317         Assert.assertFalse(result.isFull());
    318         Assert.assertFalse(result.isEmpty());
    319         Assert.assertTrue(result.isFinite());
    320         Assert.assertFalse(result.isInfinite());
    321
    322         Assert.assertEquals(4, result.getSize(), TEST_EPS);
    323
    324         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_Z, result.getPlane().getNormal(), TEST_EPS);
    325         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Y, result.getPlane().getU(), TEST_EPS);
    326
    327         EuclideanTestUtils.assertVertexLoopSequence(
    328                 Arrays.asList(Vector3D.of(1, 4, 1), Vector3D.of(3, 4, 1), Vector3D.of(3, 2, 1), Vector3D.of(1, 2, 1)),
    329                 result.getVertices(), TEST_PRECISION);
    330     }
    331
    332     @Test
    333     public void testSplit_plus() {
    334         // arrange
    335         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    336                 ConvexArea.convexPolygonFromVertices(Arrays.asList(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1)),
    337                         TEST_PRECISION));
    338
    339         final Plane splitter = Planes.fromPointAndNormal(Vector3D.ZERO, Vector3D.Unit.PLUS_X, TEST_PRECISION);
    340
    341         // act
    342         final Split<PlaneConvexSubset> split = ps.split(splitter);
    343
    344         // assert
    345         Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
    346
    347         Assert.assertNull(split.getMinus());
    348         Assert.assertSame(ps, split.getPlus());
    349     }
    350
    351     @Test
    352     public void testSplit_minus() {
    353         // arrange
    354         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    355                 ConvexArea.convexPolygonFromVertices(Arrays.asList(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1)),
    356                         TEST_PRECISION));
    357
    358         final Plane splitter = Planes.fromPointAndNormal(Vector3D.ZERO, Vector3D.Unit.MINUS_Z, TEST_PRECISION);
    359
    360         // act
    361         final Split<PlaneConvexSubset> split = ps.split(splitter);
    362
    363         // assert
    364         Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
    365
    366         Assert.assertSame(ps, split.getMinus());
    367         Assert.assertNull(split.getPlus());
    368     }
    369
    370     @Test
    371     public void testSplit_both() {
    372         // arrange
    373         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    374                 ConvexArea.convexPolygonFromVertices(Arrays.asList(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1)),
    375                         TEST_PRECISION));
    376
    377         final Plane splitter = Planes.fromPointAndNormal(Vector3D.ZERO, Vector3D.of(-1, 1, 0), TEST_PRECISION);
    378
    379         // act
    380         final Split<PlaneConvexSubset> split = ps.split(splitter);
    381
    382         // assert
    383         Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
    384
    385         final PlaneConvexSubset minus = split.getMinus();
    386         EuclideanTestUtils.assertVertexLoopSequence(
    387                 Arrays.asList(Vector3D.of(0, 0, 1), Vector3D.of(1, 0, 1), Vector3D.of(0.5, 0.5, 1)),
    388                 minus.getVertices(), TEST_PRECISION);
    389
    390         final PlaneConvexSubset plus = split.getPlus();
    391         EuclideanTestUtils.assertVertexLoopSequence(
    392                 Arrays.asList(Vector3D.of(0, 0, 1), Vector3D.of(0.5, 0.5, 1), Vector3D.of(0, 1, 1)),
    393                 plus.getVertices(), TEST_PRECISION);
    394     }
    395
    396     @Test
    397     public void testSplit_neither() {
    398         // arrange
    399         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    400                 ConvexArea.convexPolygonFromVertices(Arrays.asList(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1)),
    401                         TEST_PRECISION));
    402
    403         final Plane splitter = Planes.fromPointAndNormal(Vector3D.of(0, 0, 1), Vector3D.of(0, 1e-15, -1), TEST_PRECISION);
    404
    405         // act
    406         final Split<PlaneConvexSubset> split = ps.split(splitter);
    407
    408         // assert
    409         Assert.assertEquals(SplitLocation.NEITHER, split.getLocation());
    410
    411         Assert.assertNull(split.getMinus());
    412         Assert.assertNull(split.getPlus());
    413     }
    414
    415     @Test
    416     public void testSplit_usesVertexBasedSubsetsWhenPossible() {
    417         // arrange
    418         // create an infinite subset
    419         final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.ZERO,
    420                 Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
    421         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(plane, ConvexArea.fromBounds(
    422                     Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION),
    423                     Lines.fromPointAndAngle(Vector2D.of(1, 0), PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION),
    424                     Lines.fromPointAndAngle(Vector2D.of(0, 1), -PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION)
    425                 ));
    426
    427         final Plane splitter = Planes.fromPointAndNormal(Vector3D.of(0.5, 0.5, 0), Vector3D.of(-1, 1, 0), TEST_PRECISION);
    428
    429         // act
    430         final Split<PlaneConvexSubset> split = ps.split(splitter);
    431
    432         // assert
    433         Assert.assertTrue(ps.isInfinite());
    434
    435         Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
    436
    437         final PlaneConvexSubset plus = split.getPlus();
    438         Assert.assertNotNull(plus);
    439         Assert.assertTrue(plus.isInfinite());
    440         Assert.assertTrue(plus instanceof EmbeddedAreaPlaneConvexSubset);
    441
    442         final PlaneConvexSubset minus = split.getMinus();
    443         Assert.assertNotNull(minus);
    444         Assert.assertFalse(minus.isInfinite());
    445         Assert.assertTrue(minus instanceof SimpleTriangle3D);
    446     }
    447
    448     @Test
    449     public void testToString() {
    450         // arrange
    451         final EmbeddedAreaPlaneConvexSubset ps = new EmbeddedAreaPlaneConvexSubset(XY_PLANE_Z1,
    452                 ConvexArea.convexPolygonFromVertices(Arrays.asList(Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(0, 1)),
    453                         TEST_PRECISION));
    454
    455         // act
    456         final String str = ps.toString();
    457
    458         // assert
    459         GeometryTestUtils.assertContains("EmbeddedAreaPlaneConvexSubset[plane= EmbeddingPlane[", str);
    460         GeometryTestUtils.assertContains("subspaceRegion= ConvexArea[", str);
    461     }
    462
    463     private static void checkPoints(final EmbeddedAreaPlaneConvexSubset ps, final RegionLocation loc, final Vector3D... pts) {
    464         for (final Vector3D pt : pts) {
    465             Assert.assertEquals("Unexpected location for point " + pt, loc, ps.classify(pt));
    466         }
    467     }
    468 }