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.twod;
    18
    19  import java.util.List;
    20
    21  import org.apache.commons.geometry.core.GeometryTestUtils;
    22  import org.apache.commons.geometry.core.partitioning.HyperplaneLocation;
    23  import org.apache.commons.geometry.core.partitioning.Split;
    24  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    25  import org.apache.commons.geometry.euclidean.oned.Interval;
    26  import org.apache.commons.numbers.angle.Angle;
    27  import org.apache.commons.numbers.core.Precision;
    28  import org.junit.jupiter.api.Assertions;
    29  import org.junit.jupiter.api.Test;
    30
    31  class LineConvexSubsetTest {
    32
    33      private static final double TEST_EPS = 1e-10;
    34
    35      private static final Precision.DoubleEquivalence TEST_PRECISION =
    36              Precision.doubleEquivalenceOfEpsilon(TEST_EPS);
    37
    38      @Test
    39      void testFromInterval_intervalArg_finite() {
    40          // arrange
    41          final Precision.DoubleEquivalence intervalPrecision = Precision.doubleEquivalenceOfEpsilon(1e-2);
    42          final Interval interval = Interval.of(-1, 2, intervalPrecision);
    43
    44          final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    45
    46          // act
    47          final Segment segment = (Segment) Lines.subsetFromInterval(line, interval);
    48
    49          // assert
    50          final double side = 1.0 / Math.sqrt(2);
    51          checkFinite(segment, Vector2D.of(-side, -side), Vector2D.of(2 * side, 2 * side));
    52
    53          Assertions.assertSame(TEST_PRECISION, segment.getPrecision());
    54      }
    55
    56      @Test
    57      void testFromInterval_intervalArg_full() {
    58          // arrange
    59          final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    60
    61          // act
    62          final LineConvexSubset span = Lines.subsetFromInterval(line, Interval.full());
    63
    64          // assert
    65          GeometryTestUtils.assertNegativeInfinity(span.getSubspaceStart());
    66          GeometryTestUtils.assertPositiveInfinity(span.getSubspaceEnd());
    67
    68          Assertions.assertNull(span.getStartPoint());
    69          Assertions.assertNull(span.getEndPoint());
    70
    71          Assertions.assertSame(Interval.full(), span.getInterval());
    72          Assertions.assertSame(TEST_PRECISION, span.getPrecision());
    73      }
    74
    75      @Test
    76      void testFromInterval_intervalArg_positiveHalfSpace() {
    77          // arrange
    78          final Precision.DoubleEquivalence intervalPrecision = Precision.doubleEquivalenceOfEpsilon(1e-2);
    79          final Interval interval = Interval.min(-1, intervalPrecision);
    80
    81          final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    82
    83          // act
    84          final Ray ray = (Ray) Lines.subsetFromInterval(line, interval);
    85
    86          // assert
    87          Assertions.assertEquals(-1.0, ray.getSubspaceStart(), TEST_EPS);
    88          GeometryTestUtils.assertPositiveInfinity(ray.getSubspaceEnd());
    89
    90          final double side = 1.0 / Math.sqrt(2);
    91
    92          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-side, -side), ray.getStartPoint(), TEST_EPS);
    93          Assertions.assertNull(ray.getEndPoint());
    94
    95          checkInterval(interval, ray.getInterval());
    96          Assertions.assertSame(TEST_PRECISION, ray.getPrecision());
    97      }
    98
    99      @Test
    100     void testFromInterval_intervalArg_negativeHalfSpace() {
    101         // arrange
    102         final Precision.DoubleEquivalence intervalPrecision = Precision.doubleEquivalenceOfEpsilon(1e-2);
    103         final Interval interval = Interval.max(2, intervalPrecision);
    104
    105         final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    106
    107         // act
    108         final ReverseRay halfLine = (ReverseRay) Lines.subsetFromInterval(line, interval);
    109
    110         // assert
    111         GeometryTestUtils.assertNegativeInfinity(halfLine.getSubspaceStart());
    112         Assertions.assertEquals(2, halfLine.getSubspaceEnd(), TEST_EPS);
    113
    114         final double side = 1.0 / Math.sqrt(2);
    115
    116         Assertions.assertNull(halfLine.getStartPoint());
    117         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2 * side, 2 * side), halfLine.getEndPoint(), TEST_EPS);
    118
    119         checkInterval(interval, halfLine.getInterval());
    120         Assertions.assertSame(TEST_PRECISION, halfLine.getPrecision());
    121     }
    122
    123     @Test
    124     void testFromInterval_doubleArgs_finite() {
    125         // arrange
    126         final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    127
    128         // act
    129         final Segment segment = (Segment) Lines.subsetFromInterval(line, -1, 2);
    130
    131         // assert
    132         final double side = 1.0 / Math.sqrt(2);
    133         checkFinite(segment, Vector2D.of(-side, -side), Vector2D.of(2 * side, 2 * side));
    134
    135         Assertions.assertSame(TEST_PRECISION, segment.getPrecision());
    136     }
    137
    138     @Test
    139     void testFromInterval_doubleArgs_full() {
    140         // arrange
    141         final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    142
    143         // act
    144         final LineConvexSubset span = Lines.subsetFromInterval(line, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    145
    146         // assert
    147         GeometryTestUtils.assertNegativeInfinity(span.getSubspaceStart());
    148         GeometryTestUtils.assertPositiveInfinity(span.getSubspaceEnd());
    149
    150         Assertions.assertNull(span.getStartPoint());
    151         Assertions.assertNull(span.getEndPoint());
    152
    153         Assertions.assertSame(TEST_PRECISION, span.getPrecision());
    154     }
    155
    156     @Test
    157     void testFromInterval_doubleArgs_positiveHalfSpace() {
    158         // arrange
    159         final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    160
    161         // act
    162         final Ray ray = (Ray) Lines.subsetFromInterval(line, -1, Double.POSITIVE_INFINITY);
    163
    164         // assert
    165         Assertions.assertEquals(-1.0, ray.getSubspaceStart(), TEST_EPS);
    166         GeometryTestUtils.assertPositiveInfinity(ray.getSubspaceEnd());
    167
    168         final double side = 1.0 / Math.sqrt(2);
    169
    170         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-side, -side), ray.getStartPoint(), TEST_EPS);
    171         Assertions.assertNull(ray.getEndPoint());
    172
    173         Assertions.assertSame(TEST_PRECISION, ray.getPrecision());
    174     }
    175
    176     @Test
    177     void testFromInterval_doubleArgs_negativeHalfSpace() {
    178         // arrange
    179         final Line line = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
    180
    181         // act
    182         final ReverseRay halfLine = (ReverseRay) Lines.subsetFromInterval(line, 2, Double.NEGATIVE_INFINITY);
    183
    184         // assert
    185         GeometryTestUtils.assertNegativeInfinity(halfLine.getSubspaceStart());
    186         Assertions.assertEquals(2, halfLine.getSubspaceEnd(), TEST_EPS);
    187
    188         final double side = 1.0 / Math.sqrt(2);
    189
    190         Assertions.assertNull(halfLine.getStartPoint());
    191         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2 * side, 2 * side), halfLine.getEndPoint(), TEST_EPS);
    192
    193         Assertions.assertSame(TEST_PRECISION, halfLine.getPrecision());
    194     }
    195
    196     @Test
    197     void testFromInterval_doubleArgs_invalid() {
    198         // arrange
    199         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION);
    200
    201         // act/assert
    202         GeometryTestUtils.assertThrowsWithMessage(() -> {
    203             Lines.subsetFromInterval(line, 0, Double.NaN);
    204         }, IllegalArgumentException.class, "Invalid line subset interval: 0.0, NaN");
    205
    206         GeometryTestUtils.assertThrowsWithMessage(() -> {
    207             Lines.subsetFromInterval(line, Double.NaN, 0.0);
    208         }, IllegalArgumentException.class, "Invalid line subset interval: NaN, 0.0");
    209
    210         GeometryTestUtils.assertThrowsWithMessage(() -> {
    211             Lines.subsetFromInterval(line, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    212         }, IllegalArgumentException.class, "Invalid line subset interval: Infinity, Infinity");
    213
    214         GeometryTestUtils.assertThrowsWithMessage(() -> {
    215             Lines.subsetFromInterval(line, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    216         }, IllegalArgumentException.class, "Invalid line subset interval: -Infinity, -Infinity");
    217
    218         GeometryTestUtils.assertThrowsWithMessage(() -> {
    219             Lines.subsetFromInterval(line, Double.POSITIVE_INFINITY, Double.NaN);
    220         }, IllegalArgumentException.class, "Invalid line subset interval: Infinity, NaN");
    221
    222         GeometryTestUtils.assertThrowsWithMessage(() -> {
    223             Lines.subsetFromInterval(line, Double.NaN, Double.NEGATIVE_INFINITY);
    224         }, IllegalArgumentException.class, "Invalid line subset interval: NaN, -Infinity");
    225     }
    226
    227     @Test
    228     void testToConvex() {
    229         // arrange
    230         final Line line = Lines.fromPoints(Vector2D.of(-1, 0), Vector2D.of(4, 5), TEST_PRECISION);
    231         final LineConvexSubset sub = Lines.subsetFromInterval(line, 1, 2);
    232
    233         // act
    234         final List<LineConvexSubset> segments = sub.toConvex();
    235
    236         // assert
    237         Assertions.assertEquals(1, segments.size());
    238         Assertions.assertSame(sub, segments.get(0));
    239     }
    240
    241     @Test
    242     void testIntersection_line() {
    243         // arrange
    244         final Segment aSeg = Lines.segmentFromPoints(Vector2D.of(1, 0), Vector2D.of(2, 0), TEST_PRECISION);
    245         final Segment bSeg = Lines.segmentFromPoints(Vector2D.of(-1, -1), Vector2D.of(1, 1), TEST_PRECISION);
    246
    247         final Line xAxis = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
    248         final Line yAxis = Lines.fromPointAndAngle(Vector2D.ZERO, Angle.PI_OVER_TWO, TEST_PRECISION);
    249         final Line angledLine = Lines.fromPoints(Vector2D.of(1, 1), Vector2D.of(2, 0), TEST_PRECISION);
    250
    251         // act/assert
    252         Assertions.assertNull(aSeg.intersection(xAxis));
    253         Assertions.assertNull(aSeg.intersection(yAxis));
    254
    255         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, bSeg.intersection(xAxis), TEST_EPS);
    256         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, bSeg.intersection(yAxis), TEST_EPS);
    257
    258         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), bSeg.intersection(angledLine), TEST_EPS);
    259     }
    260
    261     @Test
    262     void testIntersection_lineSegment() {
    263         // arrange
    264         final Segment a = Lines.segmentFromPoints(Vector2D.of(1, 0), Vector2D.of(2, 0), TEST_PRECISION);
    265         final Segment b = Lines.segmentFromPoints(Vector2D.of(-1, -1), Vector2D.of(1, 1), TEST_PRECISION);
    266         final Segment c = Lines.segmentFromPoints(Vector2D.of(-1, 0), Vector2D.ZERO, TEST_PRECISION);
    267         final Segment d = Lines.segmentFromPoints(Vector2D.of(0, 3), Vector2D.of(3, 0), TEST_PRECISION);
    268
    269         // act/assert
    270         Assertions.assertNull(a.intersection(a));
    271         Assertions.assertNull(a.intersection(c));
    272         Assertions.assertNull(a.intersection(b));
    273
    274         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, b.intersection(c), TEST_EPS);
    275
    276         Assertions.assertNull(b.intersection(d));
    277         Assertions.assertNull(d.intersection(b));
    278     }
    279
    280     @Test
    281     void testSplit_finite() {
    282         // arrange
    283         final Vector2D start = Vector2D.of(1, 1);
    284         final Vector2D end = Vector2D.of(3, 2);
    285         final Vector2D middle = start.lerp(end, 0.5);
    286
    287         final Segment sub = Lines.segmentFromPoints(start, end, TEST_PRECISION);
    288
    289         // act/assert
    290         final Split<LineConvexSubset> both = sub.split(Lines.fromPointAndDirection(middle, Vector2D.of(1, -2), TEST_PRECISION));
    291         checkFinite(both.getMinus(), middle, end);
    292         checkFinite(both.getPlus(), start, middle);
    293
    294         final Split<LineConvexSubset> bothReversed = sub.split(Lines.fromPointAndDirection(middle, Vector2D.of(-1, 2), TEST_PRECISION));
    295         checkFinite(bothReversed.getMinus(), start, middle);
    296         checkFinite(bothReversed.getPlus(), middle, end);
    297
    298         final Split<LineConvexSubset> minusOnlyOrthogonal = sub.split(Lines.fromPointAndDirection(start, Vector2D.of(1, -2), TEST_PRECISION));
    299         Assertions.assertSame(sub, minusOnlyOrthogonal.getMinus());
    300         Assertions.assertNull(minusOnlyOrthogonal.getPlus());
    301
    302         final Split<LineConvexSubset> minusOnlyParallel = sub.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(2, 1), TEST_PRECISION));
    303         Assertions.assertSame(sub, minusOnlyParallel.getMinus());
    304         Assertions.assertNull(minusOnlyParallel.getPlus());
    305
    306         final Split<LineConvexSubset> plusOnlyOrthogonal = sub.split(Lines.fromPointAndDirection(end, Vector2D.of(1, -2), TEST_PRECISION));
    307         Assertions.assertNull(plusOnlyOrthogonal.getMinus());
    308         Assertions.assertSame(sub, plusOnlyOrthogonal.getPlus());
    309
    310         final Split<LineConvexSubset> plusOnlyParallel = sub.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(-2, -1), TEST_PRECISION));
    311         Assertions.assertNull(plusOnlyParallel.getMinus());
    312         Assertions.assertSame(sub, plusOnlyParallel.getPlus());
    313
    314         final Split<LineConvexSubset> hyper = sub.split(Lines.fromPointAndDirection(start, Vector2D.of(2, 1), TEST_PRECISION));
    315         Assertions.assertNull(hyper.getMinus());
    316         Assertions.assertNull(hyper.getPlus());
    317     }
    318
    319     @Test
    320     void testSplit_full() {
    321         // arrange
    322         final Vector2D p1 = Vector2D.of(1, 1);
    323         final Vector2D p2 = Vector2D.of(3, 2);
    324         final Vector2D middle = p1.lerp(p2, 0.5);
    325
    326         final Line line = Lines.fromPoints(p1, p2, TEST_PRECISION);
    327
    328         final LineConvexSubset seg = Lines.subsetFromInterval(line, Interval.full());
    329
    330         // act/assert
    331         final Split<LineConvexSubset> both = seg.split(Lines.fromPointAndDirection(middle, Vector2D.of(1, -2), TEST_PRECISION));
    332         checkInfinite(both.getMinus(), line,  middle, null);
    333         checkInfinite(both.getPlus(), line, null, middle);
    334
    335         final Split<LineConvexSubset> bothReversed = seg.split(Lines.fromPointAndDirection(middle, Vector2D.of(-1, 2), TEST_PRECISION));
    336         checkInfinite(bothReversed.getMinus(), line,  null, middle);
    337         checkInfinite(bothReversed.getPlus(), line, middle, null);
    338
    339         final Split<LineConvexSubset> minusOnlyParallel = seg.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(2, 1), TEST_PRECISION));
    340         Assertions.assertSame(seg, minusOnlyParallel.getMinus());
    341         Assertions.assertNull(minusOnlyParallel.getPlus());
    342
    343         final Split<LineConvexSubset> plusOnlyParallel = seg.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(-2, -1), TEST_PRECISION));
    344         Assertions.assertNull(plusOnlyParallel.getMinus());
    345         Assertions.assertSame(seg, plusOnlyParallel.getPlus());
    346
    347         final Split<LineConvexSubset> hyper = seg.split(Lines.fromPointAndDirection(p1, Vector2D.of(2, 1), TEST_PRECISION));
    348         Assertions.assertNull(hyper.getMinus());
    349         Assertions.assertNull(hyper.getPlus());
    350     }
    351
    352     @Test
    353     void testSplit_positiveHalfSpace() {
    354         // arrange
    355         final Vector2D p1 = Vector2D.of(1, 1);
    356         final Vector2D p2 = Vector2D.of(3, 2);
    357         final Vector2D middle = p1.lerp(p2, 0.5);
    358
    359         final Line line = Lines.fromPoints(p1, p2, TEST_PRECISION);
    360
    361         final LineConvexSubset sub = Lines.subsetFromInterval(line, Interval.min(line.toSubspace(p1).getX(), TEST_PRECISION));
    362
    363         // act/assert
    364         final Split<LineConvexSubset> both = sub.split(Lines.fromPointAndDirection(middle, Vector2D.of(1, -2), TEST_PRECISION));
    365         checkInfinite(both.getMinus(), line,  middle, null);
    366         checkFinite(both.getPlus(), p1, middle);
    367
    368         final Split<LineConvexSubset> bothReversed = sub.split(Lines.fromPointAndDirection(middle, Vector2D.of(-1, 2), TEST_PRECISION));
    369         checkFinite(bothReversed.getMinus(), p1, middle);
    370         checkInfinite(bothReversed.getPlus(), line, middle, null);
    371
    372         final Split<LineConvexSubset> minusOnlyParallel = sub.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(2, 1), TEST_PRECISION));
    373         Assertions.assertSame(sub, minusOnlyParallel.getMinus());
    374         Assertions.assertNull(minusOnlyParallel.getPlus());
    375
    376         final Split<LineConvexSubset> minusOnlyOrthogonal = sub.split(Lines.fromPointAndDirection(p1, Vector2D.of(1, -2), TEST_PRECISION));
    377         Assertions.assertSame(sub, minusOnlyOrthogonal.getMinus());
    378         Assertions.assertNull(minusOnlyOrthogonal.getPlus());
    379
    380         final Split<LineConvexSubset> plusOnlyParallel = sub.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(-2, -1), TEST_PRECISION));
    381         Assertions.assertNull(plusOnlyParallel.getMinus());
    382         Assertions.assertSame(sub, plusOnlyParallel.getPlus());
    383
    384         final Split<LineConvexSubset> hyper = sub.split(Lines.fromPointAndDirection(p1, Vector2D.of(2, 1), TEST_PRECISION));
    385         Assertions.assertNull(hyper.getMinus());
    386         Assertions.assertNull(hyper.getPlus());
    387     }
    388
    389     @Test
    390     void testSplit_negativeHalfSpace() {
    391         // arrange
    392         final Vector2D p1 = Vector2D.of(1, 1);
    393         final Vector2D p2 = Vector2D.of(3, 2);
    394         final Vector2D middle = p1.lerp(p2, 0.5);
    395
    396         final Line line = Lines.fromPoints(p1, p2, TEST_PRECISION);
    397
    398         final LineConvexSubset seg = Lines.subsetFromInterval(line, Interval.max(line.toSubspace(p2).getX(), TEST_PRECISION));
    399
    400         // act/assert
    401         final Split<LineConvexSubset> both = seg.split(Lines.fromPointAndDirection(middle, Vector2D.of(1, -2), TEST_PRECISION));
    402         checkFinite(both.getMinus(), middle, p2);
    403         checkInfinite(both.getPlus(), line, null, middle);
    404
    405         final Split<LineConvexSubset> bothReversed = seg.split(Lines.fromPointAndDirection(middle, Vector2D.of(-1, 2), TEST_PRECISION));
    406         checkInfinite(bothReversed.getMinus(), line, null, middle);
    407         checkFinite(bothReversed.getPlus(), middle, p2);
    408
    409         final Split<LineConvexSubset> minusOnlyParallel = seg.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(2, 1), TEST_PRECISION));
    410         Assertions.assertSame(seg, minusOnlyParallel.getMinus());
    411         Assertions.assertNull(minusOnlyParallel.getPlus());
    412
    413         final Split<LineConvexSubset> plusOnlyParallel = seg.split(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(-2, -1), TEST_PRECISION));
    414         Assertions.assertNull(plusOnlyParallel.getMinus());
    415         Assertions.assertSame(seg, plusOnlyParallel.getPlus());
    416
    417         final Split<LineConvexSubset> plusOnlyOrthogonal = seg.split(Lines.fromPointAndDirection(p2, Vector2D.of(1, -2), TEST_PRECISION));
    418         Assertions.assertNull(plusOnlyOrthogonal.getMinus());
    419         Assertions.assertSame(seg, plusOnlyOrthogonal.getPlus());
    420
    421         final Split<LineConvexSubset> hyper = seg.split(Lines.fromPointAndDirection(p1, Vector2D.of(2, 1), TEST_PRECISION));
    422         Assertions.assertNull(hyper.getMinus());
    423         Assertions.assertNull(hyper.getPlus());
    424     }
    425
    426     private static void checkInterval(final Interval expected, final Interval actual) {
    427         Assertions.assertEquals(expected.getMin(), actual.getMin(), TEST_EPS);
    428         Assertions.assertEquals(expected.getMax(), actual.getMax(), TEST_EPS);
    429     }
    430
    431     private static void checkFinite(final LineConvexSubset segment, final Vector2D start, final Vector2D end) {
    432         checkFinite(segment, start, end, TEST_PRECISION);
    433     }
    434
    435     private static void checkFinite(final LineConvexSubset segment, final Vector2D start, final Vector2D end, final Precision.DoubleEquivalence precision) {
    436         Assertions.assertFalse(segment.isInfinite());
    437
    438         EuclideanTestUtils.assertCoordinatesEqual(start, segment.getStartPoint(), TEST_EPS);
    439         EuclideanTestUtils.assertCoordinatesEqual(end, segment.getEndPoint(), TEST_EPS);
    440
    441         final Line line = segment.getLine();
    442         Assertions.assertEquals(HyperplaneLocation.ON, line.classify(segment.getStartPoint()));
    443         Assertions.assertEquals(HyperplaneLocation.ON, line.classify(segment.getEndPoint()));
    444
    445         Assertions.assertEquals(line.toSubspace(segment.getStartPoint()).getX(), segment.getSubspaceStart(), TEST_EPS);
    446         Assertions.assertEquals(line.toSubspace(segment.getEndPoint()).getX(), segment.getSubspaceEnd(), TEST_EPS);
    447
    448         Assertions.assertSame(precision, segment.getPrecision());
    449         Assertions.assertSame(precision, line.getPrecision());
    450     }
    451
    452     private static void checkInfinite(final LineConvexSubset segment, final Line line, final Vector2D start, final Vector2D end) {
    453         checkInfinite(segment, line, start, end, TEST_PRECISION);
    454     }
    455
    456     private static void checkInfinite(final LineConvexSubset segment, final Line line, final Vector2D start, final Vector2D end,
    457                                       final Precision.DoubleEquivalence precision) {
    458
    459         Assertions.assertTrue(segment.isInfinite());
    460
    461         Assertions.assertEquals(line, segment.getLine());
    462
    463         if (start == null) {
    464             Assertions.assertNull(segment.getStartPoint());
    465         } else {
    466             EuclideanTestUtils.assertCoordinatesEqual(start, segment.getStartPoint(), TEST_EPS);
    467             Assertions.assertEquals(line.toSubspace(segment.getStartPoint()).getX(), segment.getSubspaceStart(), TEST_EPS);
    468         }
    469
    470         if (end == null) {
    471             Assertions.assertNull(segment.getEndPoint());
    472         } else {
    473             EuclideanTestUtils.assertCoordinatesEqual(end, segment.getEndPoint(), TEST_EPS);
    474             Assertions.assertEquals(line.toSubspace(segment.getEndPoint()).getX(), segment.getSubspaceEnd(), TEST_EPS);
    475         }
    476
    477         Assertions.assertSame(precision, segment.getPrecision());
    478         Assertions.assertSame(precision, line.getPrecision());
    479     }
    480 }