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