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.line;
    18
    19  import org.apache.commons.geometry.core.GeometryTestUtils;
    20  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    21  import org.apache.commons.geometry.euclidean.oned.Interval;
    22  import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
    23  import org.apache.commons.geometry.euclidean.threed.Vector3D;
    24  import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
    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 ReverseRay3DTest {
    30
    31      private static final double TEST_EPS = 1e-10;
    32
    33      private static final Precision.DoubleEquivalence TEST_PRECISION =
    34              Precision.doubleEquivalenceOfEpsilon(TEST_EPS);
    35
    36      @Test
    37      void testFromPointAndDirection() {
    38          // arrange
    39          final Vector3D pt = Vector3D.of(1, 1, 2);
    40
    41          // act
    42          final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(pt, Vector3D.Unit.PLUS_Z, TEST_PRECISION);
    43
    44          // assert
    45          Assertions.assertTrue(revRay.isInfinite());
    46          Assertions.assertFalse(revRay.isFinite());
    47
    48          Assertions.assertNull(revRay.getStartPoint());
    49          EuclideanTestUtils.assertCoordinatesEqual(pt, revRay.getEndPoint(), TEST_EPS);
    50
    51          EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Z, revRay.getLine().getDirection(), TEST_EPS);
    52
    53          GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
    54          Assertions.assertEquals(2, revRay.getSubspaceEnd(), TEST_EPS);
    55
    56          GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
    57
    58          Assertions.assertNull(revRay.getCentroid());
    59          Assertions.assertNull(revRay.getBounds());
    60      }
    61
    62      @Test
    63      void testFromPointAndDirection_invalidArgs() {
    64          // arrange
    65          final Vector3D pt = Vector3D.of(0, 2, 4);
    66          final Vector3D dir = Vector3D.of(1e-11, 0, 0);
    67
    68          // act/assert
    69          GeometryTestUtils.assertThrowsWithMessage(() -> {
    70              Lines3D.reverseRayFromPointAndDirection(pt, dir, TEST_PRECISION);
    71          }, IllegalArgumentException.class, "Line direction cannot be zero");
    72      }
    73
    74      @Test
    75      void testFromPoint() {
    76          // arrange
    77          final Vector3D pt = Vector3D.of(-2, -1, 2);
    78
    79          final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(1, 0, 2), Vector3D.Unit.PLUS_Y, TEST_PRECISION);
    80
    81          // act
    82          final ReverseRay3D revRay = Lines3D.reverseRayFromPoint(line, pt);
    83
    84          // assert
    85          Assertions.assertTrue(revRay.isInfinite());
    86          Assertions.assertFalse(revRay.isFinite());
    87
    88          Assertions.assertNull(revRay.getStartPoint());
    89          EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, -1, 2), revRay.getEndPoint(), TEST_EPS);
    90
    91          GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
    92          Assertions.assertEquals(-1, revRay.getSubspaceEnd(), TEST_EPS);
    93
    94          GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
    95
    96          Assertions.assertNull(revRay.getCentroid());
    97          Assertions.assertNull(revRay.getBounds());
    98      }
    99
    100     @Test
    101     void testFromPoint_invalidArgs() {
    102         // arrange
    103         final Line3D line = Lines3D.fromPointAndDirection(Vector3D.ZERO, Vector3D.Unit.PLUS_X, TEST_PRECISION);
    104
    105         // act/assert
    106         GeometryTestUtils.assertThrowsWithMessage(() -> {
    107             Lines3D.reverseRayFromPoint(line, Vector3D.NaN);
    108         }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
    109
    110         GeometryTestUtils.assertThrowsWithMessage(() -> {
    111             Lines3D.reverseRayFromPoint(line, Vector3D.NEGATIVE_INFINITY);
    112         }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
    113
    114         GeometryTestUtils.assertThrowsWithMessage(() -> {
    115             Lines3D.reverseRayFromPoint(line, Vector3D.POSITIVE_INFINITY);
    116         }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
    117     }
    118
    119     @Test
    120     void testFromLocation() {
    121         // arrange
    122         final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(-1, 0, 0), Vector3D.Unit.PLUS_Z, TEST_PRECISION);
    123
    124         // act
    125         final ReverseRay3D revRay = Lines3D.reverseRayFromLocation(line, -1);
    126
    127         // assert
    128         Assertions.assertTrue(revRay.isInfinite());
    129         Assertions.assertFalse(revRay.isFinite());
    130
    131         Assertions.assertNull(revRay.getStartPoint());
    132         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-1, 0, -1), revRay.getEndPoint(), TEST_EPS);
    133
    134         GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
    135         Assertions.assertEquals(-1, revRay.getSubspaceEnd(), TEST_EPS);
    136
    137         GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
    138
    139         Assertions.assertNull(revRay.getCentroid());
    140         Assertions.assertNull(revRay.getBounds());
    141     }
    142
    143     @Test
    144     void testTransform() {
    145         // arrange
    146         final AffineTransformMatrix3D t = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, 0.5 * Math.PI)
    147                 .toMatrix()
    148                 .translate(Vector3D.Unit.PLUS_Y);
    149
    150         final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 0, 0), Vector3D.Unit.PLUS_X, TEST_PRECISION);
    151
    152         // act
    153         final ReverseRay3D result = revRay.transform(t);
    154
    155         // assert
    156         Assertions.assertNull(result.getStartPoint());
    157         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -1), result.getEndPoint(), TEST_EPS);
    158
    159         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_Z, result.getLine().getDirection(), TEST_EPS);
    160     }
    161
    162     @Test
    163     void testTransform_reflection() {
    164         // arrange
    165         final AffineTransformMatrix3D t = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, 0.5 * Math.PI)
    166                 .toMatrix()
    167                 .translate(Vector3D.Unit.PLUS_Y)
    168                 .scale(1, 1, -2);
    169
    170         final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 0, 0), Vector3D.Unit.PLUS_X, TEST_PRECISION);
    171
    172         // act
    173         final ReverseRay3D result = revRay.transform(t);
    174
    175         // assert
    176         Assertions.assertNull(result.getStartPoint());
    177         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, 2), result.getEndPoint(), TEST_EPS);
    178
    179         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Z, result.getLine().getDirection(), TEST_EPS);
    180     }
    181
    182     @Test
    183     void testContains() {
    184         // arrange
    185         final Vector3D p0 = Vector3D.of(1, 1, 1);
    186
    187         final Vector3D delta = Vector3D.of(1e-12, 1e-12, 1e-12);
    188
    189         final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 1, 1), Vector3D.Unit.PLUS_X, TEST_PRECISION);
    190
    191         // act/assert
    192         Assertions.assertFalse(revRay.contains(Vector3D.of(2, 2, 2)));
    193         Assertions.assertFalse(revRay.contains(Vector3D.of(1.1, 1, 1)));
    194         Assertions.assertFalse(revRay.contains(Vector3D.of(100, 1, 1)));
    195
    196         Assertions.assertTrue(revRay.contains(p0));
    197         Assertions.assertTrue(revRay.contains(p0.add(delta)));
    198
    199         Assertions.assertTrue(revRay.contains(Vector3D.of(-1000, 1, 1)));
    200     }
    201
    202     @Test
    203     void testGetInterval() {
    204         // arrange
    205         final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(2, -1, 3), Vector3D.Unit.PLUS_Y, TEST_PRECISION);
    206
    207         // act
    208         final Interval interval = revRay.getInterval();
    209
    210         // assert
    211         GeometryTestUtils.assertNegativeInfinity(interval.getMin());
    212         Assertions.assertEquals(-1, interval.getMax(), TEST_EPS);
    213
    214         Assertions.assertSame(revRay.getLine().getPrecision(), interval.getMaxBoundary().getPrecision());
    215     }
    216
    217     @Test
    218     void testToString() {
    219         // arrange
    220         final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.ZERO, Vector3D.Unit.PLUS_X, TEST_PRECISION);
    221
    222         // act
    223         final String str = revRay.toString();
    224
    225         // assert
    226         GeometryTestUtils.assertContains("ReverseRay3D[direction= (1", str);
    227         GeometryTestUtils.assertContains(", endPoint= (0", str);
    228     }
    229 }