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.spherical.oned;
    18
    19  import java.util.Comparator;
    20
    21  import org.apache.commons.geometry.core.GeometryTestUtils;
    22  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    23  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
    24  import org.apache.commons.geometry.euclidean.twod.PolarCoordinates;
    25  import org.apache.commons.geometry.euclidean.twod.Vector2D;
    26  import org.apache.commons.numbers.angle.PlaneAngle;
    27  import org.apache.commons.numbers.angle.PlaneAngleRadians;
    28  import org.junit.Assert;
    29  import org.junit.Test;
    30
    31  public class Point1STest {
    32
    33      private static final double TEST_EPS = 1e-10;
    34
    35      @Test
    36      public void testConstants() {
    37          // act/assert
    38          Assert.assertEquals(0.0, Point1S.ZERO.getAzimuth(), TEST_EPS);
    39          Assert.assertEquals(Math.PI, Point1S.PI.getAzimuth(), TEST_EPS);
    40      }
    41
    42      @Test
    43      public void testNormalizedAzimuthComparator() {
    44          // arrange
    45          final Comparator<Point1S> comp = Point1S.NORMALIZED_AZIMUTH_ASCENDING_ORDER;
    46
    47          // act/assert
    48          Assert.assertEquals(0, comp.compare(Point1S.of(1), Point1S.of(1)));
    49          Assert.assertEquals(-1, comp.compare(Point1S.of(0), Point1S.of(1)));
    50          Assert.assertEquals(1, comp.compare(Point1S.of(1), Point1S.of(0)));
    51          Assert.assertEquals(1, comp.compare(Point1S.of(1), Point1S.of(0.1 + PlaneAngleRadians.TWO_PI)));
    52
    53          Assert.assertEquals(1, comp.compare(null, Point1S.of(0)));
    54          Assert.assertEquals(-1, comp.compare(Point1S.of(0), null));
    55          Assert.assertEquals(0, comp.compare(null, null));
    56      }
    57
    58      @Test
    59      public void testOf() {
    60          // act/assert
    61          checkPoint(Point1S.of(0), 0, 0);
    62          checkPoint(Point1S.of(1), 1, 1);
    63          checkPoint(Point1S.of(-1), -1, PlaneAngleRadians.TWO_PI - 1);
    64
    65          checkPoint(Point1S.of(PlaneAngle.ofDegrees(90)), PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO);
    66          checkPoint(Point1S.of(PlaneAngle.ofTurns(0.5)), PlaneAngleRadians.PI, PlaneAngleRadians.PI);
    67          checkPoint(Point1S.of(-PlaneAngleRadians.PI_OVER_TWO), -PlaneAngleRadians.PI_OVER_TWO, 1.5 * PlaneAngleRadians.PI);
    68
    69          final double base = PlaneAngleRadians.PI_OVER_TWO;
    70          for (int k = -3; k <= 3; ++k) {
    71              final double az = base + (k * PlaneAngleRadians.TWO_PI);
    72              checkPoint(Point1S.of(az), az, base);
    73          }
    74      }
    75
    76      @Test
    77      public void testFrom_vector() {
    78          // act/assert
    79          checkPoint(Point1S.from(Vector2D.of(2, 0)), 0.0);
    80          checkPoint(Point1S.from(Vector2D.of(0, 0.1)), PlaneAngleRadians.PI_OVER_TWO);
    81          checkPoint(Point1S.from(Vector2D.of(-0.5, 0)), PlaneAngleRadians.PI);
    82          checkPoint(Point1S.from(Vector2D.of(0, -100)), 1.5 * PlaneAngleRadians.PI);
    83      }
    84
    85      @Test
    86      public void testFrom_polar() {
    87          // act/assert
    88          checkPoint(Point1S.from(PolarCoordinates.of(100, 0)), 0.0);
    89          checkPoint(Point1S.from(PolarCoordinates.of(1, PlaneAngleRadians.PI_OVER_TWO)), PlaneAngleRadians.PI_OVER_TWO);
    90          checkPoint(Point1S.from(PolarCoordinates.of(0.5, PlaneAngleRadians.PI)), PlaneAngleRadians.PI);
    91          checkPoint(Point1S.from(PolarCoordinates.of(1e-4, -PlaneAngleRadians.PI_OVER_TWO)), 1.5 * PlaneAngleRadians.PI);
    92      }
    93
    94      @Test
    95      public void testFrom_polar_invalidAzimuths() {
    96          // act/assert
    97          checkPoint(Point1S.from(PolarCoordinates.of(100, Double.POSITIVE_INFINITY)), Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    98          checkPoint(Point1S.from(PolarCoordinates.of(100, Double.NEGATIVE_INFINITY)), Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    99          checkPoint(Point1S.from(PolarCoordinates.of(100, Double.NaN)), Double.NaN, Double.NaN);
    100     }
    101
    102     @Test
    103     public void testNaN() {
    104         // act
    105         final Point1S pt = Point1S.of(Double.NaN);
    106
    107         // assert
    108         Assert.assertTrue(pt.isNaN());
    109         Assert.assertTrue(Point1S.NaN.isNaN());
    110
    111         Assert.assertTrue(Double.isNaN(pt.getAzimuth()));
    112         Assert.assertTrue(Double.isNaN(pt.getNormalizedAzimuth()));
    113         Assert.assertNull(pt.getVector());
    114
    115         Assert.assertEquals(Point1S.NaN, pt);
    116         Assert.assertNotEquals(Point1S.of(1.0), Point1S.NaN);
    117     }
    118
    119     @Test
    120     public void testGetDimension() {
    121         // arrange
    122         final Point1S p = Point1S.of(0.0);
    123
    124         // act/assert
    125         Assert.assertEquals(1, p.getDimension());
    126     }
    127
    128     @Test
    129     public void testInfinite() {
    130         // act/assert
    131         Assert.assertTrue(Point1S.of(Double.POSITIVE_INFINITY).isInfinite());
    132         Assert.assertTrue(Point1S.of(Double.NEGATIVE_INFINITY).isInfinite());
    133
    134         Assert.assertFalse(Point1S.NaN.isInfinite());
    135         Assert.assertFalse(Point1S.of(1).isInfinite());
    136     }
    137
    138     @Test
    139     public void testFinite() {
    140         // act/assert
    141         Assert.assertTrue(Point1S.of(0).isFinite());
    142         Assert.assertTrue(Point1S.of(1).isFinite());
    143
    144         Assert.assertFalse(Point1S.of(Double.POSITIVE_INFINITY).isFinite());
    145         Assert.assertFalse(Point1S.of(Double.NEGATIVE_INFINITY).isFinite());
    146         Assert.assertFalse(Point1S.NaN.isFinite());
    147     }
    148
    149     @Test
    150     public void testAntipodal() {
    151         for (double az = -6 * PlaneAngleRadians.PI; az <= 6 * PlaneAngleRadians.PI; az += 0.1) {
    152             // arrange
    153             final Point1S pt = Point1S.of(az);
    154
    155             // act
    156             final Point1S result = pt.antipodal();
    157
    158             // assert
    159             Assert.assertTrue(result.getAzimuth() >= 0 && result.getAzimuth() < PlaneAngleRadians.TWO_PI);
    160             Assert.assertEquals(PlaneAngleRadians.PI, pt.distance(result), TEST_EPS);
    161         }
    162     }
    163
    164     @Test
    165     public void testHashCode() {
    166         // act
    167         final Point1S a = Point1S.of(1.0);
    168         final Point1S b = Point1S.of(2.0);
    169         final Point1S c = Point1S.of(1.0);
    170         final Point1S d = Point1S.of(1.0 + PlaneAngleRadians.PI);
    171
    172         final int hash = a.hashCode();
    173
    174         // assert
    175         Assert.assertEquals(hash, a.hashCode());
    176         Assert.assertNotEquals(hash, b.hashCode());
    177         Assert.assertEquals(hash, c.hashCode());
    178         Assert.assertNotEquals(hash, d.hashCode());
    179
    180         Assert.assertEquals(Point1S.NaN.hashCode(), Point1S.of(Double.NaN).hashCode());
    181     }
    182
    183     @Test
    184     public void testEquals() {
    185         // act
    186         final Point1S a = Point1S.of(1.0);
    187         final Point1S b = Point1S.of(2.0);
    188         final Point1S c = Point1S.of(1.0 + PlaneAngleRadians.PI);
    189         final Point1S d = Point1S.of(1.0);
    190         final Point1S e = Point1S.of(Double.NaN);
    191
    192         // assert
    193         Assert.assertFalse(a.equals(null));
    194         Assert.assertFalse(a.equals(new Object()));
    195
    196         Assert.assertEquals(a, a);
    197
    198         Assert.assertNotEquals(a, b);
    199         Assert.assertNotEquals(b, a);
    200
    201         Assert.assertNotEquals(a, c);
    202         Assert.assertNotEquals(c, a);
    203
    204         Assert.assertEquals(a, d);
    205         Assert.assertEquals(d, a);
    206
    207         Assert.assertNotEquals(a, e);
    208         Assert.assertEquals(Point1S.NaN, e);
    209     }
    210
    211     @Test
    212     public void testEqualsAndHashCode_signedZeroConsistency() {
    213         // arrange
    214         final Point1S a = Point1S.of(0.0);
    215         final Point1S b = Point1S.of(-0.0);
    216         final Point1S c = Point1S.of(0.0);
    217         final Point1S d = Point1S.of(-0.0);
    218
    219         // act/assert
    220         Assert.assertFalse(a.equals(b));
    221         Assert.assertNotEquals(a.hashCode(), b.hashCode());
    222
    223         Assert.assertTrue(a.equals(c));
    224         Assert.assertEquals(a.hashCode(), c.hashCode());
    225
    226         Assert.assertTrue(b.equals(d));
    227         Assert.assertEquals(b.hashCode(), d.hashCode());
    228     }
    229
    230     @Test
    231     public void testEq() {
    232         // arrange
    233         final DoublePrecisionContext highPrecision = new EpsilonDoublePrecisionContext(1e-10);
    234         final DoublePrecisionContext lowPrecision = new EpsilonDoublePrecisionContext(1e-2);
    235
    236         final Point1S a = Point1S.of(1);
    237         final Point1S b = Point1S.of(0.9999);
    238         final Point1S c = Point1S.of(1.00001);
    239         final Point1S d = Point1S.of(1 + (3 * PlaneAngleRadians.TWO_PI));
    240
    241         // act/assert
    242         Assert.assertTrue(a.eq(a, highPrecision));
    243         Assert.assertTrue(a.eq(a, lowPrecision));
    244
    245         Assert.assertFalse(a.eq(b, highPrecision));
    246         Assert.assertTrue(a.eq(b, lowPrecision));
    247
    248         Assert.assertFalse(a.eq(c, highPrecision));
    249         Assert.assertTrue(a.eq(c, lowPrecision));
    250
    251         Assert.assertTrue(a.eq(d, highPrecision));
    252         Assert.assertTrue(a.eq(d, lowPrecision));
    253     }
    254
    255     @Test
    256     public void testEq_wrapAround() {
    257         // arrange
    258         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-2);
    259
    260         final Point1S a = Point1S.ZERO;
    261         final Point1S b = Point1S.of(1e-3);
    262         final Point1S c = Point1S.of(-1e-3);
    263
    264         // act/assert
    265         Assert.assertTrue(a.eq(a, precision));
    266
    267         Assert.assertTrue(a.eq(b, precision));
    268         Assert.assertTrue(b.eq(a, precision));
    269
    270         Assert.assertTrue(a.eq(c, precision));
    271         Assert.assertTrue(c.eq(a, precision));
    272     }
    273
    274     @Test
    275     public void testDistance() {
    276         // arrange
    277         final Point1S a = Point1S.of(0.0);
    278         final Point1S b = Point1S.of(PlaneAngleRadians.PI - 0.5);
    279         final Point1S c = Point1S.of(PlaneAngleRadians.PI);
    280         final Point1S d = Point1S.of(PlaneAngleRadians.PI + 0.5);
    281         final Point1S e = Point1S.of(4.0);
    282
    283         // act/assert
    284         Assert.assertEquals(0.0, a.distance(a), TEST_EPS);
    285         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.distance(b), TEST_EPS);
    286         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, b.distance(a), TEST_EPS);
    287
    288         Assert.assertEquals(PlaneAngleRadians.PI, a.distance(c), TEST_EPS);
    289         Assert.assertEquals(PlaneAngleRadians.PI, c.distance(a), TEST_EPS);
    290
    291         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.distance(d), TEST_EPS);
    292         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, d.distance(a), TEST_EPS);
    293
    294         Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, a.distance(e), TEST_EPS);
    295         Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, e.distance(a), TEST_EPS);
    296     }
    297
    298     @Test
    299     public void testSignedDistance() {
    300         // arrange
    301         final Point1S a = Point1S.of(0.0);
    302         final Point1S b = Point1S.of(PlaneAngleRadians.PI - 0.5);
    303         final Point1S c = Point1S.of(PlaneAngleRadians.PI);
    304         final Point1S d = Point1S.of(PlaneAngleRadians.PI + 0.5);
    305         final Point1S e = Point1S.of(4.0);
    306
    307         // act/assert
    308         Assert.assertEquals(0.0, a.signedDistance(a), TEST_EPS);
    309         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.signedDistance(b), TEST_EPS);
    310         Assert.assertEquals(-PlaneAngleRadians.PI + 0.5, b.signedDistance(a), TEST_EPS);
    311
    312         Assert.assertEquals(-PlaneAngleRadians.PI, a.signedDistance(c), TEST_EPS);
    313         Assert.assertEquals(-PlaneAngleRadians.PI, c.signedDistance(a), TEST_EPS);
    314
    315         Assert.assertEquals(-PlaneAngleRadians.PI + 0.5, a.signedDistance(d), TEST_EPS);
    316         Assert.assertEquals(PlaneAngleRadians.PI - 0.5, d.signedDistance(a), TEST_EPS);
    317
    318         Assert.assertEquals(-PlaneAngleRadians.TWO_PI + 4, a.signedDistance(e), TEST_EPS);
    319         Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, e.signedDistance(a), TEST_EPS);
    320     }
    321
    322     @Test
    323     public void testDistance_inRangeZeroToPi() {
    324         for (double a = -4 * PlaneAngleRadians.PI; a < 4 * PlaneAngleRadians.PI; a += 0.1) {
    325             for (double b = -4 * PlaneAngleRadians.PI; b < 4 * PlaneAngleRadians.PI; b += 0.1) {
    326                 // arrange
    327                 final Point1S p1 = Point1S.of(a);
    328                 final Point1S p2 = Point1S.of(b);
    329
    330                 // act/assert
    331                 final double d1 = p1.distance(p2);
    332                 Assert.assertTrue(d1 >= 0 && d1 <= PlaneAngleRadians.PI);
    333
    334                 final double d2 = p2.distance(p1);
    335                 Assert.assertTrue(d2 >= 0 && d2 <= PlaneAngleRadians.PI);
    336             }
    337         }
    338     }
    339
    340     @Test
    341     public void testNormalize() {
    342         for (double az = -PlaneAngleRadians.TWO_PI; az < 2 * PlaneAngleRadians.TWO_PI; az += 0.2) {
    343             // arrange
    344             final Point1S pt = Point1S.of(az);
    345
    346             final double expectedPiNorm = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(az);
    347             final double expectedZeroNorm = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(az);
    348
    349             // act
    350             final Point1S piNorm = pt.normalize(Point1S.PI);
    351             final Point1S zeroNorm = pt.normalize(0.0);
    352
    353             // assert
    354             Assert.assertEquals(expectedPiNorm, piNorm.getAzimuth(), TEST_EPS);
    355             Assert.assertEquals(pt.getNormalizedAzimuth(), piNorm.getNormalizedAzimuth(), TEST_EPS);
    356
    357             Assert.assertEquals(expectedZeroNorm, zeroNorm.getAzimuth(), TEST_EPS);
    358             Assert.assertEquals(pt.getNormalizedAzimuth(), zeroNorm.getNormalizedAzimuth(), TEST_EPS);
    359         }
    360     }
    361
    362     @Test
    363     public void testNormalize_nonFinite() {
    364         // act/assert
    365         GeometryTestUtils.assertThrows(() -> {
    366             Point1S.of(Double.POSITIVE_INFINITY).normalize(0.0);
    367         }, IllegalArgumentException.class);
    368
    369         GeometryTestUtils.assertThrows(() -> {
    370             Point1S.of(Double.NEGATIVE_INFINITY).normalize(0.0);
    371         }, IllegalArgumentException.class);
    372
    373         GeometryTestUtils.assertThrows(() -> {
    374             Point1S.of(Double.NaN).normalize(Point1S.ZERO);
    375         }, IllegalArgumentException.class);
    376     }
    377
    378     @Test
    379     public void testAbove() {
    380         // arrange
    381         final Point1S p1 = Point1S.ZERO;
    382         final Point1S p2 = Point1S.of(PlaneAngle.ofDegrees(90));
    383         final Point1S p3 = Point1S.PI;
    384         final Point1S p4 = Point1S.of(PlaneAngle.ofDegrees(-90));
    385         final Point1S p5 = Point1S.of(PlaneAngleRadians.TWO_PI);
    386
    387         // act/assert
    388         checkPoint(p1.above(p1), 0);
    389         checkPoint(p2.above(p1), PlaneAngleRadians.PI_OVER_TWO);
    390         checkPoint(p3.above(p1), PlaneAngleRadians.PI);
    391         checkPoint(p4.above(p1), 1.5 * PlaneAngleRadians.PI);
    392         checkPoint(p5.above(p1), 0);
    393
    394         checkPoint(p1.above(p3), PlaneAngleRadians.TWO_PI);
    395         checkPoint(p2.above(p3), 2.5 * PlaneAngleRadians.PI);
    396         checkPoint(p3.above(p3), PlaneAngleRadians.PI);
    397         checkPoint(p4.above(p3), 1.5 * PlaneAngleRadians.PI);
    398         checkPoint(p5.above(p3), PlaneAngleRadians.TWO_PI);
    399     }
    400
    401     @Test
    402     public void testAbove_nonFinite() {
    403         // act/assert
    404         GeometryTestUtils.assertThrows(() -> {
    405             Point1S.of(Double.POSITIVE_INFINITY).above(Point1S.ZERO);
    406         }, IllegalArgumentException.class);
    407
    408         GeometryTestUtils.assertThrows(() -> {
    409             Point1S.of(Double.NEGATIVE_INFINITY).above(Point1S.ZERO);
    410         }, IllegalArgumentException.class);
    411
    412         GeometryTestUtils.assertThrows(() -> {
    413             Point1S.of(Double.NaN).above(Point1S.ZERO);
    414         }, IllegalArgumentException.class);
    415     }
    416
    417     @Test
    418     public void testBelow() {
    419         // arrange
    420         final Point1S p1 = Point1S.ZERO;
    421         final Point1S p2 = Point1S.of(PlaneAngle.ofDegrees(90));
    422         final Point1S p3 = Point1S.PI;
    423         final Point1S p4 = Point1S.of(PlaneAngle.ofDegrees(-90));
    424         final Point1S p5 = Point1S.of(PlaneAngleRadians.TWO_PI);
    425
    426         // act/assert
    427         checkPoint(p1.below(p1), -PlaneAngleRadians.TWO_PI);
    428         checkPoint(p2.below(p1), -1.5 * PlaneAngleRadians.PI);
    429         checkPoint(p3.below(p1), -PlaneAngleRadians.PI);
    430         checkPoint(p4.below(p1), -PlaneAngleRadians.PI_OVER_TWO);
    431         checkPoint(p5.below(p1), -PlaneAngleRadians.TWO_PI);
    432
    433         checkPoint(p1.below(p3), 0.0);
    434         checkPoint(p2.below(p3), PlaneAngleRadians.PI_OVER_TWO);
    435         checkPoint(p3.below(p3), -PlaneAngleRadians.PI);
    436         checkPoint(p4.below(p3), -PlaneAngleRadians.PI_OVER_TWO);
    437         checkPoint(p5.below(p3), 0.0);
    438     }
    439
    440     @Test
    441     public void testBelow_nonFinite() {
    442         // act/assert
    443         GeometryTestUtils.assertThrows(() -> {
    444             Point1S.of(Double.POSITIVE_INFINITY).below(Point1S.ZERO);
    445         }, IllegalArgumentException.class);
    446
    447         GeometryTestUtils.assertThrows(() -> {
    448             Point1S.of(Double.NEGATIVE_INFINITY).below(Point1S.ZERO);
    449         }, IllegalArgumentException.class);
    450
    451         GeometryTestUtils.assertThrows(() -> {
    452             Point1S.of(Double.NaN).below(Point1S.ZERO);
    453         }, IllegalArgumentException.class);
    454     }
    455
    456     @Test
    457     public void testToString() {
    458         // act/assert
    459         Assert.assertEquals("(0.0)", Point1S.of(0.0).toString());
    460         Assert.assertEquals("(1.0)", Point1S.of(1.0).toString());
    461     }
    462
    463     @Test
    464     public void testParse() {
    465         // act/assert
    466         checkPoint(Point1S.parse("(0)"), 0.0);
    467         checkPoint(Point1S.parse("(1)"), 1.0);
    468     }
    469
    470     @Test(expected = IllegalArgumentException.class)
    471     public void testParse_failure() {
    472         // act/assert
    473         Point1S.parse("abc");
    474     }
    475
    476     private static void checkPoint(final Point1S pt, final double az) {
    477         checkPoint(pt, az, PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(az));
    478     }
    479
    480     private static void checkPoint(final Point1S pt, final double az, final double normAz) {
    481         Assert.assertEquals(az, pt.getAzimuth(), TEST_EPS);
    482         Assert.assertEquals(normAz, pt.getNormalizedAzimuth(), TEST_EPS);
    483
    484         Assert.assertEquals(1, pt.getDimension());
    485
    486         Assert.assertEquals(Double.isFinite(az), pt.isFinite());
    487         Assert.assertEquals(Double.isInfinite(az), pt.isInfinite());
    488
    489         final Vector2D vec = pt.getVector();
    490         if (pt.isFinite()) {
    491             Assert.assertEquals(1, vec.norm(), TEST_EPS);
    492             Assert.assertEquals(normAz, PolarCoordinates.fromCartesian(vec).getAzimuth(), TEST_EPS);
    493         } else {
    494             Assert.assertNull(vec);
    495         }
    496     }
    497 }