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.oned;
    18
    19  import java.util.List;
    20
    21  import org.apache.commons.geometry.core.GeometryTestUtils;
    22  import org.apache.commons.geometry.core.RegionLocation;
    23  import org.apache.commons.geometry.core.Transform;
    24  import org.apache.commons.geometry.core.partitioning.HyperplaneConvexSubset;
    25  import org.apache.commons.geometry.core.partitioning.HyperplaneLocation;
    26  import org.apache.commons.geometry.core.partitioning.Split;
    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.numbers.core.Precision;
    31  import org.junit.Assert;
    32  import org.junit.Test;
    33
    34  public class OrientedPointTest {
    35
    36      private static final double TEST_EPS = 1e-15;
    37
    38      private static final DoublePrecisionContext TEST_PRECISION =
    39              new EpsilonDoublePrecisionContext(TEST_EPS);
    40
    41      @Test
    42      public void testGetDirection() {
    43          // act/assert
    44          EuclideanTestUtils.assertCoordinatesEqual(Vector1D.Unit.PLUS,
    45                  OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, TEST_PRECISION).getDirection(),
    46                  TEST_EPS);
    47          EuclideanTestUtils.assertCoordinatesEqual(Vector1D.Unit.MINUS,
    48                  OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), false, TEST_PRECISION).getDirection(),
    49                  TEST_EPS);
    50      }
    51
    52      @Test
    53      public void testReverse() {
    54          // act/assert
    55          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(0), true, TEST_PRECISION).reverse(),
    56                  0.0, false, TEST_PRECISION);
    57          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(-1), false, TEST_PRECISION).reverse(),
    58                  -1.0, true, TEST_PRECISION);
    59          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(1), true, TEST_PRECISION).reverse(),
    60                  1.0, false, TEST_PRECISION);
    61
    62          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(0), true, TEST_PRECISION).reverse().reverse(),
    63                  0.0, true, TEST_PRECISION);
    64          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(-1), false, TEST_PRECISION).reverse().reverse(),
    65                  -1.0, false, TEST_PRECISION);
    66          assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(1), true, TEST_PRECISION).reverse().reverse(),
    67                  1.0, true, TEST_PRECISION);
    68      }
    69
    70      @Test
    71      public void testTransform() {
    72          // arrange
    73          final AffineTransformMatrix1D scaleAndTranslate = AffineTransformMatrix1D
    74                  .createScale(0.5)
    75                  .translate(-10);
    76
    77          final AffineTransformMatrix1D reflect = AffineTransformMatrix1D.createScale(-2);
    78
    79          final OrientedPoint a = OrientedPoints.createPositiveFacing(Vector1D.of(2.0), TEST_PRECISION);
    80          final OrientedPoint b = OrientedPoints.createNegativeFacing(Vector1D.of(-3.0), TEST_PRECISION);
    81
    82          // act/assert
    83          assertOrientedPoint(a.transform(scaleAndTranslate), -9.0, true, TEST_PRECISION);
    84          assertOrientedPoint(b.transform(scaleAndTranslate), -11.5, false, TEST_PRECISION);
    85
    86          assertOrientedPoint(a.transform(reflect), -4.0, false, TEST_PRECISION);
    87          assertOrientedPoint(b.transform(reflect), 6.0, true, TEST_PRECISION);
    88      }
    89
    90      @Test
    91      public void testTransform_locationAtInfinity() {
    92          // arrange
    93          final OrientedPoint pos = OrientedPoints.createNegativeFacing(Double.POSITIVE_INFINITY, TEST_PRECISION);
    94          final OrientedPoint neg = OrientedPoints.createPositiveFacing(Double.NEGATIVE_INFINITY, TEST_PRECISION);
    95
    96          final Transform<Vector1D> scaleAndTranslate = AffineTransformMatrix1D.identity().scale(10.0).translate(5.0);
    97          final Transform<Vector1D> negate = AffineTransformMatrix1D.from(Vector1D::negate);
    98
    99          // act/assert
    100         assertOrientedPoint(pos.transform(scaleAndTranslate), Double.POSITIVE_INFINITY, false, TEST_PRECISION);
    101         assertOrientedPoint(neg.transform(scaleAndTranslate), Double.NEGATIVE_INFINITY, true, TEST_PRECISION);
    102
    103         assertOrientedPoint(pos.transform(negate), Double.NEGATIVE_INFINITY, true, TEST_PRECISION);
    104         assertOrientedPoint(neg.transform(negate), Double.POSITIVE_INFINITY, false, TEST_PRECISION);
    105     }
    106
    107     @Test
    108     public void testTransform_zeroScale() {
    109         // arrange
    110         final AffineTransformMatrix1D zeroScale = AffineTransformMatrix1D.createScale(0.0);
    111
    112         final OrientedPoint pt = OrientedPoints.createPositiveFacing(Vector1D.of(2.0), TEST_PRECISION);
    113
    114         // act/assert
    115         GeometryTestUtils.assertThrows(
    116             () -> pt.transform(zeroScale),
    117             IllegalArgumentException.class, "Oriented point direction cannot be zero");
    118     }
    119
    120     @Test
    121     public void testOffset_positiveFacing() {
    122         // arrange
    123         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(-2.0), true, TEST_PRECISION);
    124
    125         // act/assert
    126         Assert.assertEquals(-98.0, pt.offset(Vector1D.of(-100)), Precision.EPSILON);
    127         Assert.assertEquals(-0.1, pt.offset(Vector1D.of(-2.1)), Precision.EPSILON);
    128         Assert.assertEquals(0.0, pt.offset(Vector1D.of(-2)), Precision.EPSILON);
    129         Assert.assertEquals(0.99, pt.offset(Vector1D.of(-1.01)), Precision.EPSILON);
    130         Assert.assertEquals(1.0, pt.offset(Vector1D.of(-1.0)), Precision.EPSILON);
    131         Assert.assertEquals(1.01, pt.offset(Vector1D.of(-0.99)), Precision.EPSILON);
    132         Assert.assertEquals(2.0, pt.offset(Vector1D.of(0)), Precision.EPSILON);
    133         Assert.assertEquals(102, pt.offset(Vector1D.of(100)), Precision.EPSILON);
    134     }
    135
    136     @Test
    137     public void testOffset_negativeFacing() {
    138         // arrange
    139         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(-2.0), false, TEST_PRECISION);
    140
    141         // act/assert
    142         Assert.assertEquals(98.0, pt.offset(Vector1D.of(-100)), Precision.EPSILON);
    143         Assert.assertEquals(0.1, pt.offset(Vector1D.of(-2.1)), Precision.EPSILON);
    144         Assert.assertEquals(0.0, pt.offset(Vector1D.of(-2)), Precision.EPSILON);
    145         Assert.assertEquals(-0.99, pt.offset(Vector1D.of(-1.01)), Precision.EPSILON);
    146         Assert.assertEquals(-1.0, pt.offset(Vector1D.of(-1.0)), Precision.EPSILON);
    147         Assert.assertEquals(-1.01, pt.offset(Vector1D.of(-0.99)), Precision.EPSILON);
    148         Assert.assertEquals(-2, pt.offset(Vector1D.of(0)), Precision.EPSILON);
    149         Assert.assertEquals(-102, pt.offset(Vector1D.of(100)), Precision.EPSILON);
    150     }
    151
    152     @Test
    153     public void testOffset_infinityArguments() {
    154         // arrange
    155         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(-2.0), true, TEST_PRECISION);
    156
    157         // act/assert
    158         GeometryTestUtils.assertPositiveInfinity(pt.offset(Vector1D.of(Double.POSITIVE_INFINITY)));
    159         GeometryTestUtils.assertNegativeInfinity(pt.offset(Vector1D.of(Double.NEGATIVE_INFINITY)));
    160     }
    161
    162     @Test
    163     public void testOffset_infinityLocation() {
    164         // arrange
    165         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(Double.POSITIVE_INFINITY), true, TEST_PRECISION);
    166
    167         // act/assert
    168         Assert.assertTrue(Double.isNaN(pt.offset(Vector1D.of(Double.POSITIVE_INFINITY))));
    169         GeometryTestUtils.assertNegativeInfinity(pt.offset(Vector1D.of(Double.NEGATIVE_INFINITY)));
    170
    171         GeometryTestUtils.assertNegativeInfinity(pt.offset(Vector1D.of(0)));
    172     }
    173
    174     @Test
    175     public void testClassify() {
    176         // arrange
    177         final DoublePrecisionContext smallPrecision = new EpsilonDoublePrecisionContext(1e-10);
    178         final DoublePrecisionContext largePrecision = new EpsilonDoublePrecisionContext(1e-1);
    179
    180         final OrientedPoint smallPosFacing = OrientedPoints.fromLocationAndDirection(1.0, true, smallPrecision);
    181         final OrientedPoint largeNegFacing = OrientedPoints.fromLocationAndDirection(1.0, false, largePrecision);
    182
    183         // act/assert
    184         assertClassify(HyperplaneLocation.MINUS, smallPosFacing,
    185                 Double.NEGATIVE_INFINITY, -10, 0, 0.9, 0.99999, 1 - 1e-9);
    186         assertClassify(HyperplaneLocation.ON, smallPosFacing,
    187                 1 - 1e-11, 1, 1 + 1e-11);
    188         assertClassify(HyperplaneLocation.PLUS, smallPosFacing,
    189                 1 + 1e-9, 2, 10, Double.POSITIVE_INFINITY);
    190
    191         assertClassify(HyperplaneLocation.PLUS, largeNegFacing,
    192                 Double.NEGATIVE_INFINITY, -10, 0, 0.89);
    193         assertClassify(HyperplaneLocation.ON, largeNegFacing,
    194                 0.91, 0.9999, 1, 1.001, 1.09);
    195         assertClassify(HyperplaneLocation.MINUS, largeNegFacing,
    196                 1.11, 2, 10, Double.POSITIVE_INFINITY);
    197     }
    198
    199     @Test
    200     public void testSpan() {
    201         // arrange
    202         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(1.0), false, TEST_PRECISION);
    203
    204         // act
    205         final HyperplaneConvexSubset<Vector1D> result = pt.span();
    206
    207         // assert
    208         Assert.assertSame(pt, result.getHyperplane());
    209     }
    210
    211     @Test
    212     public void testSimilarOrientation() {
    213         // arrange
    214         final OrientedPoint negativeDir1 = OrientedPoints.fromPointAndDirection(Vector1D.of(1.0), false, TEST_PRECISION);
    215         final OrientedPoint negativeDir2 = OrientedPoints.fromPointAndDirection(Vector1D.of(-1.0), false, TEST_PRECISION);
    216         final OrientedPoint positiveDir1 = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, TEST_PRECISION);
    217         final OrientedPoint positiveDir2 = OrientedPoints.fromPointAndDirection(Vector1D.of(-2.0), true, TEST_PRECISION);
    218
    219         // act/assert
    220         Assert.assertTrue(negativeDir1.similarOrientation(negativeDir1));
    221         Assert.assertTrue(negativeDir1.similarOrientation(negativeDir2));
    222         Assert.assertTrue(negativeDir2.similarOrientation(negativeDir1));
    223
    224         Assert.assertTrue(positiveDir1.similarOrientation(positiveDir1));
    225         Assert.assertTrue(positiveDir1.similarOrientation(positiveDir2));
    226         Assert.assertTrue(positiveDir2.similarOrientation(positiveDir1));
    227
    228         Assert.assertFalse(negativeDir1.similarOrientation(positiveDir1));
    229         Assert.assertFalse(positiveDir1.similarOrientation(negativeDir1));
    230     }
    231
    232     @Test
    233     public void testProject() {
    234         // arrange
    235         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(1.0), true, TEST_PRECISION);
    236
    237         // act/assert
    238         Assert.assertEquals(1.0, pt.project(Vector1D.of(-1.0)).getX(), Precision.EPSILON);
    239         Assert.assertEquals(1.0, pt.project(Vector1D.of(0.0)).getX(), Precision.EPSILON);
    240         Assert.assertEquals(1.0, pt.project(Vector1D.of(1.0)).getX(), Precision.EPSILON);
    241         Assert.assertEquals(1.0, pt.project(Vector1D.of(100.0)).getX(), Precision.EPSILON);
    242     }
    243
    244
    245     @Test
    246     public void testEq() {
    247         // arrange
    248         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-3);
    249
    250         final OrientedPoint a = OrientedPoints.createPositiveFacing(0, precision);
    251         final OrientedPoint b = OrientedPoints.createPositiveFacing(0, TEST_PRECISION);
    252
    253         final OrientedPoint c = OrientedPoints.createPositiveFacing(2e-3, precision);
    254         final OrientedPoint d = OrientedPoints.createNegativeFacing(0, precision);
    255         final OrientedPoint e = OrientedPoints.createPositiveFacing(1e-4, precision);
    256
    257         // act/assert
    258         Assert.assertTrue(a.eq(a, precision));
    259         Assert.assertTrue(a.eq(b, precision));
    260
    261         Assert.assertFalse(a.eq(c, precision));
    262         Assert.assertFalse(a.eq(d, precision));
    263
    264         Assert.assertTrue(a.eq(e, precision));
    265         Assert.assertTrue(e.eq(a, precision));
    266     }
    267
    268     @Test
    269     public void testHashCode() {
    270         // arrange
    271         final DoublePrecisionContext precisionA = new EpsilonDoublePrecisionContext(1e-10);
    272         final DoublePrecisionContext precisionB = new EpsilonDoublePrecisionContext(1e-15);
    273
    274         final OrientedPoint a = OrientedPoints.fromPointAndDirection(Vector1D.of(3.0), true, precisionA);
    275         final OrientedPoint b = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), false, precisionA);
    276         final OrientedPoint c = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionB);
    277
    278         final OrientedPoint d = OrientedPoints.fromPointAndDirection(Vector1D.of(3.0), true, precisionA);
    279         final OrientedPoint e = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), false, precisionA);
    280         final OrientedPoint f = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionB);
    281
    282         // act/assert
    283         Assert.assertNotEquals(a.hashCode(), b.hashCode());
    284         Assert.assertNotEquals(b.hashCode(), c.hashCode());
    285         Assert.assertNotEquals(c.hashCode(), a.hashCode());
    286
    287         Assert.assertEquals(a.hashCode(), d.hashCode());
    288         Assert.assertEquals(b.hashCode(), e.hashCode());
    289         Assert.assertEquals(c.hashCode(), f.hashCode());
    290     }
    291
    292     @Test
    293     public void testEquals() {
    294         // arrange
    295         final DoublePrecisionContext precisionA = new EpsilonDoublePrecisionContext(1e-10);
    296         final DoublePrecisionContext precisionB = new EpsilonDoublePrecisionContext(1e-15);
    297
    298         final OrientedPoint a = OrientedPoints.fromPointAndDirection(Vector1D.of(1.0), true, precisionA);
    299         final OrientedPoint b = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionA);
    300
    301         final OrientedPoint c = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionA);
    302         final OrientedPoint d = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), false, precisionA);
    303
    304         final OrientedPoint e = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionA);
    305         final OrientedPoint f = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, precisionB);
    306
    307         final OrientedPoint g = OrientedPoints.fromPointAndDirection(Vector1D.of(1.0), true, precisionA);
    308
    309         // act/assert
    310         Assert.assertFalse(a.equals(null));
    311         Assert.assertFalse(a.equals(new Object()));
    312
    313         Assert.assertNotEquals(a, b);
    314         Assert.assertNotEquals(c, d);
    315         Assert.assertNotEquals(e, f);
    316
    317         Assert.assertEquals(a, a);
    318         Assert.assertEquals(a, g);
    319         Assert.assertEquals(g, a);
    320     }
    321
    322     @Test
    323     public void testToString() {
    324         // arrange
    325         final OrientedPoint pt = OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), true, TEST_PRECISION);
    326
    327         // act
    328         final String str = pt.toString();
    329
    330         // assert
    331         Assert.assertTrue(str.contains("OrientedPoint"));
    332         Assert.assertTrue(str.contains("point= (2.0)"));
    333         Assert.assertTrue(str.contains("direction= (1.0)"));
    334     }
    335
    336     @Test
    337     public void testFromLocationAndDirection() {
    338         // act/assert
    339         assertOrientedPoint(OrientedPoints.fromLocationAndDirection(3.0, true, TEST_PRECISION),
    340                 3.0, true, TEST_PRECISION);
    341         assertOrientedPoint(OrientedPoints.fromLocationAndDirection(2.0, false, TEST_PRECISION),
    342                 2.0, false, TEST_PRECISION);
    343     }
    344
    345     @Test
    346     public void testFromPointAndDirection_pointAndBooleanArgs() {
    347         // act/assert
    348         assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(3.0), true, TEST_PRECISION),
    349                 3.0, true, TEST_PRECISION);
    350         assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), false, TEST_PRECISION),
    351                 2.0, false, TEST_PRECISION);
    352     }
    353
    354     @Test
    355     public void testFromPointAndDirection_pointAndVectorArgs() {
    356         // act/assert
    357         assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(-2.0), Vector1D.of(0.1), TEST_PRECISION),
    358                 -2.0, true, TEST_PRECISION);
    359         assertOrientedPoint(OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), Vector1D.of(-10.1), TEST_PRECISION),
    360                 2.0, false, TEST_PRECISION);
    361     }
    362
    363     @Test
    364     public void testFromPointAndDirection_invalidDirection() {
    365         // arrange
    366         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(0.1);
    367
    368         // act/assert
    369         GeometryTestUtils.assertThrows(
    370             () -> OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), Vector1D.of(0.09), precision),
    371             IllegalArgumentException.class, "Oriented point direction cannot be zero");
    372         GeometryTestUtils.assertThrows(
    373             () -> OrientedPoints.fromPointAndDirection(Vector1D.of(2.0), Vector1D.of(-0.09), precision),
    374             IllegalArgumentException.class, "Oriented point direction cannot be zero");
    375     }
    376
    377     @Test
    378     public void testCreatePositiveFacing() {
    379         // act/assert
    380         assertOrientedPoint(OrientedPoints.createPositiveFacing(Vector1D.of(-2.0), TEST_PRECISION),
    381                 -2.0, true, TEST_PRECISION);
    382         assertOrientedPoint(OrientedPoints.createPositiveFacing(-4.0, TEST_PRECISION),
    383                 -4.0, true, TEST_PRECISION);
    384     }
    385
    386     @Test
    387     public void testCreateNegativeFacing() {
    388         // act/assert
    389         assertOrientedPoint(OrientedPoints.createNegativeFacing(Vector1D.of(2.0), TEST_PRECISION),
    390                 2.0, false, TEST_PRECISION);
    391         assertOrientedPoint(OrientedPoints.createNegativeFacing(4, TEST_PRECISION),
    392                 4.0, false, TEST_PRECISION);
    393     }
    394
    395     @Test
    396     public void testSubset_split() {
    397         // arrange
    398         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-3);
    399
    400         final OrientedPoint pt = OrientedPoints.createPositiveFacing(-1.5, precision);
    401         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    402
    403         // act/assert
    404         checkSplit(sub, OrientedPoints.createPositiveFacing(1.0, precision), true, false);
    405         checkSplit(sub, OrientedPoints.createPositiveFacing(-1.5 + 1e-2, precision), true, false);
    406
    407         checkSplit(sub, OrientedPoints.createNegativeFacing(1.0, precision), false, true);
    408         checkSplit(sub, OrientedPoints.createNegativeFacing(-1.5 + 1e-2, precision), false, true);
    409
    410         checkSplit(sub, OrientedPoints.createNegativeFacing(-1.5, precision), false, false);
    411         checkSplit(sub, OrientedPoints.createNegativeFacing(-1.5 + 1e-4, precision), false, false);
    412         checkSplit(sub, OrientedPoints.createNegativeFacing(-1.5 - 1e-4, precision), false, false);
    413     }
    414
    415     private void checkSplit(final HyperplaneConvexSubset<Vector1D> sub, final OrientedPoint splitter, final boolean minus, final boolean plus) {
    416         final Split<? extends HyperplaneConvexSubset<Vector1D>> split = sub.split(splitter);
    417
    418         Assert.assertSame(minus ? sub : null, split.getMinus());
    419         Assert.assertSame(plus ? sub : null, split.getPlus());
    420     }
    421
    422     @Test
    423     public void testSubset_simpleMethods() {
    424         // arrange
    425         final OrientedPoint pt = OrientedPoints.createPositiveFacing(2, TEST_PRECISION);
    426         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    427
    428         // act/assert
    429         Assert.assertSame(pt, sub.getHyperplane());
    430         Assert.assertFalse(sub.isFull());
    431         Assert.assertFalse(sub.isEmpty());
    432         Assert.assertFalse(sub.isInfinite());
    433         Assert.assertTrue(sub.isFinite());
    434         Assert.assertEquals(0.0, sub.getSize(), TEST_EPS);
    435         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(2), sub.getCentroid(), TEST_EPS);
    436
    437         final List<? extends HyperplaneConvexSubset<Vector1D>> list = sub.toConvex();
    438         Assert.assertEquals(1, list.size());
    439         Assert.assertSame(sub, list.get(0));
    440     }
    441
    442     @Test
    443     public void testSubset_classify() {
    444         // arrange
    445         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-1);
    446         final OrientedPoint pt = OrientedPoints.createPositiveFacing(1, precision);
    447         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    448
    449         // act/assert
    450         Assert.assertEquals(RegionLocation.BOUNDARY, sub.classify(Vector1D.of(0.95)));
    451         Assert.assertEquals(RegionLocation.BOUNDARY, sub.classify(Vector1D.of(1)));
    452         Assert.assertEquals(RegionLocation.BOUNDARY, sub.classify(Vector1D.of(1.05)));
    453
    454         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.of(1.11)));
    455         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.of(0.89)));
    456
    457         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.of(-3)));
    458         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.of(10)));
    459
    460         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.NEGATIVE_INFINITY));
    461         Assert.assertEquals(RegionLocation.OUTSIDE, sub.classify(Vector1D.POSITIVE_INFINITY));
    462     }
    463
    464     @Test
    465     public void testSubset_contains() {
    466         // arrange
    467         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-1);
    468         final OrientedPoint pt = OrientedPoints.createPositiveFacing(1, precision);
    469         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    470
    471         // act/assert
    472         Assert.assertTrue(sub.contains(Vector1D.of(0.95)));
    473         Assert.assertTrue(sub.contains(Vector1D.of(1)));
    474         Assert.assertTrue(sub.contains(Vector1D.of(1.05)));
    475
    476         Assert.assertFalse(sub.contains(Vector1D.of(1.11)));
    477         Assert.assertFalse(sub.contains(Vector1D.of(0.89)));
    478
    479         Assert.assertFalse(sub.contains(Vector1D.of(-3)));
    480         Assert.assertFalse(sub.contains(Vector1D.of(10)));
    481
    482         Assert.assertFalse(sub.contains(Vector1D.NEGATIVE_INFINITY));
    483         Assert.assertFalse(sub.contains(Vector1D.POSITIVE_INFINITY));
    484     }
    485
    486     @Test
    487     public void testSubset_closestContained() {
    488         // arrange
    489         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-1);
    490         final OrientedPoint pt = OrientedPoints.createPositiveFacing(1, precision);
    491         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    492
    493         // act/assert
    494         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1), sub.closest(Vector1D.NEGATIVE_INFINITY), TEST_EPS);
    495         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1), sub.closest(Vector1D.of(0)), TEST_EPS);
    496         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1), sub.closest(Vector1D.of(1)), TEST_EPS);
    497         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1), sub.closest(Vector1D.of(2)), TEST_EPS);
    498         EuclideanTestUtils.assertCoordinatesEqual(Vector1D.of(1), sub.closest(Vector1D.POSITIVE_INFINITY), TEST_EPS);
    499     }
    500
    501     @Test
    502     public void testSubset_transform() {
    503         // arrange
    504         final AffineTransformMatrix1D scaleAndTranslate = AffineTransformMatrix1D
    505                 .createScale(0.5)
    506                 .translate(-10);
    507
    508         final AffineTransformMatrix1D reflect = AffineTransformMatrix1D.createScale(-2);
    509
    510         final HyperplaneConvexSubset<Vector1D> a =
    511                 OrientedPoints.createPositiveFacing(Vector1D.of(2.0), TEST_PRECISION).span();
    512         final HyperplaneConvexSubset<Vector1D> b =
    513                 OrientedPoints.createNegativeFacing(Vector1D.of(-3.0), TEST_PRECISION).span();
    514
    515         // act/assert
    516         assertOrientedPoint((OrientedPoint) a.transform(scaleAndTranslate).getHyperplane(),
    517                 -9.0, true, TEST_PRECISION);
    518         assertOrientedPoint((OrientedPoint) b.transform(scaleAndTranslate).getHyperplane(),
    519                 -11.5, false, TEST_PRECISION);
    520
    521         assertOrientedPoint((OrientedPoint) a.transform(reflect).getHyperplane(), -4.0, false, TEST_PRECISION);
    522         assertOrientedPoint((OrientedPoint) b.transform(reflect).getHyperplane(), 6.0, true, TEST_PRECISION);
    523     }
    524
    525     @Test
    526     public void testSubset_reverse() {
    527         // arrange
    528         final OrientedPoint pt = OrientedPoints.createPositiveFacing(2.0, TEST_PRECISION);
    529         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    530
    531         // act
    532         final HyperplaneConvexSubset<Vector1D> result = sub.reverse();
    533
    534         // assert
    535         Assert.assertEquals(2.0, ((OrientedPoint) result.getHyperplane()).getLocation(), TEST_EPS);
    536         Assert.assertFalse(((OrientedPoint) result.getHyperplane()).isPositiveFacing());
    537
    538         Assert.assertEquals(sub.getHyperplane(), result.reverse().getHyperplane());
    539     }
    540
    541     @Test
    542     public void testSubset_toString() {
    543         // arrange
    544         final OrientedPoint pt = OrientedPoints.createPositiveFacing(2, TEST_PRECISION);
    545         final HyperplaneConvexSubset<Vector1D> sub = pt.span();
    546
    547         // act
    548         final String str = sub.toString();
    549
    550         //assert
    551         Assert.assertTrue(str.contains("OrientedPointConvexSubset"));
    552         Assert.assertTrue(str.contains("point= (2.0)"));
    553         Assert.assertTrue(str.contains("direction= (1.0)"));
    554     }
    555
    556     private static void assertOrientedPoint(final OrientedPoint pt, final double location, final boolean positiveFacing,
    557                                             final DoublePrecisionContext precision) {
    558         Assert.assertEquals(location, pt.getPoint().getX(), TEST_EPS);
    559         Assert.assertEquals(location, pt.getLocation(), TEST_EPS);
    560         Assert.assertEquals(positiveFacing ? 1.0 : -1.0, pt.getDirection().getX(), TEST_EPS);
    561         Assert.assertEquals(positiveFacing, pt.isPositiveFacing());
    562         Assert.assertSame(precision, pt.getPrecision());
    563     }
    564
    565     private static void assertClassify(final HyperplaneLocation expected, final OrientedPoint pt, final double... locations) {
    566         for (final double location : locations) {
    567             final String msg = "Unexpected classification for location " + location;
    568
    569             Assert.assertEquals(msg, expected, pt.classify(location));
    570             Assert.assertEquals(msg, expected, pt.classify(Vector1D.of(location)));
    571         }
    572     }
    573 }