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.twod;
    18
    19
    20  import java.util.Comparator;
    21
    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.threed.Vector3D;
    25  import org.apache.commons.geometry.spherical.SphericalTestUtils;
    26  import org.apache.commons.numbers.angle.PlaneAngleRadians;
    27  import org.junit.Assert;
    28  import org.junit.Test;
    29
    30  public class Point2STest {
    31
    32      private static final double TEST_EPS = 1e-10;
    33
    34      @Test
    35      public void testProperties() {
    36          for (int k = -2; k < 3; ++k) {
    37              // arrange
    38              final Point2S p = Point2S.of(1.0 + k * PlaneAngleRadians.TWO_PI, 1.4);
    39
    40              // act/assert
    41              Assert.assertEquals(1.0, p.getAzimuth(), TEST_EPS);
    42              Assert.assertEquals(1.4, p.getPolar(), TEST_EPS);
    43
    44              Assert.assertEquals(Math.cos(1.0) * Math.sin(1.4), p.getVector().getX(), TEST_EPS);
    45              Assert.assertEquals(Math.sin(1.0) * Math.sin(1.4), p.getVector().getY(), TEST_EPS);
    46              Assert.assertEquals(Math.cos(1.4), p.getVector().getZ(), TEST_EPS);
    47
    48              Assert.assertFalse(p.isNaN());
    49          }
    50      }
    51
    52      @Test
    53      public void testAzimuthPolarComparator() {
    54          // arrange
    55          final Comparator<Point2S> comp = Point2S.POLAR_AZIMUTH_ASCENDING_ORDER;
    56
    57          // act/assert
    58          Assert.assertEquals(0, comp.compare(Point2S.of(1, 2), Point2S.of(1, 2)));
    59          Assert.assertEquals(1, comp.compare(Point2S.of(1, 2), Point2S.of(2, 1)));
    60          Assert.assertEquals(-1, comp.compare(Point2S.of(2, 1), Point2S.of(1, 2)));
    61
    62          Assert.assertEquals(-1, comp.compare(Point2S.of(1, 2), Point2S.of(1, 3)));
    63          Assert.assertEquals(1, comp.compare(Point2S.of(1, 3), Point2S.of(1, 2)));
    64
    65          Assert.assertEquals(1, comp.compare(null, Point2S.of(1, 2)));
    66          Assert.assertEquals(-1, comp.compare(Point2S.of(1, 2), null));
    67          Assert.assertEquals(0, comp.compare(null, null));
    68      }
    69
    70      @Test
    71      public void testFrom_vector() {
    72          // arrange
    73          final double quarterPi = 0.25 * PlaneAngleRadians.PI;
    74
    75          // act/assert
    76          checkPoint(Point2S.from(Vector3D.of(1, 1, 0)), quarterPi, PlaneAngleRadians.PI_OVER_TWO);
    77          checkPoint(Point2S.from(Vector3D.of(1, 0, 1)), 0, quarterPi);
    78          checkPoint(Point2S.from(Vector3D.of(0, 1, 1)), PlaneAngleRadians.PI_OVER_TWO, quarterPi);
    79
    80          checkPoint(Point2S.from(Vector3D.of(1, -1, 0)), PlaneAngleRadians.TWO_PI - quarterPi, PlaneAngleRadians.PI_OVER_TWO);
    81          checkPoint(Point2S.from(Vector3D.of(-1, 0, -1)), PlaneAngleRadians.PI, PlaneAngleRadians.PI - quarterPi);
    82          checkPoint(Point2S.from(Vector3D.of(0, -1, -1)), PlaneAngleRadians.TWO_PI - PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI - quarterPi);
    83      }
    84
    85      @Test
    86      public void testNaN() {
    87          // act/assert
    88          Assert.assertTrue(Point2S.NaN.isNaN());
    89          Assert.assertEquals(Point2S.NaN, Point2S.of(Double.NaN, 1.0));
    90          Assert.assertNotEquals(Point2S.of(1.0, 1.3), Point2S.NaN);
    91          Assert.assertNull(Point2S.NaN.getVector());
    92
    93          Assert.assertEquals(Point2S.NaN.hashCode(), Point2S.of(Double.NaN, Double.NaN).hashCode());
    94      }
    95
    96      @Test
    97      public void testInfinite() {
    98          // act/assert
    99          Assert.assertTrue(Point2S.of(0, Double.POSITIVE_INFINITY).isInfinite());
    100         Assert.assertTrue(Point2S.of(Double.POSITIVE_INFINITY, 0).isInfinite());
    101
    102         Assert.assertTrue(Point2S.of(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY).isInfinite());
    103
    104         Assert.assertFalse(Point2S.of(0, 0).isInfinite());
    105         Assert.assertFalse(Point2S.of(1, 1).isInfinite());
    106         Assert.assertFalse(Point2S.NaN.isInfinite());
    107     }
    108
    109     @Test
    110     public void testFinite() {
    111         // act/assert
    112         Assert.assertTrue(Point2S.of(0, 0).isFinite());
    113         Assert.assertTrue(Point2S.of(1, 1).isFinite());
    114
    115         Assert.assertFalse(Point2S.of(0, Double.POSITIVE_INFINITY).isFinite());
    116         Assert.assertFalse(Point2S.of(Double.POSITIVE_INFINITY, 0).isFinite());
    117         Assert.assertFalse(Point2S.of(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY).isFinite());
    118
    119         Assert.assertFalse(Point2S.NaN.isFinite());
    120     }
    121
    122     @Test
    123     public void testDistance() {
    124         // arrange
    125         final Point2S a = Point2S.of(1.0, 0.5 * PlaneAngleRadians.PI);
    126         final Point2S b = Point2S.of(a.getAzimuth() + 0.5 * PlaneAngleRadians.PI, a.getPolar());
    127
    128         // act/assert
    129         Assert.assertEquals(0.5 * PlaneAngleRadians.PI, a.distance(b), 1.0e-10);
    130         Assert.assertEquals(PlaneAngleRadians.PI, a.distance(a.antipodal()), 1.0e-10);
    131         Assert.assertEquals(0.5 * PlaneAngleRadians.PI, Point2S.MINUS_I.distance(Point2S.MINUS_K), 1.0e-10);
    132         Assert.assertEquals(0.0, Point2S.of(1.0, 0).distance(Point2S.of(2.0, 0)), 1.0e-10);
    133     }
    134
    135     @Test
    136     public void testSlerp_alongEquator() {
    137         // arrange
    138         final Point2S p1 = Point2S.PLUS_I;
    139         final Point2S p2 = Point2S.PLUS_J;
    140
    141         // act/assert
    142         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p2, 0), TEST_EPS);
    143         SphericalTestUtils.assertPointsEq(Point2S.of(0.25 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.25), TEST_EPS);
    144         SphericalTestUtils.assertPointsEq(Point2S.of(0.5 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.5), TEST_EPS);
    145         SphericalTestUtils.assertPointsEq(Point2S.of(0.75 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.75), TEST_EPS);
    146         SphericalTestUtils.assertPointsEq(p2, p1.slerp(p2, 1), TEST_EPS);
    147
    148         SphericalTestUtils.assertPointsEq(p2, p2.slerp(p1, 0), TEST_EPS);
    149         SphericalTestUtils.assertPointsEq(Point2S.of(0.75 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.25), TEST_EPS);
    150         SphericalTestUtils.assertPointsEq(Point2S.of(0.5 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.5), TEST_EPS);
    151         SphericalTestUtils.assertPointsEq(Point2S.of(0.25 * PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.75), TEST_EPS);
    152         SphericalTestUtils.assertPointsEq(p1, p2.slerp(p1, 1), TEST_EPS);
    153
    154         SphericalTestUtils.assertPointsEq(Point2S.MINUS_I, p1.slerp(p2, 2), TEST_EPS);
    155         SphericalTestUtils.assertPointsEq(Point2S.MINUS_J, p1.slerp(p2, -1), TEST_EPS);
    156     }
    157
    158     @Test
    159     public void testSlerp_alongMeridian() {
    160         // arrange
    161         final Point2S p1 = Point2S.PLUS_J;
    162         final Point2S p2 = Point2S.PLUS_K;
    163
    164         // act/assert
    165         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p2, 0), TEST_EPS);
    166         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.75 * PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.25), TEST_EPS);
    167         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.5 * PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.5), TEST_EPS);
    168         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.25 * PlaneAngleRadians.PI_OVER_TWO), p1.slerp(p2, 0.75), TEST_EPS);
    169         SphericalTestUtils.assertPointsEq(p2, p1.slerp(p2, 1), TEST_EPS);
    170
    171         SphericalTestUtils.assertPointsEq(p2, p2.slerp(p1, 0), TEST_EPS);
    172         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.25 * PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.25), TEST_EPS);
    173         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.5 * PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.5), TEST_EPS);
    174         SphericalTestUtils.assertPointsEq(Point2S.of(PlaneAngleRadians.PI_OVER_TWO, 0.75 * PlaneAngleRadians.PI_OVER_TWO), p2.slerp(p1, 0.75), TEST_EPS);
    175         SphericalTestUtils.assertPointsEq(p1, p2.slerp(p1, 1), TEST_EPS);
    176
    177         SphericalTestUtils.assertPointsEq(Point2S.MINUS_J, p1.slerp(p2, 2), TEST_EPS);
    178         SphericalTestUtils.assertPointsEq(Point2S.MINUS_K, p1.slerp(p2, -1), TEST_EPS);
    179     }
    180
    181     @Test
    182     public void testSlerp_samePoint() {
    183         // arrange
    184         final Point2S p1 = Point2S.PLUS_I;
    185
    186         // act/assert
    187         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p1, 0), TEST_EPS);
    188         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p1, 0.5), TEST_EPS);
    189         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p1, 1), TEST_EPS);
    190     }
    191
    192     @Test
    193     public void testSlerp_antipodal() {
    194         // arrange
    195         final Point2S p1 = Point2S.PLUS_I;
    196         final Point2S p2 = Point2S.MINUS_I;
    197
    198         // act/assert
    199         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p1, 0), TEST_EPS);
    200         SphericalTestUtils.assertPointsEq(p1, p1.slerp(p1, 1), TEST_EPS);
    201
    202         final Point2S pt = p1.slerp(p2, 0.5);
    203         Assert.assertEquals(p1.distance(pt), p2.distance(pt), TEST_EPS);
    204     }
    205
    206     @Test
    207     public void testAntipodal() {
    208         for (double az = -6 * PlaneAngleRadians.PI; az <= 6 * PlaneAngleRadians.PI; az += 0.1) {
    209             for (double p = 0; p <= PlaneAngleRadians.PI; p += 0.1) {
    210                 // arrange
    211                 final Point2S pt = Point2S.of(az, p);
    212
    213                 // act
    214                 final Point2S result = pt.antipodal();
    215
    216                 // assert
    217                 Assert.assertEquals(PlaneAngleRadians.PI, pt.distance(result), TEST_EPS);
    218
    219                 // check that the azimuth and polar components of the point are correct by creating a
    220                 // new point and checking the distance
    221                 Assert.assertEquals(PlaneAngleRadians.PI,
    222                         Point2S.of(result.getAzimuth(), result.getPolar()).distance(pt), TEST_EPS);
    223
    224                 // check that the vectors point in opposite directions
    225                 Assert.assertEquals(-1, pt.getVector().dot(result.getVector()), TEST_EPS);
    226             }
    227         }
    228     }
    229
    230     @Test
    231     public void testAntipodal_numericalStability() {
    232         // arrange
    233         final double eps = 1e-16;
    234         final Point2S pt = Point2S.of(1, 2);
    235
    236         // act
    237         final Point2S result = pt.antipodal().antipodal();
    238
    239         // assert
    240         Assert.assertEquals(1.0, result.getAzimuth(), eps);
    241         Assert.assertEquals(2.0, result.getPolar(), eps);
    242     }
    243
    244     @Test
    245     public void testDimension() {
    246         // arrange
    247         final Point2S pt = Point2S.of(1, 2);
    248
    249         // act/assert
    250         Assert.assertEquals(2, pt.getDimension());
    251     }
    252
    253     @Test
    254     public void testEq() {
    255         // arrange
    256         final DoublePrecisionContext smallEps = new EpsilonDoublePrecisionContext(1e-5);
    257         final DoublePrecisionContext largeEps = new EpsilonDoublePrecisionContext(5e-1);
    258
    259         final Point2S a = Point2S.of(1.0, 2.0);
    260         final Point2S b = Point2S.of(1.0, 2.01);
    261         final Point2S c = Point2S.of(1.01, 2.0);
    262         final Point2S d = Point2S.of(1.0, 2.0);
    263         final Point2S e = Point2S.of(3.0, 2.0);
    264
    265         // act/assert
    266         Assert.assertTrue(a.eq(a, smallEps));
    267         Assert.assertFalse(a.eq(b, smallEps));
    268         Assert.assertFalse(a.eq(c, smallEps));
    269         Assert.assertTrue(a.eq(d, smallEps));
    270         Assert.assertFalse(a.eq(e, smallEps));
    271
    272         Assert.assertTrue(a.eq(a, largeEps));
    273         Assert.assertTrue(a.eq(b, largeEps));
    274         Assert.assertTrue(a.eq(c, largeEps));
    275         Assert.assertTrue(a.eq(d, largeEps));
    276         Assert.assertFalse(a.eq(e, largeEps));
    277     }
    278
    279     @Test
    280     public void testHashCode() {
    281         // arrange
    282         final Point2S a = Point2S.of(1.0, 2.0);
    283         final Point2S b = Point2S.of(1.0, 3.0);
    284         final Point2S c = Point2S.of(4.0, 2.0);
    285         final Point2S d = Point2S.of(1.0, 2.0);
    286
    287         // act
    288         final int hash = a.hashCode();
    289
    290         // assert
    291         Assert.assertEquals(hash, a.hashCode());
    292
    293         Assert.assertNotEquals(hash, b.hashCode());
    294         Assert.assertNotEquals(hash, c.hashCode());
    295
    296         Assert.assertEquals(hash, d.hashCode());
    297     }
    298
    299     @Test
    300     public void testEquals() {
    301         // arrange
    302         final Point2S a = Point2S.of(1.0, 2.0);
    303         final Point2S b = Point2S.of(1.0, 3.0);
    304         final Point2S c = Point2S.of(4.0, 2.0);
    305         final Point2S d = Point2S.of(1.0, 2.0);
    306
    307         // act/assert
    308         Assert.assertFalse(a.equals(null));
    309         Assert.assertFalse(a.equals(new Object()));
    310
    311         Assert.assertEquals(a, a);
    312
    313         Assert.assertNotEquals(a, b);
    314         Assert.assertNotEquals(a, c);
    315
    316         Assert.assertEquals(a, d);
    317         Assert.assertEquals(d, a);
    318     }
    319
    320     @Test
    321     public void testEquals_poles() {
    322         // arrange
    323         final Point2S a = Point2S.of(1.0, 0.0);
    324         final Point2S b = Point2S.of(0.0, 0.0);
    325         final Point2S c = Point2S.of(1.0, 0.0);
    326
    327         final Point2S d = Point2S.of(-1.0, PlaneAngleRadians.PI);
    328         final Point2S e = Point2S.of(0.0, PlaneAngleRadians.PI);
    329         final Point2S f = Point2S.of(-1.0, PlaneAngleRadians.PI);
    330
    331         // act/assert
    332         Assert.assertEquals(a, a);
    333         Assert.assertNotEquals(a, b);
    334         Assert.assertEquals(a, c);
    335
    336         Assert.assertEquals(d, d);
    337         Assert.assertNotEquals(d, e);
    338         Assert.assertEquals(d, f);
    339     }
    340
    341     @Test
    342     public void testToString() {
    343         // act/assert
    344         Assert.assertEquals("(0.0, 0.0)", Point2S.of(0.0, 0.0).toString());
    345         Assert.assertEquals("(1.0, 2.0)", Point2S.of(1.0, 2.0).toString());
    346     }
    347
    348     @Test
    349     public void testParse() {
    350         // act/assert
    351         checkPoint(Point2S.parse("(0,0)"), 0.0, 0.0);
    352         checkPoint(Point2S.parse("(1,2)"), 1.0, 2.0);
    353     }
    354
    355     @Test(expected = IllegalArgumentException.class)
    356     public void testParse_failure() {
    357         // act/assert
    358         Point2S.parse("abc");
    359     }
    360
    361     private static void checkPoint(final Point2S p, final double az, final double polar) {
    362         final String msg = "Expected (" + az + "," + polar + ") but was " + p;
    363
    364         Assert.assertEquals(msg, az, p.getAzimuth(), TEST_EPS);
    365         Assert.assertEquals(msg, polar, p.getPolar(), TEST_EPS);
    366     }
    367 }