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 }