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