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.Split;
23  import org.apache.commons.geometry.core.partitioning.SplitLocation;
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.geometry.euclidean.oned.RegionBSPTree1D;
29  import org.apache.commons.numbers.angle.PlaneAngleRadians;
30  import org.junit.Assert;
31  import org.junit.Test;
32  
33  public class EmbeddedTreeLineSubsetTest {
34  
35      private static final double TEST_EPS = 1e-10;
36  
37      private static final DoublePrecisionContext TEST_PRECISION =
38              new EpsilonDoublePrecisionContext(TEST_EPS);
39  
40      private static final Line DEFAULT_TEST_LINE =
41              Lines.fromPointAndDirection(Vector2D.of(0, 1), Vector2D.Unit.PLUS_X, TEST_PRECISION);
42  
43      @Test
44      public void testCtor_lineOnly() {
45          // act
46          final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE);
47  
48          // assert
49          Assert.assertSame(DEFAULT_TEST_LINE, sub.getLine());
50          Assert.assertSame(TEST_PRECISION, sub.getPrecision());
51  
52          Assert.assertFalse(sub.isFull());
53          Assert.assertTrue(sub.isEmpty());
54          Assert.assertFalse(sub.isInfinite());
55          Assert.assertTrue(sub.isFinite());
56  
57          Assert.assertEquals(0, sub.getSize(), TEST_EPS);
58          Assert.assertNull(sub.getCentroid());
59      }
60  
61      @Test
62      public void testCtor_lineAndBoolean() {
63          // act
64          final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE, true);
65  
66          // assert
67          Assert.assertSame(DEFAULT_TEST_LINE, sub.getLine());
68          Assert.assertSame(TEST_PRECISION, sub.getPrecision());
69  
70          Assert.assertTrue(sub.isFull());
71          Assert.assertFalse(sub.isEmpty());
72          Assert.assertTrue(sub.isInfinite());
73          Assert.assertFalse(sub.isFinite());
74  
75          GeometryTestUtils.assertPositiveInfinity(sub.getSize());
76          Assert.assertNull(sub.getCentroid());
77      }
78  
79      @Test
80      public void testCtor_lineAndRegion() {
81          // arrange
82          final RegionBSPTree1D tree = RegionBSPTree1D.full();
83  
84          // act
85          final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE, tree);
86  
87          // assert
88          Assert.assertSame(DEFAULT_TEST_LINE, sub.getLine());
89          Assert.assertSame(tree, sub.getSubspaceRegion());
90          Assert.assertSame(TEST_PRECISION, sub.getPrecision());
91  
92          Assert.assertTrue(sub.isFull());
93          Assert.assertFalse(sub.isEmpty());
94          Assert.assertTrue(sub.isInfinite());
95          Assert.assertFalse(sub.isFinite());
96  
97          GeometryTestUtils.assertPositiveInfinity(sub.getSize());
98          Assert.assertNull(sub.getCentroid());
99      }
100 
101     @Test
102     public void testToConvex_full() {
103         // arrange
104         final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE, true);
105 
106         // act
107         final List<LineConvexSubset> segments = sub.toConvex();
108 
109         // assert
110         Assert.assertEquals(1, segments.size());
111 
112         final LineConvexSubset seg = segments.get(0);
113         Assert.assertTrue(seg.isFull());
114     }
115 
116     @Test
117     public void testToConvex_empty() {
118         // arrange
119         final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE, false);
120 
121         // act
122         final List<LineConvexSubset> segments = sub.toConvex();
123 
124         // assert
125         Assert.assertEquals(0, segments.size());
126     }
127 
128     @Test
129     public void testToConvex_finiteAndInfiniteSegments() {
130         // arrange
131         final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE, false);
132         final RegionBSPTree1D tree = sub.getSubspaceRegion();
133         tree.add(Interval.max(-2.0, TEST_PRECISION));
134         tree.add(Interval.of(-1, 2, TEST_PRECISION));
135 
136         // act
137         final List<LineConvexSubset> segments = sub.toConvex();
138 
139         // assert
140         Assert.assertEquals(2, segments.size());
141 
142         Assert.assertNull(segments.get(0).getStartPoint());
143         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 1), segments.get(0).getEndPoint(), TEST_EPS);
144 
145         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1), segments.get(1).getStartPoint(), TEST_EPS);
146         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 1), segments.get(1).getEndPoint(), TEST_EPS);
147     }
148 
149     @Test
150     public void testAdd_lineSegment() {
151         // arrange
152         final Line line = Lines.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);
153         final Line otherLine = Lines.fromPointAndAngle(Vector2D.of(0, 1), 1e-11, TEST_PRECISION);
154 
155         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line);
156 
157         // act
158         subset.add(Lines.subsetFromInterval(line, 2, 4));
159         subset.add(Lines.subsetFromInterval(otherLine, 1, 3));
160         subset.add(Lines.segmentFromPoints(Vector2D.of(-3, 1), Vector2D.of(-1, 1), TEST_PRECISION));
161 
162         // assert
163         Assert.assertFalse(subset.isFull());
164         Assert.assertFalse(subset.isEmpty());
165 
166         final List<LineConvexSubset> segments = subset.toConvex();
167 
168         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segments.get(0).getStartPoint(), TEST_EPS);
169         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1), segments.get(0).getEndPoint(), TEST_EPS);
170 
171         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), segments.get(1).getStartPoint(), TEST_EPS);
172         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(4, 1), segments.get(1).getEndPoint(), TEST_EPS);
173 
174         Assert.assertEquals(5, subset.getSize(), TEST_EPS);
175         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0.7, 1), subset.getCentroid(), TEST_EPS);
176     }
177 
178     @Test
179     public void testAdd_subset() {
180         // arrange
181         final Line line = Lines.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);
182 
183         final EmbeddedTreeLineSubset a = new EmbeddedTreeLineSubset(line);
184         final RegionBSPTree1D aTree = a.getSubspaceRegion();
185         aTree.add(Interval.max(-3, TEST_PRECISION));
186         aTree.add(Interval.of(1, 2, TEST_PRECISION));
187 
188         final EmbeddedTreeLineSubset b = new EmbeddedTreeLineSubset(line);
189         final RegionBSPTree1D bTree = b.getSubspaceRegion();
190         bTree.add(Interval.of(2, 4, TEST_PRECISION));
191         bTree.add(Interval.of(-4, -2, TEST_PRECISION));
192 
193         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line);
194 
195         final int aTreeCount = aTree.count();
196         final int bTreeCount = bTree.count();
197 
198         // act
199         subset.add(a);
200         subset.add(b);
201 
202         // assert
203         Assert.assertFalse(subset.isFull());
204         Assert.assertFalse(subset.isEmpty());
205 
206         final List<LineConvexSubset> segments = subset.toConvex();
207 
208         Assert.assertEquals(2, segments.size());
209 
210         Assert.assertNull(segments.get(0).getStartPoint());
211         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 1), segments.get(0).getEndPoint(), TEST_EPS);
212 
213         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), segments.get(1).getStartPoint(), TEST_EPS);
214         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(4, 1), segments.get(1).getEndPoint(), TEST_EPS);
215 
216         Assert.assertEquals(aTreeCount, aTree.count());
217         Assert.assertEquals(bTreeCount, bTree.count());
218 
219         GeometryTestUtils.assertPositiveInfinity(subset.getSize());
220         Assert.assertNull(subset.getCentroid());
221     }
222 
223     @Test
224     public void testAdd_argumentsFromDifferentLine() {
225         // arrange
226         final Line line = Lines.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);
227         final Line otherLine = Lines.fromPointAndAngle(Vector2D.of(0, 1), 1e-2, TEST_PRECISION);
228 
229         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line);
230 
231         // act/assert
232         GeometryTestUtils.assertThrows(() -> {
233             subset.add(Lines.subsetFromInterval(otherLine, 0, 1));
234         }, IllegalArgumentException.class);
235 
236         GeometryTestUtils.assertThrows(() -> {
237             subset.add(new EmbeddedTreeLineSubset(otherLine));
238         }, IllegalArgumentException.class);
239     }
240 
241     @Test
242     public void testGetBounds_noBounds() {
243         // arrange
244         final Line line = Lines.fromPointAndAngle(Vector2D.of(1, 0), 0.25 * Math.PI, TEST_PRECISION);
245 
246         final EmbeddedTreeLineSubset full = new EmbeddedTreeLineSubset(line, RegionBSPTree1D.full());
247         final EmbeddedTreeLineSubset empty = new EmbeddedTreeLineSubset(line, RegionBSPTree1D.empty());
248         final EmbeddedTreeLineSubset halfFull = new EmbeddedTreeLineSubset(line, Interval.min(1.0, TEST_PRECISION).toTree());
249 
250         // act/assert
251         Assert.assertNull(full.getBounds());
252         Assert.assertNull(empty.getBounds());
253         Assert.assertNull(halfFull.getBounds());
254     }
255 
256     @Test
257     public void testGetBounds_hasBounds() {
258         // arrange
259         final Line line = Lines.fromPoints(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
260 
261         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, false);
262 
263         final double sqrt2 = Math.sqrt(2);
264         subset.getSubspaceRegion().add(Interval.of(-2 * sqrt2, -sqrt2, TEST_PRECISION));
265         subset.getSubspaceRegion().add(Interval.of(0, sqrt2, TEST_PRECISION));
266 
267         // act
268         final Bounds2D bounds = subset.getBounds();
269 
270         // assert
271         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, -2), bounds.getMin(), TEST_EPS);
272         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), bounds.getMax(), TEST_EPS);
273     }
274 
275     @Test
276     public void testSplit_both_anglePositive() {
277         // arrange
278         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
279         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
280         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
281 
282         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
283         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
284 
285         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(1, 0), 0.1 * PlaneAngleRadians.PI, TEST_PRECISION);
286 
287         // act
288         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
289 
290         // assert
291         Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
292 
293         final List<LineConvexSubset> minusSegments = split.getMinus().toConvex();
294         Assert.assertEquals(1, minusSegments.size());
295         checkFiniteSegment(minusSegments.get(0), Vector2D.ZERO, Vector2D.of(1, 0));
296 
297         final List<LineConvexSubset> plusSegments = split.getPlus().toConvex();
298         Assert.assertEquals(2, plusSegments.size());
299         checkFiniteSegment(plusSegments.get(0), Vector2D.of(1, 0), Vector2D.of(2, 0));
300         checkFiniteSegment(plusSegments.get(1), Vector2D.of(3, 0), Vector2D.of(4, 0));
301     }
302 
303     @Test
304     public void testSplit_both_angleNegative() {
305         // arrange
306         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
307         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
308         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
309 
310         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
311         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
312 
313         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(1, 0), -0.9 * PlaneAngleRadians.PI, TEST_PRECISION);
314 
315         // act
316         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
317 
318         // assert
319         Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
320 
321         final List<LineConvexSubset> minusSegments = split.getMinus().toConvex();
322         Assert.assertEquals(2, minusSegments.size());
323         checkFiniteSegment(minusSegments.get(0), Vector2D.of(1, 0), Vector2D.of(2, 0));
324         checkFiniteSegment(minusSegments.get(1), Vector2D.of(3, 0), Vector2D.of(4, 0));
325 
326         final List<LineConvexSubset> plusSegments = split.getPlus().toConvex();
327         Assert.assertEquals(1, plusSegments.size());
328         checkFiniteSegment(plusSegments.get(0), Vector2D.ZERO, Vector2D.of(1, 0));
329     }
330 
331     @Test
332     public void testSplit_intersection_plusOnly() {
333         // arrange
334         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
335         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
336         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
337 
338         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
339         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
340 
341         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(-1, 0), 0.1 * PlaneAngleRadians.PI, TEST_PRECISION);
342 
343         // act
344         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
345 
346         // assert
347         Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
348 
349         Assert.assertNull(split.getMinus());
350         Assert.assertSame(subset, split.getPlus());
351     }
352 
353     @Test
354     public void testSplit_intersection_minusOnly() {
355         // arrange
356         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
357         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
358         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
359 
360         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
361         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
362 
363         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(10, 0), 0.1 * PlaneAngleRadians.PI, TEST_PRECISION);
364 
365         // act
366         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
367 
368         // assert
369         Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
370 
371         Assert.assertSame(subset, split.getMinus());
372         Assert.assertNull(split.getPlus());
373     }
374 
375     @Test
376     public void testSplit_parallel_plus() {
377         // arrange
378         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
379         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
380         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
381 
382         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
383         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
384 
385         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);
386 
387         // act
388         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
389 
390         // assert
391         Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
392 
393         Assert.assertNull(split.getMinus());
394         Assert.assertSame(subset, split.getPlus());
395     }
396 
397     @Test
398     public void testSplit_parallel_minus() {
399         // arrange
400         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
401         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
402         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
403 
404         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
405         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
406 
407         final Line splitter = Lines.fromPointAndAngle(Vector2D.of(0, -1), 0.0, TEST_PRECISION);
408 
409         // act
410         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
411 
412         // assert
413         Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
414 
415         Assert.assertSame(subset, split.getMinus());
416         Assert.assertNull(split.getPlus());
417     }
418 
419     @Test
420     public void testSplit_coincident_sameDirection() {
421         // arrange
422         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
423         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
424         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
425 
426         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
427         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
428 
429         final Line splitter = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
430 
431         // act
432         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
433 
434         // assert
435         Assert.assertEquals(SplitLocation.NEITHER, split.getLocation());
436 
437         Assert.assertNull(split.getMinus());
438         Assert.assertNull(split.getPlus());
439     }
440 
441     @Test
442     public void testSplit_coincident_oppositeDirection() {
443         // arrange
444         final RegionBSPTree1D subRegion = RegionBSPTree1D.empty();
445         subRegion.add(Interval.of(0,  2, TEST_PRECISION));
446         subRegion.add(Interval.of(3,  4, TEST_PRECISION));
447 
448         final Line line = Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
449         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(line, subRegion);
450 
451         final Line splitter = Lines.fromPointAndAngle(Vector2D.ZERO, PlaneAngleRadians.PI, TEST_PRECISION);
452 
453         // act
454         final Split<EmbeddedTreeLineSubset> split = subset.split(splitter);
455 
456         // assert
457         Assert.assertEquals(SplitLocation.NEITHER, split.getLocation());
458 
459         Assert.assertNull(split.getMinus());
460         Assert.assertNull(split.getPlus());
461     }
462 
463     @Test
464     public void testTransform() {
465         // arrange
466         final AffineTransformMatrix2D mat = AffineTransformMatrix2D
467                 .createRotation(Vector2D.of(0, 1), PlaneAngleRadians.PI_OVER_TWO)
468                 .scale(Vector2D.of(3, 2));
469 
470         final EmbeddedTreeLineSubset subset = new EmbeddedTreeLineSubset(Lines.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION));
471         subset.getSubspaceRegion().add(Interval.of(0, 1, TEST_PRECISION));
472         subset.getSubspaceRegion().add(Interval.min(3, TEST_PRECISION));
473 
474         // act
475         final EmbeddedTreeLineSubset transformed = subset.transform(mat);
476 
477         // assert
478         Assert.assertNotSame(subset, transformed);
479 
480         final List<LineConvexSubset> originalSegments = subset.toConvex();
481         Assert.assertEquals(2, originalSegments.size());
482         checkFiniteSegment(originalSegments.get(0), Vector2D.ZERO, Vector2D.Unit.PLUS_X);
483         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 0), originalSegments.get(1).getStartPoint(), TEST_EPS);
484         Assert.assertNull(originalSegments.get(1).getEndPoint());
485 
486         final List<LineConvexSubset> transformedSegments = transformed.toConvex();
487         Assert.assertEquals(2, transformedSegments.size());
488         checkFiniteSegment(transformedSegments.get(0), Vector2D.of(3, 2), Vector2D.of(3, 4));
489         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 8), transformedSegments.get(1).getStartPoint(), TEST_EPS);
490         Assert.assertNull(transformedSegments.get(1).getEndPoint());
491     }
492 
493     @Test
494     public void testTransform_reflection() {
495         // arrange
496         final AffineTransformMatrix2D mat = AffineTransformMatrix2D.createScale(Vector2D.of(-1, 2));
497 
498         final EmbeddedTreeLineSubset subset =
499                 new EmbeddedTreeLineSubset(Lines.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION));
500         subset.getSubspaceRegion().add(Interval.of(0, 1, TEST_PRECISION));
501 
502         // act
503         final EmbeddedTreeLineSubset transformed = subset.transform(mat);
504 
505         // assert
506         Assert.assertNotSame(subset, transformed);
507 
508         final List<LineConvexSubset> originalSegments = subset.toConvex();
509         Assert.assertEquals(1, originalSegments.size());
510         checkFiniteSegment(originalSegments.get(0), Vector2D.of(0, 1), Vector2D.of(1, 1));
511 
512         final List<LineConvexSubset> transformedSegments = transformed.toConvex();
513         Assert.assertEquals(1, transformedSegments.size());
514         checkFiniteSegment(transformedSegments.get(0), Vector2D.of(0, 2), Vector2D.of(-1, 2));
515     }
516 
517     @Test
518     public void testToString() {
519         // arrange
520         final EmbeddedTreeLineSubset sub = new EmbeddedTreeLineSubset(DEFAULT_TEST_LINE);
521 
522         // act
523         final String str = sub.toString();
524 
525         // assert
526         Assert.assertTrue(str.contains("EmbeddedTreeLineSubset[lineOrigin= "));
527         Assert.assertTrue(str.contains(", lineDirection= "));
528         Assert.assertTrue(str.contains(", region= "));
529     }
530 
531     private static void checkFiniteSegment(final LineConvexSubset segment, final Vector2D start, final Vector2D end) {
532         Assert.assertFalse(segment.isInfinite());
533 
534         EuclideanTestUtils.assertCoordinatesEqual(start, segment.getStartPoint(), TEST_EPS);
535         EuclideanTestUtils.assertCoordinatesEqual(end, segment.getEndPoint(), TEST_EPS);
536     }
537 }