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.spherical.twod;
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.function.Consumer;
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.spherical.SphericalTestUtils;
28  import org.apache.commons.geometry.spherical.twod.InteriorAngleGreatArcConnector.Maximize;
29  import org.apache.commons.geometry.spherical.twod.InteriorAngleGreatArcConnector.Minimize;
30  import org.junit.Assert;
31  import org.junit.Test;
32  
33  public class InteriorAngleGreatArcConnectorTest {
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      @Test
41      public void testConnectAll_empty() {
42          runWithMaxAndMin(connector -> {
43              // arrange
44              final List<GreatArc> arcs = new ArrayList<>();
45              connector.add(arcs);
46  
47              // act
48              final List<GreatArcPath> paths = connector.connectAll();
49  
50              // assert
51              Assert.assertEquals(0, paths.size());
52          });
53      }
54  
55      @Test
56      public void testConnectAll_singlePath() {
57          runWithMaxAndMin(connector -> {
58              // arrange
59              final List<GreatArc> arcs = Collections.singletonList(
60                      GreatCircles.arcFromPoints(Point2S.PLUS_I, Point2S.PLUS_J, TEST_PRECISION)
61              );
62              connector.add(arcs);
63  
64              // act
65              final List<GreatArcPath> paths = connector.connectAll();
66  
67              // assert
68              Assert.assertEquals(1, paths.size());
69  
70              final GreatArcPath a = paths.get(0);
71              Assert.assertEquals(1, a.getArcs().size());
72              assertPathPoints(a, Point2S.PLUS_I, Point2S.PLUS_J);
73          });
74      }
75  
76      @Test
77      public void testConnectAll_maximize_instance() {
78          // arrange
79          final GreatArc a1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.PLUS_I, TEST_PRECISION);
80          final GreatArc a2 = GreatCircles.arcFromPoints(Point2S.PLUS_I, Point2S.PLUS_J, TEST_PRECISION);
81          final GreatArc a3 = GreatCircles.arcFromPoints(Point2S.PLUS_J, Point2S.PLUS_K, TEST_PRECISION);
82  
83          final GreatArc b1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.MINUS_I, TEST_PRECISION);
84          final GreatArc b2 = GreatCircles.arcFromPoints(Point2S.MINUS_I, Point2S.MINUS_J, TEST_PRECISION);
85          final GreatArc b3 = GreatCircles.arcFromPoints(Point2S.MINUS_J, Point2S.PLUS_K, TEST_PRECISION);
86  
87          final InteriorAngleGreatArcConnector connector = new InteriorAngleGreatArcConnector.Maximize();
88  
89          // act
90          final List<GreatArcPath> paths = connector.connectAll(Arrays.asList(b3, b1, a1, a3, b2, a2));
91  
92          // assert
93          Assert.assertEquals(1, paths.size());
94  
95          assertPathPoints(paths.get(0),
96              Point2S.PLUS_K,
97              Point2S.MINUS_I,
98              Point2S.MINUS_J,
99              Point2S.PLUS_K,
100             Point2S.PLUS_I,
101             Point2S.PLUS_J,
102             Point2S.PLUS_K
103         );
104     }
105 
106     @Test
107     public void testConnectAll_maximize_method() {
108         // arrange
109         final GreatArc a1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.PLUS_I, TEST_PRECISION);
110         final GreatArc a2 = GreatCircles.arcFromPoints(Point2S.PLUS_I, Point2S.PLUS_J, TEST_PRECISION);
111         final GreatArc a3 = GreatCircles.arcFromPoints(Point2S.PLUS_J, Point2S.PLUS_K, TEST_PRECISION);
112 
113         final GreatArc b1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.MINUS_I, TEST_PRECISION);
114         final GreatArc b2 = GreatCircles.arcFromPoints(Point2S.MINUS_I, Point2S.MINUS_J, TEST_PRECISION);
115         final GreatArc b3 = GreatCircles.arcFromPoints(Point2S.MINUS_J, Point2S.PLUS_K, TEST_PRECISION);
116 
117         // act
118         final List<GreatArcPath> paths = InteriorAngleGreatArcConnector.connectMaximized(
119                 Arrays.asList(b3, b1, a1, a3, b2, a2));
120 
121         // assert
122         Assert.assertEquals(1, paths.size());
123 
124         assertPathPoints(paths.get(0),
125             Point2S.PLUS_K,
126             Point2S.MINUS_I,
127             Point2S.MINUS_J,
128             Point2S.PLUS_K,
129             Point2S.PLUS_I,
130             Point2S.PLUS_J,
131             Point2S.PLUS_K
132         );
133     }
134 
135     @Test
136     public void testConnectAll_minimize_instance() {
137         // arrange
138         final GreatArc a1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.PLUS_I, TEST_PRECISION);
139         final GreatArc a2 = GreatCircles.arcFromPoints(Point2S.PLUS_I, Point2S.PLUS_J, TEST_PRECISION);
140         final GreatArc a3 = GreatCircles.arcFromPoints(Point2S.PLUS_J, Point2S.PLUS_K, TEST_PRECISION);
141 
142         final GreatArc b1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.MINUS_I, TEST_PRECISION);
143         final GreatArc b2 = GreatCircles.arcFromPoints(Point2S.MINUS_I, Point2S.MINUS_J, TEST_PRECISION);
144         final GreatArc b3 = GreatCircles.arcFromPoints(Point2S.MINUS_J, Point2S.PLUS_K, TEST_PRECISION);
145 
146         final InteriorAngleGreatArcConnector connector = new InteriorAngleGreatArcConnector.Minimize();
147 
148         // act
149         final List<GreatArcPath> paths = connector.connectAll(Arrays.asList(b3, b1, a1, a3, b2, a2));
150 
151         // assert
152         Assert.assertEquals(2, paths.size());
153 
154         assertPathPoints(paths.get(0),
155             Point2S.PLUS_K,
156             Point2S.MINUS_I,
157             Point2S.MINUS_J,
158             Point2S.PLUS_K
159         );
160 
161         assertPathPoints(paths.get(1),
162             Point2S.PLUS_K,
163             Point2S.PLUS_I,
164             Point2S.PLUS_J,
165             Point2S.PLUS_K
166         );
167     }
168 
169     @Test
170     public void testConnectAll_minimize_method() {
171         // arrange
172         final GreatArc a1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.PLUS_I, TEST_PRECISION);
173         final GreatArc a2 = GreatCircles.arcFromPoints(Point2S.PLUS_I, Point2S.PLUS_J, TEST_PRECISION);
174         final GreatArc a3 = GreatCircles.arcFromPoints(Point2S.PLUS_J, Point2S.PLUS_K, TEST_PRECISION);
175 
176         final GreatArc b1 = GreatCircles.arcFromPoints(Point2S.PLUS_K, Point2S.MINUS_I, TEST_PRECISION);
177         final GreatArc b2 = GreatCircles.arcFromPoints(Point2S.MINUS_I, Point2S.MINUS_J, TEST_PRECISION);
178         final GreatArc b3 = GreatCircles.arcFromPoints(Point2S.MINUS_J, Point2S.PLUS_K, TEST_PRECISION);
179 
180         // act
181         final List<GreatArcPath> paths = InteriorAngleGreatArcConnector.connectMinimized(
182                 Arrays.asList(b3, b1, a1, a3, b2, a2));
183 
184         // assert
185         Assert.assertEquals(2, paths.size());
186 
187         assertPathPoints(paths.get(0),
188             Point2S.PLUS_K,
189             Point2S.MINUS_I,
190             Point2S.MINUS_J,
191             Point2S.PLUS_K
192         );
193 
194         assertPathPoints(paths.get(1),
195             Point2S.PLUS_K,
196             Point2S.PLUS_I,
197             Point2S.PLUS_J,
198             Point2S.PLUS_K
199         );
200     }
201 
202     /**
203      * Run the given consumer function twice, once with a Maximize instance and once with
204      * a Minimize instance.
205      */
206     private static void runWithMaxAndMin(final Consumer<InteriorAngleGreatArcConnector> body) {
207         body.accept(new Maximize());
208         body.accept(new Minimize());
209     }
210 
211     private static void assertPathPoints(final GreatArcPath path, final Point2S... points) {
212         final List<Point2S> expectedPoints = Arrays.asList(points);
213         final List<Point2S> actualPoints = path.getVertices();
214 
215         final String msg = "Expected path points to equal " + expectedPoints + " but was " + actualPoints;
216         Assert.assertEquals(msg, expectedPoints.size(), actualPoints.size());
217 
218         for (int i = 0; i < expectedPoints.size(); ++i) {
219             SphericalTestUtils.assertPointsEq(expectedPoints.get(i), actualPoints.get(i), TEST_EPS);
220         }
221     }
222 }