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 java.util.List;
    20
    21  import org.apache.commons.geometry.core.GeometryTestUtils;
    22  import org.apache.commons.geometry.core.Transform;
    23  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    24  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
    25  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    26  import org.apache.commons.geometry.euclidean.oned.Interval;
    27  import org.apache.commons.geometry.euclidean.oned.RegionBSPTree1D;
    28  import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
    29  import org.apache.commons.geometry.euclidean.threed.Bounds3D;
    30  import org.apache.commons.geometry.euclidean.threed.Vector3D;
    31  import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
    32  import org.apache.commons.numbers.angle.PlaneAngleRadians;
    33  import org.junit.Assert;
    34  import org.junit.Test;
    35
    36  public class EmbeddedTreeLineSubset3DTest {
    37
    38      private static final double TEST_EPS = 1e-10;
    39
    40      private static final DoublePrecisionContext TEST_PRECISION =
    41              new EpsilonDoublePrecisionContext(TEST_EPS);
    42
    43      private final Line3D testLine = Lines3D.fromPointAndDirection(Vector3D.ZERO, Vector3D.of(1, 1, 0), TEST_PRECISION);
    44
    45      @Test
    46      public void testCtor_default() {
    47          // act
    48          final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine);
    49
    50          // assert
    51          Assert.assertSame(testLine, sub.getLine());
    52          Assert.assertTrue(sub.getSubspaceRegion().isEmpty());
    53          Assert.assertEquals(0, sub.getSize(), TEST_EPS);
    54      }
    55
    56      @Test
    57      public void testCtor_true() {
    58          // act
    59          final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
    60
    61          // assert
    62          Assert.assertSame(testLine, sub.getLine());
    63          Assert.assertTrue(sub.getSubspaceRegion().isFull());
    64          GeometryTestUtils.assertPositiveInfinity(sub.getSize());
    65      }
    66
    67      @Test
    68      public void testCtor_false() {
    69          // act
    70          final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, false);
    71
    72          // assert
    73          Assert.assertSame(testLine, sub.getLine());
    74          Assert.assertTrue(sub.getSubspaceRegion().isEmpty());
    75          Assert.assertEquals(0, sub.getSize(), TEST_EPS);
    76      }
    77
    78      @Test
    79      public void testCtor_lineAndRegion() {
    80          // arrange
    81          final RegionBSPTree1D tree = RegionBSPTree1D.empty();
    82
    83          // act
    84          final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
    85
    86          // assert
    87          Assert.assertSame(testLine, sub.getLine());
    88          Assert.assertSame(tree, sub.getSubspaceRegion());
    89          Assert.assertEquals(0, sub.getSize(), TEST_EPS);
    90      }
    91
    92      @Test
    93      public void testProperties_full() {
    94          // arrange
    95          final EmbeddedTreeLineSubset3D full = new EmbeddedTreeLineSubset3D(testLine, true);
    96
    97          // act/assert
    98          Assert.assertTrue(full.isInfinite());
    99          Assert.assertFalse(full.isFinite());
    100
    101         GeometryTestUtils.assertPositiveInfinity(full.getSize());
    102         Assert.assertNull(full.getCentroid());
    103         Assert.assertNull(full.getBounds());
    104     }
    105
    106     @Test
    107     public void testProperties_empty() {
    108         // arrange
    109         final EmbeddedTreeLineSubset3D empty = new EmbeddedTreeLineSubset3D(testLine, false);
    110
    111         // act/assert
    112         Assert.assertFalse(empty.isInfinite());
    113         Assert.assertTrue(empty.isFinite());
    114
    115         Assert.assertEquals(0, empty.getSize(), TEST_EPS);
    116         Assert.assertNull(empty.getCentroid());
    117         Assert.assertNull(empty.getBounds());
    118     }
    119
    120     @Test
    121     public void testProperties_half() {
    122         // arrange
    123         final EmbeddedTreeLineSubset3D half = new EmbeddedTreeLineSubset3D(testLine, false);
    124         half.getSubspaceRegion().add(Interval.min(1, TEST_PRECISION));
    125
    126         // act/assert
    127         Assert.assertTrue(half.isInfinite());
    128         Assert.assertFalse(half.isFinite());
    129
    130         GeometryTestUtils.assertPositiveInfinity(half.getSize());
    131         Assert.assertNull(half.getCentroid());
    132         Assert.assertNull(half.getBounds());
    133     }
    134
    135     @Test
    136     public void testProperties_finite() {
    137         // arrange
    138         final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(0, 0, 1), Vector3D.of(1, 1, 0), TEST_PRECISION);
    139         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(line);
    140
    141         final double sqrt2 = Math.sqrt(2);
    142         sub.getSubspaceRegion().add(Interval.of(0, sqrt2, TEST_PRECISION));
    143         sub.getSubspaceRegion().add(Interval.of(-2 * sqrt2, -sqrt2, TEST_PRECISION));
    144
    145         // act/assert
    146         Assert.assertFalse(sub.isInfinite());
    147         Assert.assertTrue(sub.isFinite());
    148
    149         Assert.assertEquals(2 * sqrt2, sub.getSize(), TEST_EPS);
    150         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-0.5, -0.5, 1), sub.getCentroid(), TEST_EPS);
    151
    152         final Bounds3D bounds = sub.getBounds();
    153         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-2, -2, 1), bounds.getMin(), TEST_EPS);
    154         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 1, 1), bounds.getMax(), TEST_EPS);
    155     }
    156
    157     @Test
    158     public void testTransform_full() {
    159         // arrange
    160         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
    161
    162         final Transform<Vector3D> transform = AffineTransformMatrix3D.identity()
    163                 .translate(Vector3D.of(1, 0, 0))
    164                 .scale(Vector3D.of(2, 1, 1))
    165                 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
    166
    167         // act
    168         final EmbeddedTreeLineSubset3D result = sub.transform(transform);
    169
    170         // assert
    171         final Line3D resultLine = result.getLine();
    172
    173         final Vector3D expectedOrigin = Lines3D.fromPoints(Vector3D.of(0, 0, -2), Vector3D.of(0, 1, -4), TEST_PRECISION)
    174                 .getOrigin();
    175
    176         EuclideanTestUtils.assertCoordinatesEqual(expectedOrigin, resultLine.getOrigin(), TEST_EPS);
    177         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -2).normalize(), resultLine.getDirection(), TEST_EPS);
    178
    179         Assert.assertTrue(result.getSubspaceRegion().isFull());
    180     }
    181
    182     @Test
    183     public void testTransform_finite() {
    184         // arrange
    185         final RegionBSPTree1D tree = RegionBSPTree1D.empty();
    186         tree.add(Interval.of(
    187                 testLine.toSubspace(Vector3D.of(1, 1, 0)).getX(),
    188                 testLine.toSubspace(Vector3D.of(2, 2, 0)).getX(), TEST_PRECISION));
    189
    190         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
    191
    192         final Transform<Vector3D> transform = AffineTransformMatrix3D.identity()
    193                 .translate(Vector3D.of(1, 0, 0))
    194                 .scale(Vector3D.of(2, 1, 1))
    195                 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
    196
    197         // act
    198         final EmbeddedTreeLineSubset3D result = sub.transform(transform);
    199
    200         // assert
    201         final Line3D resultLine = result.getLine();
    202
    203         final Vector3D expectedOrigin = Lines3D.fromPoints(Vector3D.of(0, 0, -2), Vector3D.of(0, 1, -4), TEST_PRECISION)
    204                 .getOrigin();
    205
    206         EuclideanTestUtils.assertCoordinatesEqual(expectedOrigin, resultLine.getOrigin(), TEST_EPS);
    207         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -2).normalize(), resultLine.getDirection(), TEST_EPS);
    208
    209         Assert.assertFalse(result.getSubspaceRegion().isFull());
    210
    211         final List<Interval> intervals = result.getSubspaceRegion().toIntervals();
    212         Assert.assertEquals(1, intervals.size());
    213
    214         final Interval resultInterval = intervals.get(0);
    215         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -4),
    216                 resultLine.toSpace(resultInterval.getMin()), TEST_EPS);
    217         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 2, -6),
    218                 resultLine.toSpace(resultInterval.getMax()), TEST_EPS);
    219     }
    220
    221     @Test
    222     public void testToConvex_full() {
    223         // arrange
    224         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
    225
    226         // act
    227         final List<LineConvexSubset3D> segments = sub.toConvex();
    228
    229         // assert
    230         Assert.assertEquals(1, segments.size());
    231         Assert.assertTrue(segments.get(0).getSubspaceRegion().isFull());
    232     }
    233
    234     @Test
    235     public void testToConvex_finite() {
    236         // arrange
    237         final RegionBSPTree1D tree = RegionBSPTree1D.empty();
    238         tree.add(Interval.of(
    239                 testLine.toSubspace(Vector3D.of(1, 1, 0)).getX(),
    240                 testLine.toSubspace(Vector3D.of(2, 2, 0)).getX(), TEST_PRECISION));
    241
    242         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
    243
    244         // act
    245         final List<LineConvexSubset3D> segments = sub.toConvex();
    246
    247         // assert
    248         Assert.assertEquals(1, segments.size());
    249
    250         final LineConvexSubset3D segment = segments.get(0);
    251         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 1, 0), segment.getStartPoint(), TEST_EPS);
    252         EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(2, 2, 0), segment.getEndPoint(), TEST_EPS);
    253     }
    254
    255     @Test
    256     public void testToString() {
    257         // arrange
    258         final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine);
    259
    260         // act
    261         final String str = sub.toString();
    262
    263         // assert
    264         Assert.assertTrue(str.contains("EmbeddedTreeLineSubset3D[lineOrigin= "));
    265         Assert.assertTrue(str.contains(", lineDirection= "));
    266         Assert.assertTrue(str.contains(", region= "));
    267     }
    268 }