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.regex.Pattern;
    20
    21  import org.apache.commons.geometry.core.GeometryTestUtils;
    22  import org.apache.commons.numbers.angle.Angle;
    23  import org.junit.jupiter.api.Assertions;
    24  import org.junit.jupiter.api.Test;
    25
    26  class SphericalCoordinatesTest {
    27
    28      private static final double EPS = 1e-10;
    29
    30      private static final double THREE_PI_OVER_TWO = 3 * Math.PI / 2;
    31
    32      private static final double QUARTER_PI = 0.25 * Math.PI;
    33      private static final double MINUS_QUARTER_PI = -0.25 * Math.PI;
    34      private static final double THREE_QUARTER_PI = 0.75 * Math.PI;
    35      private static final double MINUS_THREE_QUARTER_PI = -0.75 * Math.PI;
    36
    37      @Test
    38      void testOf() {
    39          // act/assert
    40          checkSpherical(SphericalCoordinates.of(0, 0, 0), 0, 0, 0);
    41          checkSpherical(SphericalCoordinates.of(0.1, 0.2, 0.3), 0.1, 0.2, 0.3);
    42
    43          checkSpherical(SphericalCoordinates.of(1, Angle.PI_OVER_TWO, Math.PI),
    44                  1, Angle.PI_OVER_TWO, Math.PI);
    45          checkSpherical(SphericalCoordinates.of(1, -Angle.PI_OVER_TWO, Angle.PI_OVER_TWO),
    46                  1, THREE_PI_OVER_TWO, Angle.PI_OVER_TWO);
    47      }
    48
    49      @Test
    50      void testOf_normalizesAzimuthAngle() {
    51          // act/assert
    52          checkSpherical(SphericalCoordinates.of(2, Angle.TWO_PI, 0), 2, 0, 0);
    53          checkSpherical(SphericalCoordinates.of(2, Angle.PI_OVER_TWO + Angle.TWO_PI, 0), 2, Angle.PI_OVER_TWO, 0);
    54          checkSpherical(SphericalCoordinates.of(2, -Math.PI, 0), 2, Math.PI, 0);
    55          checkSpherical(SphericalCoordinates.of(2, THREE_PI_OVER_TWO, 0), 2, THREE_PI_OVER_TWO, 0);
    56      }
    57
    58      @Test
    59      void testOf_normalizesPolarAngle() {
    60          // act/assert
    61          checkSpherical(SphericalCoordinates.of(1, 0, 0), 1, 0, 0);
    62
    63          checkSpherical(SphericalCoordinates.of(1, 0, QUARTER_PI), 1, 0, QUARTER_PI);
    64          checkSpherical(SphericalCoordinates.of(1, 0, MINUS_QUARTER_PI), 1, 0, QUARTER_PI);
    65
    66          checkSpherical(SphericalCoordinates.of(1, 0, Angle.PI_OVER_TWO), 1, 0, Angle.PI_OVER_TWO);
    67          checkSpherical(SphericalCoordinates.of(1, 0, -Angle.PI_OVER_TWO), 1, 0, Angle.PI_OVER_TWO);
    68
    69          checkSpherical(SphericalCoordinates.of(1, 0, THREE_QUARTER_PI), 1, 0, THREE_QUARTER_PI);
    70          checkSpherical(SphericalCoordinates.of(1, 0, MINUS_THREE_QUARTER_PI), 1, 0, THREE_QUARTER_PI);
    71
    72          checkSpherical(SphericalCoordinates.of(1, 0, Angle.TWO_PI), 1, 0, 0);
    73          checkSpherical(SphericalCoordinates.of(1, 0, -Angle.TWO_PI), 1, 0, 0);
    74      }
    75
    76      @Test
    77      void testOf_angleWrapAround() {
    78          // act/assert
    79          checkOfWithAngleWrapAround(1, 0, 0);
    80          checkOfWithAngleWrapAround(1, QUARTER_PI, QUARTER_PI);
    81          checkOfWithAngleWrapAround(1, Angle.PI_OVER_TWO, Angle.PI_OVER_TWO);
    82          checkOfWithAngleWrapAround(1, THREE_QUARTER_PI, THREE_QUARTER_PI);
    83          checkOfWithAngleWrapAround(1, Math.PI, Math.PI);
    84      }
    85
    86      private void checkOfWithAngleWrapAround(final double radius, final double azimuth, final double polar) {
    87          for (int i = -4; i <= 4; ++i) {
    88              checkSpherical(
    89                      SphericalCoordinates.of(radius, azimuth + (i * Angle.TWO_PI), polar + (-i * Angle.TWO_PI)),
    90                      radius, azimuth, polar);
    91          }
    92      }
    93
    94      @Test
    95      void testOf_negativeRadius() {
    96          // act/assert
    97          checkSpherical(SphericalCoordinates.of(-2, 0, 0), 2, Math.PI, Math.PI);
    98          checkSpherical(SphericalCoordinates.of(-2, Math.PI, Math.PI), 2, 0, 0);
    99
    100         checkSpherical(SphericalCoordinates.of(-3, Angle.PI_OVER_TWO, QUARTER_PI), 3, THREE_PI_OVER_TWO, THREE_QUARTER_PI);
    101         checkSpherical(SphericalCoordinates.of(-3, -Angle.PI_OVER_TWO, THREE_QUARTER_PI), 3, Angle.PI_OVER_TWO, QUARTER_PI);
    102
    103         checkSpherical(SphericalCoordinates.of(-4, QUARTER_PI, Angle.PI_OVER_TWO), 4, Math.PI + QUARTER_PI, Angle.PI_OVER_TWO);
    104         checkSpherical(SphericalCoordinates.of(-4, MINUS_THREE_QUARTER_PI, Angle.PI_OVER_TWO), 4, QUARTER_PI, Angle.PI_OVER_TWO);
    105     }
    106
    107     @Test
    108     void testOf_NaNAndInfinite() {
    109         // act/assert
    110         checkSpherical(SphericalCoordinates.of(Double.NaN, Double.NaN, Double.NaN),
    111                 Double.NaN, Double.NaN, Double.NaN);
    112         checkSpherical(SphericalCoordinates.of(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY),
    113                 Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    114         checkSpherical(SphericalCoordinates.of(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
    115                 Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    116     }
    117
    118     @Test
    119     void testFromCartesian_coordinates() {
    120         // arrange
    121         final double sqrt3 = Math.sqrt(3);
    122
    123         // act/assert
    124         checkSpherical(SphericalCoordinates.fromCartesian(0, 0, 0), 0, 0, 0);
    125
    126         checkSpherical(SphericalCoordinates.fromCartesian(0.1, 0, 0), 0.1, 0, Angle.PI_OVER_TWO);
    127         checkSpherical(SphericalCoordinates.fromCartesian(-0.1, 0, 0), 0.1, Math.PI, Angle.PI_OVER_TWO);
    128
    129         checkSpherical(SphericalCoordinates.fromCartesian(0, 0.1, 0), 0.1, Angle.PI_OVER_TWO, Angle.PI_OVER_TWO);
    130         checkSpherical(SphericalCoordinates.fromCartesian(0, -0.1, 0), 0.1, THREE_PI_OVER_TWO, Angle.PI_OVER_TWO);
    131
    132         checkSpherical(SphericalCoordinates.fromCartesian(0, 0, 0.1), 0.1, 0, 0);
    133         checkSpherical(SphericalCoordinates.fromCartesian(0, 0, -0.1), 0.1, 0, Math.PI);
    134
    135         checkSpherical(SphericalCoordinates.fromCartesian(1, 1, 1), sqrt3, QUARTER_PI, Math.acos(1 / sqrt3));
    136         checkSpherical(SphericalCoordinates.fromCartesian(-1, -1, -1), sqrt3, 1.25 * Math.PI, Math.acos(-1 / sqrt3));
    137     }
    138
    139     @Test
    140     void testFromCartesian_vector() {
    141         // arrange
    142         final double sqrt3 = Math.sqrt(3);
    143
    144         // act/assert
    145         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0, 0, 0)), 0, 0, 0);
    146
    147         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0.1, 0, 0)), 0.1, 0, Angle.PI_OVER_TWO);
    148         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(-0.1, 0, 0)), 0.1, Math.PI, Angle.PI_OVER_TWO);
    149
    150         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0, 0.1, 0)), 0.1, Angle.PI_OVER_TWO, Angle.PI_OVER_TWO);
    151         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0, -0.1, 0)), 0.1, THREE_PI_OVER_TWO, Angle.PI_OVER_TWO);
    152
    153         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0, 0, 0.1)), 0.1, 0, 0);
    154         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(0, 0, -0.1)), 0.1, 0, Math.PI);
    155
    156         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(1, 1, 1)), sqrt3, QUARTER_PI, Math.acos(1 / sqrt3));
    157         checkSpherical(SphericalCoordinates.fromCartesian(Vector3D.of(-1, -1, -1)), sqrt3, 1.25 * Math.PI, Math.acos(-1 / sqrt3));
    158     }
    159
    160     @Test
    161     void testToVector() {
    162         // arrange
    163         final double sqrt3 = Math.sqrt(3);
    164
    165         // act/assert
    166         checkVector(SphericalCoordinates.of(0, 0, 0).toVector(), 0, 0, 0);
    167
    168         checkVector(SphericalCoordinates.of(1, 0, Angle.PI_OVER_TWO).toVector(), 1, 0, 0);
    169         checkVector(SphericalCoordinates.of(1, Math.PI, Angle.PI_OVER_TWO).toVector(), -1, 0, 0);
    170
    171         checkVector(SphericalCoordinates.of(2, Angle.PI_OVER_TWO, Angle.PI_OVER_TWO).toVector(), 0, 2, 0);
    172         checkVector(SphericalCoordinates.of(2, -Angle.PI_OVER_TWO, Angle.PI_OVER_TWO).toVector(), 0, -2, 0);
    173
    174         checkVector(SphericalCoordinates.of(3, 0, 0).toVector(), 0, 0, 3);
    175         checkVector(SphericalCoordinates.of(3, 0, Math.PI).toVector(), 0, 0, -3);
    176
    177         checkVector(SphericalCoordinates.of(sqrt3, QUARTER_PI, Math.acos(1 / sqrt3)).toVector(), 1, 1, 1);
    178         checkVector(SphericalCoordinates.of(sqrt3, MINUS_THREE_QUARTER_PI, Math.acos(-1 / sqrt3)).toVector(), -1, -1, -1);
    179     }
    180
    181     @Test
    182     void testToCartesian_static() {
    183         // arrange
    184         final double sqrt3 = Math.sqrt(3);
    185
    186         // act/assert
    187         checkVector(SphericalCoordinates.toCartesian(0, 0, 0), 0, 0, 0);
    188
    189         checkVector(SphericalCoordinates.toCartesian(1, 0, Angle.PI_OVER_TWO), 1, 0, 0);
    190         checkVector(SphericalCoordinates.toCartesian(1, Math.PI, Angle.PI_OVER_TWO), -1, 0, 0);
    191
    192         checkVector(SphericalCoordinates.toCartesian(2, Angle.PI_OVER_TWO, Angle.PI_OVER_TWO), 0, 2, 0);
    193         checkVector(SphericalCoordinates.toCartesian(2, -Angle.PI_OVER_TWO, Angle.PI_OVER_TWO), 0, -2, 0);
    194
    195         checkVector(SphericalCoordinates.toCartesian(3, 0, 0), 0, 0, 3);
    196         checkVector(SphericalCoordinates.toCartesian(3, 0, Math.PI), 0, 0, -3);
    197
    198         checkVector(SphericalCoordinates.toCartesian(Math.sqrt(3), QUARTER_PI, Math.acos(1 / sqrt3)), 1, 1, 1);
    199         checkVector(SphericalCoordinates.toCartesian(Math.sqrt(3), MINUS_THREE_QUARTER_PI, Math.acos(-1 / sqrt3)), -1, -1, -1);
    200     }
    201
    202     @Test
    203     void testGetDimension() {
    204         // arrange
    205         final SphericalCoordinates s = SphericalCoordinates.of(0, 0, 0);
    206
    207         // act/assert
    208         Assertions.assertEquals(3, s.getDimension());
    209     }
    210
    211     @Test
    212     void testNaN() {
    213         // act/assert
    214         Assertions.assertTrue(SphericalCoordinates.of(0, 0, Double.NaN).isNaN());
    215         Assertions.assertTrue(SphericalCoordinates.of(0, Double.NaN, 0).isNaN());
    216         Assertions.assertTrue(SphericalCoordinates.of(Double.NaN, 0, 0).isNaN());
    217
    218         Assertions.assertFalse(SphericalCoordinates.of(1, 1, 1).isNaN());
    219         Assertions.assertFalse(SphericalCoordinates.of(1, 1, Double.NEGATIVE_INFINITY).isNaN());
    220         Assertions.assertFalse(SphericalCoordinates.of(1, Double.POSITIVE_INFINITY, 1).isNaN());
    221         Assertions.assertFalse(SphericalCoordinates.of(Double.NEGATIVE_INFINITY, 1, 1).isNaN());
    222     }
    223
    224     @Test
    225     void testInfinite() {
    226         // act/assert
    227         Assertions.assertTrue(SphericalCoordinates.of(0, 0, Double.NEGATIVE_INFINITY).isInfinite());
    228         Assertions.assertTrue(SphericalCoordinates.of(0, Double.NEGATIVE_INFINITY, 0).isInfinite());
    229         Assertions.assertTrue(SphericalCoordinates.of(Double.NEGATIVE_INFINITY, 0, 0).isInfinite());
    230         Assertions.assertTrue(SphericalCoordinates.of(0, 0, Double.POSITIVE_INFINITY).isInfinite());
    231         Assertions.assertTrue(SphericalCoordinates.of(0, Double.POSITIVE_INFINITY, 0).isInfinite());
    232         Assertions.assertTrue(SphericalCoordinates.of(Double.POSITIVE_INFINITY, 0, 0).isInfinite());
    233
    234         Assertions.assertFalse(SphericalCoordinates.of(1, 1, 1).isInfinite());
    235         Assertions.assertFalse(SphericalCoordinates.of(0, 0, Double.NaN).isInfinite());
    236         Assertions.assertFalse(SphericalCoordinates.of(0, Double.NEGATIVE_INFINITY, Double.NaN).isInfinite());
    237         Assertions.assertFalse(SphericalCoordinates.of(Double.NaN, 0, Double.NEGATIVE_INFINITY).isInfinite());
    238         Assertions.assertFalse(SphericalCoordinates.of(Double.POSITIVE_INFINITY, Double.NaN, 0).isInfinite());
    239         Assertions.assertFalse(SphericalCoordinates.of(0, Double.NaN, Double.POSITIVE_INFINITY).isInfinite());
    240     }
    241
    242     @Test
    243     void testFinite() {
    244         // act/assert
    245         Assertions.assertTrue(SphericalCoordinates.of(1, 1, 1).isFinite());
    246
    247         Assertions.assertFalse(SphericalCoordinates.of(0, 0, Double.NEGATIVE_INFINITY).isFinite());
    248         Assertions.assertFalse(SphericalCoordinates.of(0, Double.NEGATIVE_INFINITY, 0).isFinite());
    249         Assertions.assertFalse(SphericalCoordinates.of(Double.NEGATIVE_INFINITY, 0, 0).isFinite());
    250         Assertions.assertFalse(SphericalCoordinates.of(0, 0, Double.POSITIVE_INFINITY).isFinite());
    251         Assertions.assertFalse(SphericalCoordinates.of(0, Double.POSITIVE_INFINITY, 0).isFinite());
    252         Assertions.assertFalse(SphericalCoordinates.of(Double.POSITIVE_INFINITY, 0, 0).isFinite());
    253
    254         Assertions.assertFalse(SphericalCoordinates.of(0, 0, Double.NaN).isFinite());
    255         Assertions.assertFalse(SphericalCoordinates.of(0, Double.NEGATIVE_INFINITY, Double.NaN).isFinite());
    256         Assertions.assertFalse(SphericalCoordinates.of(Double.NaN, 0, Double.NEGATIVE_INFINITY).isFinite());
    257         Assertions.assertFalse(SphericalCoordinates.of(Double.POSITIVE_INFINITY, Double.NaN, 0).isFinite());
    258         Assertions.assertFalse(SphericalCoordinates.of(0, Double.NaN, Double.POSITIVE_INFINITY).isFinite());
    259     }
    260
    261     @Test
    262     void testHashCode() {
    263         // arrange
    264         final SphericalCoordinates a = SphericalCoordinates.of(1, 2, 3);
    265         final SphericalCoordinates b = SphericalCoordinates.of(10, 2, 3);
    266         final SphericalCoordinates c = SphericalCoordinates.of(1, 20, 3);
    267         final SphericalCoordinates d = SphericalCoordinates.of(1, 2, 30);
    268
    269         final SphericalCoordinates e = SphericalCoordinates.of(1, 2, 3);
    270
    271         // act/assert
    272         Assertions.assertEquals(a.hashCode(), a.hashCode());
    273         Assertions.assertEquals(a.hashCode(), e.hashCode());
    274
    275         Assertions.assertNotEquals(a.hashCode(), b.hashCode());
    276         Assertions.assertNotEquals(a.hashCode(), c.hashCode());
    277         Assertions.assertNotEquals(a.hashCode(), d.hashCode());
    278     }
    279
    280     @Test
    281     void testHashCode_NaNInstancesHaveSameHashCode() {
    282         // arrange
    283         final SphericalCoordinates a = SphericalCoordinates.of(1, 2, Double.NaN);
    284         final SphericalCoordinates b = SphericalCoordinates.of(1, Double.NaN, 3);
    285         final SphericalCoordinates c = SphericalCoordinates.of(Double.NaN, 2, 3);
    286
    287         // act/assert
    288         Assertions.assertEquals(a.hashCode(), b.hashCode());
    289         Assertions.assertEquals(b.hashCode(), c.hashCode());
    290     }
    291
    292     @Test
    293     void testEquals() {
    294         // arrange
    295         final SphericalCoordinates a = SphericalCoordinates.of(1, 2, 3);
    296         final SphericalCoordinates b = SphericalCoordinates.of(10, 2, 3);
    297         final SphericalCoordinates c = SphericalCoordinates.of(1, 20, 3);
    298         final SphericalCoordinates d = SphericalCoordinates.of(1, 2, 30);
    299
    300         final SphericalCoordinates e = SphericalCoordinates.of(1, 2, 3);
    301
    302         // act/assert
    303         GeometryTestUtils.assertSimpleEqualsCases(a);
    304         Assertions.assertEquals(a, e);
    305
    306         Assertions.assertNotEquals(a, b);
    307         Assertions.assertNotEquals(a, c);
    308         Assertions.assertNotEquals(a, d);
    309     }
    310
    311     @Test
    312     void testEquals_NaNInstancesEqual() {
    313         // arrange
    314         final SphericalCoordinates a = SphericalCoordinates.of(1, 2, Double.NaN);
    315         final SphericalCoordinates b = SphericalCoordinates.of(1, Double.NaN, 3);
    316         final SphericalCoordinates c = SphericalCoordinates.of(Double.NaN, 2, 3);
    317
    318         // act/assert
    319         Assertions.assertEquals(a, b);
    320         Assertions.assertEquals(b, c);
    321     }
    322
    323     @Test
    324     void testEqualsAndHashCode_signedZeroConsistency() {
    325         // arrange
    326         final SphericalCoordinates a = SphericalCoordinates.of(0.0, -0.0, 0.0);
    327         final SphericalCoordinates b = SphericalCoordinates.of(-0.0, 0.0, -0.0);
    328         final SphericalCoordinates c = SphericalCoordinates.of(0.0, -0.0, 0.0);
    329         final SphericalCoordinates d = SphericalCoordinates.of(-0.0, 0.0, -0.0);
    330
    331         // act/assert
    332         Assertions.assertFalse(a.equals(b));
    333         Assertions.assertNotEquals(a.hashCode(), b.hashCode());
    334
    335         Assertions.assertTrue(a.equals(c));
    336         Assertions.assertEquals(a.hashCode(), c.hashCode());
    337
    338         Assertions.assertTrue(b.equals(d));
    339         Assertions.assertEquals(b.hashCode(), d.hashCode());
    340     }
    341
    342     @Test
    343     void testToString() {
    344         // arrange
    345         final SphericalCoordinates sph = SphericalCoordinates.of(1, 2, 3);
    346         final Pattern pattern = Pattern.compile("\\(1.{0,2}, 2.{0,2}, 3.{0,2}\\)");
    347
    348         // act
    349         final String str = sph.toString();
    350
    351         // assert
    352         Assertions.assertTrue(pattern.matcher(str).matches(), "Expected string " + str + " to match regex " + pattern);
    353     }
    354
    355     @Test
    356     void testParse() {
    357         // act/assert
    358         checkSpherical(SphericalCoordinates.parse("(1, 2, 3)"), 1, 2, 3);
    359         checkSpherical(SphericalCoordinates.parse("(  -2.0 , 1 , -5e-1)"), 2, 1 + Math.PI, Math.PI - 0.5);
    360         checkSpherical(SphericalCoordinates.parse("(NaN,Infinity,-Infinity)"), Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
    361     }
    362
    363     @Test
    364     void testParse_failure() {
    365         // act/assert
    366         Assertions.assertThrows(IllegalArgumentException.class, () -> SphericalCoordinates.parse("abc"));
    367     }
    368
    369     @Test
    370     void testNormalizeAzimuth() {
    371         // act/assert
    372         Assertions.assertEquals(0.0, SphericalCoordinates.normalizeAzimuth(0), EPS);
    373
    374         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizeAzimuth(Angle.PI_OVER_TWO), EPS);
    375         Assertions.assertEquals(Math.PI, SphericalCoordinates.normalizeAzimuth(Math.PI), EPS);
    376         Assertions.assertEquals(THREE_PI_OVER_TWO, SphericalCoordinates.normalizeAzimuth(THREE_PI_OVER_TWO), EPS);
    377         Assertions.assertEquals(0.0, SphericalCoordinates.normalizeAzimuth(Angle.TWO_PI), EPS);
    378
    379         Assertions.assertEquals(THREE_PI_OVER_TWO, SphericalCoordinates.normalizeAzimuth(-Angle.PI_OVER_TWO), EPS);
    380         Assertions.assertEquals(Math.PI, SphericalCoordinates.normalizeAzimuth(-Math.PI), EPS);
    381         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizeAzimuth(-Math.PI - Angle.PI_OVER_TWO), EPS);
    382         Assertions.assertEquals(0.0, SphericalCoordinates.normalizeAzimuth(-Angle.TWO_PI), EPS);
    383     }
    384
    385     @Test
    386     void testNormalizeAzimuth_NaNAndInfinite() {
    387         // act/assert
    388         Assertions.assertEquals(Double.NaN, SphericalCoordinates.normalizeAzimuth(Double.NaN), EPS);
    389         Assertions.assertEquals(Double.NEGATIVE_INFINITY, SphericalCoordinates.normalizeAzimuth(Double.NEGATIVE_INFINITY), EPS);
    390         Assertions.assertEquals(Double.POSITIVE_INFINITY, SphericalCoordinates.normalizeAzimuth(Double.POSITIVE_INFINITY), EPS);
    391     }
    392
    393     @Test
    394     void testNormalizePolar() {
    395         // act/assert
    396         Assertions.assertEquals(0.0, SphericalCoordinates.normalizePolar(0), EPS);
    397
    398         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizePolar(Angle.PI_OVER_TWO), EPS);
    399         Assertions.assertEquals(Math.PI, SphericalCoordinates.normalizePolar(Math.PI), EPS);
    400         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizePolar(Math.PI + Angle.PI_OVER_TWO), EPS);
    401         Assertions.assertEquals(0.0, SphericalCoordinates.normalizePolar(Angle.TWO_PI), EPS);
    402
    403         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizePolar(-Angle.PI_OVER_TWO), EPS);
    404         Assertions.assertEquals(Math.PI, SphericalCoordinates.normalizePolar(-Math.PI), EPS);
    405         Assertions.assertEquals(Angle.PI_OVER_TWO, SphericalCoordinates.normalizePolar(-Math.PI - Angle.PI_OVER_TWO), EPS);
    406         Assertions.assertEquals(0.0, SphericalCoordinates.normalizePolar(-Angle.TWO_PI), EPS);
    407     }
    408
    409     @Test
    410     void testNormalizePolar_NaNAndInfinite() {
    411         // act/assert
    412         Assertions.assertEquals(Double.NaN, SphericalCoordinates.normalizePolar(Double.NaN), EPS);
    413         Assertions.assertEquals(Double.NEGATIVE_INFINITY, SphericalCoordinates.normalizePolar(Double.NEGATIVE_INFINITY), EPS);
    414         Assertions.assertEquals(Double.POSITIVE_INFINITY, SphericalCoordinates.normalizePolar(Double.POSITIVE_INFINITY), EPS);
    415     }
    416
    417     private void checkSpherical(final SphericalCoordinates c, final double radius, final double azimuth, final double polar) {
    418         Assertions.assertEquals(radius, c.getRadius(), EPS);
    419         Assertions.assertEquals(azimuth, c.getAzimuth(), EPS);
    420         Assertions.assertEquals(polar, c.getPolar(), EPS);
    421     }
    422
    423     private void checkVector(final Vector3D v, final double x, final double y, final double z) {
    424         Assertions.assertEquals(x, v.getX(), EPS);
    425         Assertions.assertEquals(y, v.getY(), EPS);
    426         Assertions.assertEquals(z, v.getZ(), EPS);
    427     }
    428 }