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