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.path;
    18
    19  import java.util.ArrayList;
    20  import java.util.Arrays;
    21  import java.util.Collections;
    22  import java.util.List;
    23  import java.util.Random;
    24
    25  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    26  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
    27  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    28  import org.apache.commons.geometry.euclidean.twod.Line;
    29  import org.apache.commons.geometry.euclidean.twod.LineConvexSubset;
    30  import org.apache.commons.geometry.euclidean.twod.Lines;
    31  import org.apache.commons.geometry.euclidean.twod.Segment;
    32  import org.apache.commons.geometry.euclidean.twod.Vector2D;
    33  import org.apache.commons.geometry.euclidean.twod.path.AbstractLinePathConnector.ConnectableLineSubset;
    34  import org.apache.commons.numbers.angle.PlaneAngleRadians;
    35  import org.junit.Assert;
    36  import org.junit.Test;
    37
    38  public class AbstractLinePathConnectorTest {
    39
    40      private static final double TEST_EPS = 1e-10;
    41
    42      private static final DoublePrecisionContext TEST_PRECISION =
    43              new EpsilonDoublePrecisionContext(TEST_EPS);
    44
    45      private static final Line Y_AXIS = Lines.fromPointAndAngle(Vector2D.ZERO, PlaneAngleRadians.PI_OVER_TWO,
    46              TEST_PRECISION);
    47
    48      private final TestConnector connector = new TestConnector();
    49
    50      @Test
    51      public void testConnectAll_emptyCollection() {
    52          // act
    53          final List<LinePath> paths = connector.connectAll(Collections.emptyList());
    54
    55          // assert
    56          Assert.assertEquals(0, paths.size());
    57      }
    58
    59      @Test
    60      public void testConnectAll_singleInfiniteLine() {
    61          // arrange
    62          final LineConvexSubset segment = Y_AXIS.span();
    63
    64          // act
    65          final List<LinePath> paths = connector.connectAll(Collections.singletonList(segment));
    66
    67          // assert
    68          Assert.assertEquals(1, paths.size());
    69
    70          final LinePath path = paths.get(0);
    71          Assert.assertEquals(1, path.getElements().size());
    72          Assert.assertSame(segment, path.getStart());
    73      }
    74
    75      @Test
    76      public void testConnectAll_singleHalfInfiniteLine_noEndPoint() {
    77          // arrange
    78          final LineConvexSubset segment = Y_AXIS.rayFrom(Vector2D.ZERO);
    79
    80          // act
    81          final List<LinePath> paths = connector.connectAll(Collections.singletonList(segment));
    82
    83          // assert
    84          Assert.assertEquals(1, paths.size());
    85
    86          final LinePath path = paths.get(0);
    87          Assert.assertEquals(1, path.getElements().size());
    88          Assert.assertSame(segment, path.getStart());
    89      }
    90
    91      @Test
    92      public void testConnectAll_singleHalfInfiniteLine_noStartPoint() {
    93          // arrange
    94          final LineConvexSubset segment = Y_AXIS.reverseRayTo(Vector2D.ZERO);
    95
    96          // act
    97          final List<LinePath> paths = connector.connectAll(Collections.singletonList(segment));
    98
    99          // assert
    100         Assert.assertEquals(1, paths.size());
    101
    102         final LinePath path = paths.get(0);
    103         Assert.assertEquals(1, path.getElements().size());
    104         Assert.assertSame(segment, path.getStart());
    105     }
    106
    107     @Test
    108     public void testConnectAll_disjointSegments() {
    109         // arrange
    110         final LineConvexSubset a = Y_AXIS.segment(Vector2D.of(0, 1), Vector2D.of(0, 2));
    111         final LineConvexSubset b = Y_AXIS.segment(Vector2D.of(0, -1), Vector2D.ZERO);
    112
    113         final List<LineConvexSubset> segments = Arrays.asList(a, b);
    114
    115         // act
    116         final List<LinePath> paths = connector.connectAll(segments);
    117
    118         // assert
    119         Assert.assertEquals(2, paths.size());
    120
    121         assertFinitePath(paths.get(0), Vector2D.of(0, -1), Vector2D.ZERO);
    122         assertFinitePath(paths.get(1), Vector2D.of(0, 1), Vector2D.of(0, 2));
    123     }
    124
    125     @Test
    126     public void testConnectAll_singleClosedPath() {
    127         // arrange
    128         final LinePath input = LinePath.builder(TEST_PRECISION)
    129                 .appendVertices(Vector2D.of(1, 1), Vector2D.ZERO, Vector2D.of(1, 0))
    130                 .close();
    131
    132         final List<LineConvexSubset> segments = new ArrayList<>(input.getElements());
    133         shuffle(segments);
    134
    135         // act
    136         final List<LinePath> paths = connector.connectAll(segments);
    137
    138         // assert
    139         Assert.assertEquals(1, paths.size());
    140
    141         assertFinitePath(paths.get(0),
    142                 Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(1, 1), Vector2D.ZERO);
    143     }
    144
    145     @Test
    146     public void testConnectAll_multipleClosedPaths() {
    147         // arrange
    148         final LinePath a = LinePath.builder(TEST_PRECISION)
    149                 .appendVertices(Vector2D.of(1, 1), Vector2D.ZERO, Vector2D.of(1, 0))
    150                 .close();
    151
    152         final LinePath b = LinePath.builder(TEST_PRECISION)
    153                 .appendVertices(Vector2D.of(0, 1), Vector2D.of(-1, 0), Vector2D.of(-0.5, 0))
    154                 .close();
    155
    156         final LinePath c = LinePath.builder(TEST_PRECISION)
    157                 .appendVertices(Vector2D.of(1, 3), Vector2D.of(0, 2), Vector2D.of(1, 2))
    158                 .close();
    159
    160         final List<LineConvexSubset> segments = new ArrayList<>();
    161         segments.addAll(a.getElements());
    162         segments.addAll(b.getElements());
    163         segments.addAll(c.getElements());
    164
    165         shuffle(segments);
    166
    167         // act
    168         final List<LinePath> paths = connector.connectAll(segments);
    169
    170         // assert
    171         Assert.assertEquals(3, paths.size());
    172
    173         assertFinitePath(paths.get(0),
    174                 Vector2D.of(-1, 0), Vector2D.of(-0.5, 0), Vector2D.of(0, 1), Vector2D.of(-1, 0));
    175
    176         assertFinitePath(paths.get(1),
    177                 Vector2D.ZERO, Vector2D.of(1, 0), Vector2D.of(1, 1), Vector2D.ZERO);
    178
    179         assertFinitePath(paths.get(2),
    180                 Vector2D.of(0, 2), Vector2D.of(1, 2), Vector2D.of(1, 3), Vector2D.of(0, 2));
    181     }
    182
    183     @Test
    184     public void testConnectAll_singleOpenPath() {
    185         // arrange
    186         final LinePath input = LinePath.builder(TEST_PRECISION)
    187                 .appendVertices(Vector2D.of(1, 1), Vector2D.ZERO, Vector2D.of(1, 0))
    188                 .build();
    189
    190         final List<LineConvexSubset> segments = new ArrayList<>(input.getElements());
    191         shuffle(segments);
    192
    193         // act
    194         final List<LinePath> paths = connector.connectAll(segments);
    195
    196         // assert
    197         Assert.assertEquals(1, paths.size());
    198
    199         assertFinitePath(paths.get(0),
    200                 Vector2D.of(1, 1), Vector2D.ZERO, Vector2D.of(1, 0));
    201     }
    202
    203     @Test
    204     public void testConnectAll_mixOfOpenConnectedAndInfinite() {
    205         // arrange
    206         final LineConvexSubset inputYInf = Y_AXIS.reverseRayTo(Vector2D.ZERO);
    207         final LineConvexSubset inputXInf = Lines.fromPoints(Vector2D.ZERO, Vector2D.Unit.MINUS_X, TEST_PRECISION)
    208                 .rayFrom(Vector2D.ZERO);
    209
    210         final LinePath closedPath = LinePath.builder(TEST_PRECISION)
    211                 .appendVertices(Vector2D.of(0, 2), Vector2D.of(1, 2), Vector2D.of(1, 3))
    212                 .close();
    213
    214         final LinePath openPath = LinePath.builder(TEST_PRECISION)
    215                 .appendVertices(Vector2D.of(-1, 3), Vector2D.of(0, 1), Vector2D.of(1, 1))
    216                 .build();
    217
    218         final List<LineConvexSubset> segments = new ArrayList<>();
    219         segments.add(inputYInf);
    220         segments.add(inputXInf);
    221         segments.addAll(closedPath.getElements());
    222         segments.addAll(openPath.getElements());
    223
    224         shuffle(segments);
    225
    226         // act
    227         final List<LinePath> paths = connector.connectAll(segments);
    228
    229         // assert
    230         Assert.assertEquals(3, paths.size());
    231
    232         assertFinitePath(paths.get(0),
    233                 Vector2D.of(-1, 3), Vector2D.of(0, 1), Vector2D.of(1, 1));
    234
    235         final LinePath infPath = paths.get(1);
    236         Assert.assertTrue(infPath.isInfinite());
    237         Assert.assertEquals(2, infPath.getElements().size());
    238         Assert.assertSame(inputYInf, infPath.getElements().get(0));
    239         Assert.assertSame(inputXInf, infPath.getElements().get(1));
    240
    241         assertFinitePath(paths.get(2),
    242                 Vector2D.of(0, 2), Vector2D.of(1, 2), Vector2D.of(1, 3), Vector2D.of(0, 2));
    243     }
    244
    245     @Test
    246     public void testConnectAll_pathWithSinglePoint() {
    247         // arrange
    248         final Vector2D p0 = Vector2D.ZERO;
    249
    250         final List<LineConvexSubset> segments = Collections.singletonList(Lines.fromPointAndAngle(p0, 0, TEST_PRECISION).segment(p0, p0));
    251
    252         // act
    253         final List<LinePath> paths = connector.connectAll(segments);
    254
    255         // assert
    256         Assert.assertEquals(1, paths.size());
    257
    258         assertFinitePath(paths.get(0), p0, p0);
    259     }
    260
    261     @Test
    262     public void testConnectAll_pathWithPointLikeConnectedSegments() {
    263         // arrange
    264         final Vector2D p0 = Vector2D.ZERO;
    265         final Vector2D p1 = Vector2D.of(1, 0);
    266         final Vector2D p2 = Vector2D.of(1, 1);
    267
    268         final Vector2D almostP0 = Vector2D.of(-1e-20, -1e-20);
    269         final Vector2D almostP1 = Vector2D.of(1 - 1e-15, 0);
    270
    271         final LinePath input = LinePath.builder(TEST_PRECISION)
    272                 .appendVertices(p0, p1)
    273                 .append(Lines.fromPointAndAngle(p1, 0.25 * PlaneAngleRadians.PI, TEST_PRECISION).segment(p1, p1))
    274                 .append(Lines.fromPointAndAngle(p1, -0.25 * PlaneAngleRadians.PI, TEST_PRECISION).segment(almostP1, almostP1))
    275                 .append(p2)
    276                 .append(p0)
    277                 .append(Lines.fromPointAndAngle(Vector2D.ZERO, -PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION)
    278                         .segment(almostP0, almostP0))
    279                 .build();
    280
    281         final List<LineConvexSubset> segments = new ArrayList<>(input.getElements());
    282         shuffle(segments);
    283
    284         // act
    285         final List<LinePath> paths = connector.connectAll(segments);
    286
    287         // assert
    288         Assert.assertEquals(1, paths.size());
    289
    290         assertFinitePath(paths.get(0), p0, p1, almostP1, p1, p2, p0, almostP0);
    291     }
    292
    293     @Test
    294     public void testConnectAll_flatLineRegion() {
    295         // arrange
    296         final Vector2D p0 = Vector2D.ZERO;
    297         final Vector2D p1 = Vector2D.of(1, 0);
    298
    299         final Segment seg0 = Lines.segmentFromPoints(p0, p1, TEST_PRECISION);
    300         final Segment seg1 = Lines.segmentFromPoints(p1, p0, TEST_PRECISION);
    301         final LineConvexSubset seg2 = Lines.fromPointAndAngle(p1, PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION).segment(p1, p1);
    302         final LineConvexSubset seg3 = Lines.fromPointAndAngle(p0, -PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION).segment(p0, p0);
    303
    304         final List<LineConvexSubset> segments = new ArrayList<>(Arrays.asList(seg0, seg1, seg2, seg3));
    305         shuffle(segments);
    306
    307         // act
    308         final List<LinePath> paths = connector.connectAll(segments);
    309
    310         // assert
    311         Assert.assertEquals(1, paths.size());
    312
    313         final LinePath path = paths.get(0);
    314         Assert.assertSame(seg0, path.getElements().get(0));
    315         Assert.assertSame(seg2, path.getElements().get(1));
    316         Assert.assertSame(seg1, path.getElements().get(2));
    317         Assert.assertSame(seg3, path.getElements().get(3));
    318     }
    319
    320     @Test
    321     public void testConnectAll_singlePointRegion() {
    322         // arrange
    323         final Vector2D p0 = Vector2D.of(1, 0);
    324
    325         final LineConvexSubset seg0 = Lines.fromPointAndAngle(p0, 0.0, TEST_PRECISION).segment(p0, p0);
    326         final LineConvexSubset seg1 = Lines.fromPointAndAngle(p0, PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION).segment(p0, p0);
    327         final LineConvexSubset seg2 = Lines.fromPointAndAngle(p0, PlaneAngleRadians.PI, TEST_PRECISION).segment(p0, p0);
    328         final LineConvexSubset seg3 = Lines.fromPointAndAngle(p0, -PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION).segment(p0, p0);
    329
    330         final List<LineConvexSubset> segments = new ArrayList<>(Arrays.asList(seg0, seg1, seg2, seg3));
    331         shuffle(segments);
    332
    333         // act
    334         final List<LinePath> paths = connector.connectAll(segments);
    335
    336         // assert
    337         Assert.assertEquals(1, paths.size());
    338
    339         final LinePath path = paths.get(0);
    340         Assert.assertSame(seg2, path.getElements().get(0));
    341         Assert.assertSame(seg3, path.getElements().get(1));
    342         Assert.assertSame(seg0, path.getElements().get(2));
    343         Assert.assertSame(seg1, path.getElements().get(3));
    344     }
    345
    346     @Test
    347     public void testConnectAll_pathWithPointLikeUnconnectedSegments() {
    348         // arrange
    349         final Vector2D p0 = Vector2D.ZERO;
    350         final Vector2D p1 = Vector2D.of(1, 0);
    351
    352         final LineConvexSubset seg0 = Lines.fromPointAndAngle(p1, 0.0, TEST_PRECISION).segment(p1, p1);
    353         final LineConvexSubset seg1 = Lines.fromPointAndAngle(p1, 0.25 * PlaneAngleRadians.PI, TEST_PRECISION).segment(p1, p1);
    354         final LineConvexSubset seg2 = Lines.fromPointAndAngle(p0, 0, TEST_PRECISION).segment(p0, p0);
    355
    356         final List<LineConvexSubset> segments = new ArrayList<>(Arrays.asList(seg0, seg1, seg2));
    357
    358         shuffle(segments);
    359
    360         // act
    361         final List<LinePath> paths = connector.connectAll(segments);
    362
    363         // assert
    364         Assert.assertEquals(2, paths.size());
    365
    366         final LinePath path0 = paths.get(0);
    367         Assert.assertEquals(1, path0.getElements().size());
    368         Assert.assertSame(seg2, path0.getElements().get(0));
    369
    370         final LinePath path1 = paths.get(1);
    371         Assert.assertEquals(2, path1.getElements().size());
    372         Assert.assertSame(seg0, path1.getElements().get(0));
    373         Assert.assertSame(seg1, path1.getElements().get(1));
    374     }
    375
    376     @Test
    377     public void testConnectAll_pathStartingWithPoint() {
    378         // arrange
    379         final Vector2D p0 = Vector2D.ZERO;
    380         final Vector2D p1 = Vector2D.of(1, 0);
    381         final Vector2D p2 = Vector2D.of(1, 1);
    382
    383         final LineConvexSubset seg0 = Lines.fromPointAndAngle(p0, PlaneAngleRadians.PI, TEST_PRECISION).segment(p0, p0);
    384         final LineConvexSubset seg1 = Lines.segmentFromPoints(p0, p1, TEST_PRECISION);
    385         final LineConvexSubset seg2 = Lines.segmentFromPoints(p1, p2, TEST_PRECISION);
    386
    387         final List<LineConvexSubset> segments = new ArrayList<>(Arrays.asList(seg0, seg1, seg2));
    388
    389         shuffle(segments);
    390
    391         // act
    392         final List<LinePath> paths = connector.connectAll(segments);
    393
    394         // assert
    395         Assert.assertEquals(1, paths.size());
    396
    397         final LinePath path = paths.get(0);
    398         Assert.assertSame(seg0, path.getElements().get(0));
    399         Assert.assertSame(seg1, path.getElements().get(1));
    400         Assert.assertSame(seg2, path.getElements().get(2));
    401     }
    402
    403     @Test
    404     public void testConnectAll_intersectingPaths() {
    405         // arrange
    406         final LinePath a = LinePath.builder(TEST_PRECISION)
    407                 .appendVertices(Vector2D.of(-1, 1), Vector2D.of(0.5, 0), Vector2D.of(-1, -1))
    408                 .build();
    409
    410         final LinePath b = LinePath.builder(TEST_PRECISION)
    411                 .appendVertices(Vector2D.of(1, 1), Vector2D.of(-0.5, 0), Vector2D.of(1, -1))
    412                 .build();
    413
    414         final List<LineConvexSubset> segments = new ArrayList<>();
    415         segments.addAll(a.getElements());
    416         segments.addAll(b.getElements());
    417
    418         shuffle(segments);
    419
    420         // act
    421         final List<LinePath> paths = connector.connectAll(segments);
    422
    423         // assert
    424         Assert.assertEquals(2, paths.size());
    425
    426         assertFinitePath(paths.get(0),
    427                 Vector2D.of(-1, 1), Vector2D.of(0.5, 0), Vector2D.of(-1, -1));
    428
    429         assertFinitePath(paths.get(1),
    430                 Vector2D.of(1, 1), Vector2D.of(-0.5, 0), Vector2D.of(1, -1));
    431     }
    432
    433     @Test
    434     public void testInstancesCanBeReused() {
    435         // arrange
    436         final LineConvexSubset a = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
    437         final LineConvexSubset b = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.Unit.PLUS_Y, TEST_PRECISION);
    438
    439         // act
    440         final List<LinePath> firstPaths = connector.connectAll(Collections.singletonList(a));
    441         final List<LinePath> secondPaths = connector.connectAll(Collections.singletonList(b));
    442
    443         // assert
    444         Assert.assertEquals(1, firstPaths.size());
    445         Assert.assertEquals(1, secondPaths.size());
    446
    447         Assert.assertSame(a, firstPaths.get(0).getElements().get(0));
    448         Assert.assertSame(b, secondPaths.get(0).getElements().get(0));
    449     }
    450
    451     @Test
    452     public void testAdd() {
    453         // arrange
    454         final LineConvexSubset a = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
    455         final LineConvexSubset b = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 1), TEST_PRECISION);
    456         final LineConvexSubset c = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(2, 0), TEST_PRECISION);
    457
    458         // act
    459         connector.add(Arrays.asList(a, b));
    460         connector.add(Collections.singletonList(c));
    461
    462         final List<LinePath> paths = connector.connectAll();
    463
    464         // assert
    465         Assert.assertEquals(2, paths.size());
    466
    467         assertFinitePath(paths.get(0), Vector2D.ZERO, Vector2D.Unit.PLUS_X, Vector2D.of(2, 0));
    468         assertFinitePath(paths.get(1), Vector2D.Unit.PLUS_X, Vector2D.of(1, 1));
    469     }
    470
    471     @Test
    472     public void testConnect() {
    473         // arrange
    474         final LineConvexSubset a = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
    475         final LineConvexSubset b = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 1), TEST_PRECISION);
    476         final LineConvexSubset c = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(2, 0), TEST_PRECISION);
    477
    478         // act
    479         connector.connect(Arrays.asList(a, b));
    480         connector.connect(Collections.singletonList(c));
    481
    482         final List<LinePath> paths = connector.connectAll();
    483
    484         // assert
    485         Assert.assertEquals(2, paths.size());
    486
    487         assertFinitePath(paths.get(0), Vector2D.ZERO, Vector2D.Unit.PLUS_X, Vector2D.of(1, 1));
    488         assertFinitePath(paths.get(1), Vector2D.Unit.PLUS_X, Vector2D.of(2, 0));
    489     }
    490
    491     @Test
    492     public void testConnectableSegment_hashCode() {
    493         // arrange
    494         final LineConvexSubset segA = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
    495         final LineConvexSubset segB = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 1), TEST_PRECISION);
    496
    497         final ConnectableLineSubset a = new ConnectableLineSubset(segA);
    498
    499         // act
    500         final int hash = a.hashCode();
    501
    502         // assert
    503         Assert.assertEquals(hash, a.hashCode());
    504
    505         Assert.assertNotEquals(hash, new ConnectableLineSubset(segB).hashCode());
    506         Assert.assertNotEquals(hash, new ConnectableLineSubset(Vector2D.Unit.PLUS_X).hashCode());
    507
    508         Assert.assertEquals(hash, new ConnectableLineSubset(segA).hashCode());
    509     }
    510
    511     @Test
    512     public void testConnectableSegment_equals() {
    513         // arrange
    514         final LineConvexSubset segA = Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
    515         final LineConvexSubset segB = Lines.segmentFromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 1), TEST_PRECISION);
    516
    517         final ConnectableLineSubset a = new ConnectableLineSubset(segA);
    518
    519         // act/assert
    520         Assert.assertEquals(a, a);
    521
    522         Assert.assertFalse(a.equals(null));
    523         Assert.assertFalse(a.equals(new Object()));
    524
    525         Assert.assertNotEquals(a, new ConnectableLineSubset(segB));
    526         Assert.assertNotEquals(a, new ConnectableLineSubset(Vector2D.Unit.PLUS_X));
    527
    528         Assert.assertEquals(a, new ConnectableLineSubset(segA));
    529     }
    530
    531     private static List<LineConvexSubset> shuffle(final List<LineConvexSubset> segments) {
    532         return shuffle(segments, 1);
    533     }
    534
    535     private static List<LineConvexSubset> shuffle(final List<LineConvexSubset> segments, final int seed) {
    536         Collections.shuffle(segments, new Random(seed));
    537
    538         return segments;
    539     }
    540
    541     private static void assertFinitePath(final LinePath path, final Vector2D... vertices) {
    542         Assert.assertFalse(path.isInfinite());
    543         Assert.assertTrue(path.isFinite());
    544
    545         assertPathVertices(path, vertices);
    546     }
    547
    548     private static void assertPathVertices(final LinePath path, final Vector2D... vertices) {
    549         final List<Vector2D> expectedVertices = Arrays.asList(vertices);
    550         final List<Vector2D> actualVertices = path.getVertexSequence();
    551
    552         final String msg = "Expected path vertices to equal " + expectedVertices + " but was " + actualVertices;
    553         Assert.assertEquals(msg, expectedVertices.size(), actualVertices.size());
    554
    555         for (int i = 0; i < expectedVertices.size(); ++i) {
    556             EuclideanTestUtils.assertCoordinatesEqual(expectedVertices.get(i), actualVertices.get(i), TEST_EPS);
    557         }
    558     }
    559
    560     private static class TestConnector extends AbstractLinePathConnector {
    561
    562         @Override
    563         protected ConnectableLineSubset selectConnection(final ConnectableLineSubset incoming, final List<ConnectableLineSubset> outgoing) {
    564             // just choose the first element
    565             return outgoing.get(0);
    566         }
    567     }
    568 }