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 org.apache.commons.geometry.core.GeometryTestUtils;
20  import org.apache.commons.geometry.core.RegionLocation;
21  import org.apache.commons.geometry.core.partitioning.Split;
22  import org.apache.commons.geometry.core.partitioning.SplitLocation;
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.junit.Assert;
28  import org.junit.Test;
29  
30  public class SegmentTest {
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 testFromPoints() {
39          // arrange
40          final Vector2D p1 = Vector2D.of(1, 2);
41          final Vector2D p2 = Vector2D.of(3, 2);
42  
43          // act
44          final Segment seg = Lines.segmentFromPoints(p1, p2, TEST_PRECISION);
45  
46          // assert
47          Assert.assertFalse(seg.isFull());
48          Assert.assertFalse(seg.isEmpty());
49          Assert.assertFalse(seg.isInfinite());
50          Assert.assertTrue(seg.isFinite());
51  
52          EuclideanTestUtils.assertCoordinatesEqual(p1, seg.getStartPoint(), TEST_EPS);
53          EuclideanTestUtils.assertCoordinatesEqual(p2, seg.getEndPoint(), TEST_EPS);
54          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 2), seg.getCentroid(), TEST_EPS);
55  
56          Assert.assertEquals(1, seg.getSubspaceStart(), TEST_EPS);
57          Assert.assertEquals(3, seg.getSubspaceEnd(), TEST_EPS);
58  
59          Assert.assertEquals(2, seg.getSize(), TEST_EPS);
60      }
61  
62      @Test
63      public void testFromPoints_invalidArgs() {
64          // arrange
65          final Vector2D p1 = Vector2D.of(0, 2);
66          final Vector2D p2 = Vector2D.of(1e-17, 2);
67  
68          // act/assert
69          GeometryTestUtils.assertThrows(() -> {
70              Lines.segmentFromPoints(p1, p1, TEST_PRECISION);
71          }, IllegalArgumentException.class, "Line direction cannot be zero");
72  
73          GeometryTestUtils.assertThrows(() -> {
74              Lines.segmentFromPoints(p1, p2, TEST_PRECISION);
75          }, IllegalArgumentException.class, "Line direction cannot be zero");
76      }
77  
78      @Test
79      public void testFromPoints_givenLine() {
80          // arrange
81          final Vector2D p1 = Vector2D.of(-1, 2);
82          final Vector2D p2 = Vector2D.of(3, 3);
83  
84          final Line line = Lines.fromPointAndDirection(Vector2D.of(1, 0), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
85  
86          // act
87          final Segment seg = Lines.segmentFromPoints(line, p2, p1); // reverse location order
88  
89          // assert
90          Assert.assertFalse(seg.isFull());
91          Assert.assertFalse(seg.isEmpty());
92          Assert.assertFalse(seg.isInfinite());
93          Assert.assertTrue(seg.isFinite());
94  
95          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2), seg.getStartPoint(), TEST_EPS);
96          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 3), seg.getEndPoint(), TEST_EPS);
97          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2.5), seg.getCentroid(), TEST_EPS);
98  
99          Assert.assertEquals(2, seg.getSubspaceStart(), TEST_EPS);
100         Assert.assertEquals(3, seg.getSubspaceEnd(), TEST_EPS);
101 
102         Assert.assertEquals(1, seg.getSize(), TEST_EPS);
103     }
104 
105     @Test
106     public void testFromPoints_givenLine_singlePoint() {
107         // arrange
108         final Vector2D p1 = Vector2D.of(-1, 2);
109 
110         final Line line = Lines.fromPointAndDirection(Vector2D.of(1, 0), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
111 
112         // act
113         final Segment seg = Lines.segmentFromPoints(line, p1, p1);
114 
115         // assert
116         Assert.assertFalse(seg.isFull());
117         Assert.assertFalse(seg.isEmpty());
118         Assert.assertFalse(seg.isInfinite());
119         Assert.assertTrue(seg.isFinite());
120 
121         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2), seg.getStartPoint(), TEST_EPS);
122         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2), seg.getEndPoint(), TEST_EPS);
123         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 2), seg.getCentroid(), TEST_EPS);
124 
125         Assert.assertEquals(2, seg.getSubspaceStart(), TEST_EPS);
126         Assert.assertEquals(2, seg.getSubspaceEnd(), TEST_EPS);
127 
128         Assert.assertEquals(0, seg.getSize(), TEST_EPS);
129     }
130 
131     @Test
132     public void testFromPoints_givenLine_invalidArgs() {
133         // arrange
134         final Vector2D p0 = Vector2D.of(1, 0);
135         final Vector2D p1 = Vector2D.of(2, 0);
136 
137         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION);
138 
139         // act/assert
140         GeometryTestUtils.assertThrows(() -> {
141             Lines.segmentFromPoints(line, Vector2D.NaN, p1);
142         }, IllegalArgumentException.class, "Invalid line segment locations: NaN, 2.0");
143 
144         GeometryTestUtils.assertThrows(() -> {
145             Lines.segmentFromPoints(line, p0, Vector2D.NaN);
146         }, IllegalArgumentException.class, "Invalid line segment locations: 1.0, NaN");
147 
148         GeometryTestUtils.assertThrows(() -> {
149             Lines.segmentFromPoints(line, Vector2D.NEGATIVE_INFINITY, p1);
150         }, IllegalArgumentException.class, "Invalid line segment locations: NaN, 2.0");
151 
152         GeometryTestUtils.assertThrows(() -> {
153             Lines.segmentFromPoints(line, p0, Vector2D.POSITIVE_INFINITY);
154         }, IllegalArgumentException.class, "Invalid line segment locations: 1.0, NaN");
155     }
156 
157     @Test
158     public void testFromLocations() {
159         // arrange
160         final Line line = Lines.fromPointAndDirection(Vector2D.of(-1, 0), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
161 
162         // act
163         final Segment seg = Lines.segmentFromLocations(line, -1, 2);
164 
165         // assert
166         Assert.assertFalse(seg.isFull());
167         Assert.assertFalse(seg.isEmpty());
168         Assert.assertFalse(seg.isInfinite());
169         Assert.assertTrue(seg.isFinite());
170 
171         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, -1), seg.getStartPoint(), TEST_EPS);
172         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 2), seg.getEndPoint(), TEST_EPS);
173         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 0.5), seg.getCentroid(), TEST_EPS);
174 
175         Assert.assertEquals(-1, seg.getSubspaceStart(), TEST_EPS);
176         Assert.assertEquals(2, seg.getSubspaceEnd(), TEST_EPS);
177 
178         Assert.assertEquals(3, seg.getSize(), TEST_EPS);
179     }
180 
181     @Test
182     public void testFromLocations_reversedLocationOrder() {
183         // arrange
184         final Line line = Lines.fromPointAndDirection(Vector2D.of(-1, 0), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
185 
186         // act
187         final Segment seg = Lines.segmentFromLocations(line, 2, -1);
188 
189         // assert
190         Assert.assertFalse(seg.isFull());
191         Assert.assertFalse(seg.isEmpty());
192         Assert.assertFalse(seg.isInfinite());
193         Assert.assertTrue(seg.isFinite());
194 
195         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, -1), seg.getStartPoint(), TEST_EPS);
196         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 2), seg.getEndPoint(), TEST_EPS);
197         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 0.5), seg.getCentroid(), TEST_EPS);
198 
199         Assert.assertEquals(-1, seg.getSubspaceStart(), TEST_EPS);
200         Assert.assertEquals(2, seg.getSubspaceEnd(), TEST_EPS);
201 
202         Assert.assertEquals(3, seg.getSize(), TEST_EPS);
203     }
204 
205     @Test
206     public void testFromLocations_singlePoint() {
207         // arrange
208         final Line line = Lines.fromPointAndDirection(Vector2D.of(-1, 0), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
209 
210         // act
211         final Segment seg = Lines.segmentFromLocations(line, 1, 1);
212 
213         // assert
214         Assert.assertFalse(seg.isFull());
215         Assert.assertFalse(seg.isEmpty());
216         Assert.assertFalse(seg.isInfinite());
217         Assert.assertTrue(seg.isFinite());
218 
219         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1), seg.getStartPoint(), TEST_EPS);
220         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1), seg.getEndPoint(), TEST_EPS);
221         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1), seg.getCentroid(), TEST_EPS);
222 
223         Assert.assertEquals(1, seg.getSubspaceStart(), TEST_EPS);
224         Assert.assertEquals(1, seg.getSubspaceEnd(), TEST_EPS);
225 
226         Assert.assertEquals(0, seg.getSize(), TEST_EPS);
227     }
228 
229     @Test
230     public void testFromLocations_invalidArgs() {
231         // arrange
232         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION);
233 
234         // act/assert
235         GeometryTestUtils.assertThrows(() -> {
236             Lines.segmentFromLocations(line, Double.NaN, 2);
237         }, IllegalArgumentException.class, "Invalid line segment locations: NaN, 2.0");
238 
239         GeometryTestUtils.assertThrows(() -> {
240             Lines.segmentFromLocations(line, 1, Double.NaN);
241         }, IllegalArgumentException.class, "Invalid line segment locations: 1.0, NaN");
242 
243         GeometryTestUtils.assertThrows(() -> {
244             Lines.segmentFromLocations(line, Double.NEGATIVE_INFINITY, 2);
245         }, IllegalArgumentException.class, "Invalid line segment locations: -Infinity, 2.0");
246 
247         GeometryTestUtils.assertThrows(() -> {
248             Lines.segmentFromLocations(line, 1, Double.POSITIVE_INFINITY);
249         }, IllegalArgumentException.class, "Invalid line segment locations: 1.0, Infinity");
250     }
251 
252     @Test
253     public void testGetBounds() {
254         // arrange
255         final Segment seg = Lines.segmentFromPoints(Vector2D.of(-1, 4), Vector2D.of(2, -2), TEST_PRECISION);
256 
257         // act
258         final Bounds2D bounds = seg.getBounds();
259 
260         // assert
261         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, -2), bounds.getMin(), TEST_EPS);
262         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 4), bounds.getMax(), TEST_EPS);
263     }
264 
265     @Test
266     public void testTransform() {
267         // arrange
268         final AffineTransformMatrix2D t = AffineTransformMatrix2D.createRotation(0.5 * Math.PI)
269                 .translate(Vector2D.Unit.PLUS_X);
270 
271         final Segment seg = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.of(1, 0), TEST_PRECISION);
272 
273         // act
274         final Segment result = seg.transform(t);
275 
276         // assert
277         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 0), result.getStartPoint(), TEST_EPS);
278         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), result.getEndPoint(), TEST_EPS);
279     }
280 
281     @Test
282     public void testTransform_reflection() {
283         // arrange
284         final AffineTransformMatrix2D t = AffineTransformMatrix2D.createRotation(0.5 * Math.PI)
285                 .translate(Vector2D.Unit.PLUS_X)
286                 .scale(1, -1);
287 
288         final Segment seg = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.of(1, 0), TEST_PRECISION);
289 
290         // act
291         final Segment result = seg.transform(t);
292 
293         // assert
294         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 0), result.getStartPoint(), TEST_EPS);
295         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, -1), result.getEndPoint(), TEST_EPS);
296     }
297 
298     @Test
299     public void testReverse() {
300         // arrange
301         final Vector2D start = Vector2D.of(1, 2);
302 
303         EuclideanTestUtils.permuteSkipZero(-4, 4, 1, (x, y) -> {
304             final Vector2D end = Vector2D.of(x, y).add(start);
305 
306             final Segment seg = Lines.segmentFromPoints(start, end, TEST_PRECISION);
307 
308             // act
309             final Segment rev = seg.reverse();
310 
311             // assert
312             Assert.assertEquals(seg.getSize(), rev.getSize(), TEST_EPS);
313 
314             EuclideanTestUtils.assertCoordinatesEqual(seg.getLine().getOrigin(), rev.getLine().getOrigin(), TEST_EPS);
315             Assert.assertEquals(-1, seg.getLine().getDirection().dot(rev.getLine().getDirection()), TEST_EPS);
316 
317             EuclideanTestUtils.assertCoordinatesEqual(seg.getEndPoint(), rev.getStartPoint(), TEST_EPS);
318             EuclideanTestUtils.assertCoordinatesEqual(seg.getStartPoint(), rev.getEndPoint(), TEST_EPS);
319         });
320     }
321 
322     @Test
323     public void testClosest() {
324         // arrange
325         final Vector2D p1 = Vector2D.of(0, -1);
326         final Vector2D p2 = Vector2D.of(0, 1);
327         final Segment seg = Lines.segmentFromPoints(p1, p2, TEST_PRECISION);
328 
329         // act/assert
330         EuclideanTestUtils.assertCoordinatesEqual(p1, seg.closest(p1), TEST_EPS);
331         EuclideanTestUtils.assertCoordinatesEqual(p1, seg.closest(Vector2D.of(0, -2)), TEST_EPS);
332         EuclideanTestUtils.assertCoordinatesEqual(p1, seg.closest(Vector2D.of(2, -2)), TEST_EPS);
333         EuclideanTestUtils.assertCoordinatesEqual(p1, seg.closest(Vector2D.of(-1, -1)), TEST_EPS);
334 
335         EuclideanTestUtils.assertCoordinatesEqual(p2, seg.closest(p2), TEST_EPS);
336         EuclideanTestUtils.assertCoordinatesEqual(p2, seg.closest(Vector2D.of(0, 2)), TEST_EPS);
337         EuclideanTestUtils.assertCoordinatesEqual(p2, seg.closest(Vector2D.of(-2, 2)), TEST_EPS);
338         EuclideanTestUtils.assertCoordinatesEqual(p2, seg.closest(Vector2D.of(-1, 1)), TEST_EPS);
339 
340         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, seg.closest(Vector2D.ZERO), TEST_EPS);
341         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 0.5), seg.closest(Vector2D.of(1, 0.5)), TEST_EPS);
342         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -0.5), seg.closest(Vector2D.of(-2, -0.5)), TEST_EPS);
343     }
344 
345     @Test
346     public void testClassify() {
347         // arrange
348         final Segment seg = Lines.segmentFromPoints(Vector2D.of(1, 1), Vector2D.of(3, 1), TEST_PRECISION);
349 
350         // act/assert
351         EuclideanTestUtils.assertRegionLocation(seg, RegionLocation.OUTSIDE,
352                 Vector2D.of(2, 2), Vector2D.of(2, 0),
353                 Vector2D.of(0, 1), Vector2D.of(4, 1));
354 
355         EuclideanTestUtils.assertRegionLocation(seg, RegionLocation.BOUNDARY,
356                 Vector2D.of(1, 1), Vector2D.of(3, 1),
357                 Vector2D.of(1 + 1e-16, 1), Vector2D.of(3, 1 - 1e-12));
358 
359         EuclideanTestUtils.assertRegionLocation(seg, RegionLocation.INSIDE, Vector2D.of(2, 1));
360     }
361 
362     @Test
363     public void testSplit() {
364         // --- arrange
365         final Vector2D p0 = Vector2D.of(1, 1);
366         final Vector2D p1 = Vector2D.of(3, 1);
367         final Vector2D mid = p0.lerp(p1, 0.5);
368         final Vector2D low = Vector2D.of(0, 1);
369         final Vector2D high = Vector2D.of(3, 1);
370 
371         final Vector2D delta = Vector2D.of(1e-11, 1e-11);
372 
373         final Segment seg = Lines.segmentFromPoints(Vector2D.of(1, 1), Vector2D.of(3, 1), TEST_PRECISION);
374 
375         // --- act
376 
377         // parallel
378         checkSplit(seg.split(Lines.fromPointAndAngle(Vector2D.of(2, 2), 0, TEST_PRECISION)),
379                 null, null,
380                 p0, p1);
381         checkSplit(seg.split(Lines.fromPointAndAngle(Vector2D.of(2, 2), Math.PI, TEST_PRECISION)),
382                 p0, p1,
383                 null, null);
384 
385         // coincident
386         checkSplit(seg.split(Lines.fromPointAndAngle(p0.add(delta), 1e-20, TEST_PRECISION)),
387                 null, null,
388                 null, null);
389 
390         // through mid point
391         checkSplit(seg.split(Lines.fromPointAndAngle(mid, 1, TEST_PRECISION)),
392                 p0, mid,
393                 mid, p1);
394         checkSplit(seg.split(Lines.fromPointAndAngle(mid, -1, TEST_PRECISION)),
395                 mid, p1,
396                 p0, mid);
397 
398         // through start point
399         checkSplit(seg.split(Lines.fromPointAndAngle(p0.subtract(delta), 1, TEST_PRECISION)),
400                 null, null,
401                 p0, p1);
402         checkSplit(seg.split(Lines.fromPointAndAngle(p0.add(delta), -1, TEST_PRECISION)),
403                 p0, p1,
404                 null, null);
405 
406         // through end point
407         checkSplit(seg.split(Lines.fromPointAndAngle(p1.subtract(delta), 1, TEST_PRECISION)),
408                 p0, p1,
409                 null, null);
410         checkSplit(seg.split(Lines.fromPointAndAngle(p1.add(delta), -1, TEST_PRECISION)),
411                 null, null,
412                 p0, p1);
413 
414         // intersection below minus
415         checkSplit(seg.split(Lines.fromPointAndAngle(low, 1, TEST_PRECISION)),
416                 null, null,
417                 p0, p1);
418         checkSplit(seg.split(Lines.fromPointAndAngle(low, -1, TEST_PRECISION)),
419                 p0, p1,
420                 null, null);
421 
422         // intersection above minus
423         checkSplit(seg.split(Lines.fromPointAndAngle(high, 1, TEST_PRECISION)),
424                 p0, p1,
425                 null, null);
426         checkSplit(seg.split(Lines.fromPointAndAngle(high, -1, TEST_PRECISION)),
427                 null, null,
428                 p0, p1);
429     }
430 
431     @Test
432     public void testSplit_pointsOnSplitterWithLineIntersection() {
433         // arrange
434         // Create a segment with both of its points lying on the splitter but with the intersection
435         // of the lines lying far enough away from the segment start point along the line to be
436         // considered a valid 1D distance for a split. In this case, no split should be performed since
437         // both points still lie on the splitter.
438         final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-5);
439 
440         final Segment seg = Lines.segmentFromPoints(Vector2D.of(1, 1e-8), Vector2D.of(1.01, 1e-6), precision);
441 
442         final Line splitter = Lines.fromPointAndAngle(Vector2D.ZERO, 0, precision);
443 
444         // act
445         final Split<LineConvexSubset> split = seg.split(splitter);
446 
447         // assert
448         Assert.assertEquals(SplitLocation.NEITHER, split.getLocation());
449 
450         Assert.assertNull(split.getMinus());
451         Assert.assertNull(split.getPlus());
452     }
453 
454     @Test
455     public void testGetInterval() {
456         // arrange
457         final Segment seg = Lines.segmentFromPoints(Vector2D.of(2, -1), Vector2D.of(2, 2), TEST_PRECISION);
458 
459         // act
460         final Interval interval = seg.getInterval();
461 
462         // assert
463         Assert.assertEquals(-1, interval.getMin(), TEST_EPS);
464         Assert.assertEquals(2, interval.getMax(), TEST_EPS);
465 
466         Assert.assertSame(seg.getLine().getPrecision(), interval.getMinBoundary().getPrecision());
467     }
468 
469     @Test
470     public void testGetInterval_singlePoint() {
471         // arrange
472         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION);
473         final Segment seg = Lines.segmentFromLocations(line, 1, 1);
474 
475         // act
476         final Interval interval = seg.getInterval();
477 
478         // assert
479         Assert.assertEquals(1, interval.getMin(), TEST_EPS);
480         Assert.assertEquals(1, interval.getMax(), TEST_EPS);
481         Assert.assertEquals(0, interval.getSize(), TEST_EPS);
482 
483         Assert.assertSame(seg.getLine().getPrecision(), interval.getMinBoundary().getPrecision());
484     }
485 
486     @Test
487     public void testToString() {
488         // arrange
489         final Segment seg = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.of(1, 0), TEST_PRECISION);
490 
491         // act
492         final String str = seg.toString();
493 
494         // assert
495         GeometryTestUtils.assertContains("Segment[startPoint= (0", str);
496         GeometryTestUtils.assertContains(", endPoint= (1", str);
497     }
498 
499     private static void checkSplit(final Split<LineConvexSubset> split, final Vector2D minusStart, final Vector2D minusEnd,
500                                    final Vector2D plusStart, final Vector2D plusEnd) {
501 
502         final Segment minus = (Segment) split.getMinus();
503         if (minusStart != null) {
504             EuclideanTestUtils.assertCoordinatesEqual(minusStart, minus.getStartPoint(), TEST_EPS);
505             EuclideanTestUtils.assertCoordinatesEqual(minusEnd, minus.getEndPoint(), TEST_EPS);
506         } else {
507             Assert.assertNull(minus);
508         }
509 
510         final Segment plus = (Segment) split.getPlus();
511         if (plusStart != null) {
512             EuclideanTestUtils.assertCoordinatesEqual(plusStart, plus.getStartPoint(), TEST_EPS);
513             EuclideanTestUtils.assertCoordinatesEqual(plusEnd, plus.getEndPoint(), TEST_EPS);
514         } else {
515             Assert.assertNull(plus);
516         }
517     }
518 }