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.core.partitioning.bsp;
18  
19  
20  import java.util.Arrays;
21  import java.util.Collections;
22  import java.util.List;
23  
24  import org.apache.commons.geometry.core.GeometryTestUtils;
25  import org.apache.commons.geometry.core.partitioning.HyperplaneConvexSubset;
26  import org.apache.commons.geometry.core.partitioning.test.PartitionTestUtils;
27  import org.apache.commons.geometry.core.partitioning.test.TestLine;
28  import org.apache.commons.geometry.core.partitioning.test.TestLineSegment;
29  import org.apache.commons.geometry.core.partitioning.test.TestPoint2D;
30  import org.junit.jupiter.api.Assertions;
31  import org.junit.jupiter.api.Test;
32  
33  class RegionCutBoundaryTest {
34  
35      private static final double TEST_EPS = 1e-10;
36  
37      @Test
38      void testProperties() {
39          // arrange
40          final List<HyperplaneConvexSubset<TestPoint2D>> insideFacing =
41                  Collections.singletonList(new TestLineSegment(TestPoint2D.ZERO, new TestPoint2D(1, 0)));
42          final List<HyperplaneConvexSubset<TestPoint2D>> outsideFacing =
43                  Collections.singletonList(new TestLineSegment(new TestPoint2D(-1, 0), TestPoint2D.ZERO));
44  
45          // act
46          final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(insideFacing, outsideFacing);
47  
48          // assert
49          Assertions.assertNotSame(insideFacing, boundary.getInsideFacing());
50          Assertions.assertEquals(insideFacing, boundary.getInsideFacing());
51  
52          Assertions.assertNotSame(outsideFacing, boundary.getOutsideFacing());
53          Assertions.assertEquals(outsideFacing, boundary.getOutsideFacing());
54      }
55  
56      @Test
57      void testProperties_nullLists() {
58          // act
59          final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(null, null);
60  
61          // assert
62          Assertions.assertEquals(0, boundary.getInsideFacing().size());
63          Assertions.assertEquals(0, boundary.getOutsideFacing().size());
64      }
65  
66      @Test
67      void testGetSize_noSize() {
68          // act
69          final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(null, null);
70  
71          // assert
72          Assertions.assertEquals(0, boundary.getSize(), TEST_EPS);
73      }
74  
75      @Test
76      void testGetSize_infinite() {
77          // act
78          final TestLine line = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 0));
79          final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(
80                  Collections.singletonList(new TestLineSegment(1, Double.POSITIVE_INFINITY, line)),
81                  Collections.singletonList(new TestLineSegment(Double.NEGATIVE_INFINITY, -1, line)));
82  
83          // assert
84          GeometryTestUtils.assertPositiveInfinity(boundary.getSize());
85      }
86  
87      @Test
88      void testGetSize_finite() {
89          // act
90          final TestLine line = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 0));
91          final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(
92                  Arrays.asList(new TestLineSegment(1, 2, line), new TestLineSegment(3, 4, line)),
93                  Collections.singletonList(new TestLineSegment(-3, -1, line)));
94  
95          // assert
96          Assertions.assertEquals(4, boundary.getSize(), TEST_EPS);
97      }
98  
99      @Test
100     void testClosest() {
101         // arrange
102         final TestPoint2D a = new TestPoint2D(-1, 0);
103         final TestPoint2D b = TestPoint2D.ZERO;
104         final TestPoint2D c = new TestPoint2D(1, 0);
105 
106         final TestLineSegment insideFacing = new TestLineSegment(a, b);
107         final TestLineSegment outsideFacing = new TestLineSegment(b, c);
108 
109         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(Collections.singletonList(insideFacing),
110                 Collections.singletonList(outsideFacing));
111 
112         // act/assert
113         PartitionTestUtils.assertPointsEqual(a, boundary.closest(new TestPoint2D(-2, 1)));
114         PartitionTestUtils.assertPointsEqual(new TestPoint2D(-0.5, 0), boundary.closest(new TestPoint2D(-0.5, -1)));
115         PartitionTestUtils.assertPointsEqual(b, boundary.closest(TestPoint2D.ZERO));
116         PartitionTestUtils.assertPointsEqual(b, boundary.closest(new TestPoint2D(0, 2)));
117         PartitionTestUtils.assertPointsEqual(new TestPoint2D(0.5, 0), boundary.closest(new TestPoint2D(0.5, 3)));
118         PartitionTestUtils.assertPointsEqual(c, boundary.closest(new TestPoint2D(1, -4)));
119         PartitionTestUtils.assertPointsEqual(c, boundary.closest(new TestPoint2D(3, -5)));
120     }
121 
122     @Test
123     void testClosest_nullInsideFacing() {
124         // arrange
125         final TestPoint2D a = new TestPoint2D(-1, 0);
126         final TestPoint2D b = TestPoint2D.ZERO;
127 
128         final TestLineSegment outsideFacing = new TestLineSegment(a, b);
129 
130         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(null, Collections.singletonList(outsideFacing));
131 
132         // act/assert
133         PartitionTestUtils.assertPointsEqual(a, boundary.closest(new TestPoint2D(-2, 1)));
134         PartitionTestUtils.assertPointsEqual(new TestPoint2D(-0.5, 0), boundary.closest(new TestPoint2D(-0.5, -1)));
135         PartitionTestUtils.assertPointsEqual(b, boundary.closest(TestPoint2D.ZERO));
136         PartitionTestUtils.assertPointsEqual(b, boundary.closest(new TestPoint2D(1, 2)));
137     }
138 
139     @Test
140     void testClosest_nullOutsideFacing() {
141         // arrange
142         final TestPoint2D a = new TestPoint2D(-1, 0);
143         final TestPoint2D b = TestPoint2D.ZERO;
144 
145         final TestLineSegment insideFacing = new TestLineSegment(a, b);
146 
147         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(Collections.singletonList(insideFacing), null);
148 
149         // act/assert
150         PartitionTestUtils.assertPointsEqual(a, boundary.closest(new TestPoint2D(-2, 1)));
151         PartitionTestUtils.assertPointsEqual(new TestPoint2D(-0.5, 0), boundary.closest(new TestPoint2D(-0.5, -1)));
152         PartitionTestUtils.assertPointsEqual(b, boundary.closest(TestPoint2D.ZERO));
153         PartitionTestUtils.assertPointsEqual(b, boundary.closest(new TestPoint2D(1, 2)));
154     }
155 
156     @Test
157     void testClosest_nullInsideAndOutsideFacing() {
158         // arrange
159         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(null, null);
160 
161         // act/assert
162         Assertions.assertNull(boundary.closest(TestPoint2D.ZERO));
163         Assertions.assertNull(boundary.closest(new TestPoint2D(1, 1)));
164     }
165 
166     @Test
167     void testContains() {
168         // arrange
169         final TestPoint2D a = new TestPoint2D(-1, 0);
170         final TestPoint2D b = TestPoint2D.ZERO;
171         final TestPoint2D c = new TestPoint2D(1, 0);
172 
173         final TestLineSegment insideFacing = new TestLineSegment(a, b);
174         final TestLineSegment outsideFacing = new TestLineSegment(b, c);
175 
176         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(Collections.singletonList(insideFacing),
177                 Collections.singletonList(outsideFacing));
178 
179         // act/assert
180         Assertions.assertFalse(boundary.contains(new TestPoint2D(-2, 0)));
181 
182         Assertions.assertTrue(boundary.contains(new TestPoint2D(-1, 0)));
183         Assertions.assertTrue(boundary.contains(new TestPoint2D(-0.5, 0)));
184         Assertions.assertTrue(boundary.contains(new TestPoint2D(0, 0)));
185         Assertions.assertTrue(boundary.contains(new TestPoint2D(0.5, 0)));
186         Assertions.assertTrue(boundary.contains(new TestPoint2D(1, 0)));
187 
188         Assertions.assertFalse(boundary.contains(new TestPoint2D(2, 0)));
189 
190         Assertions.assertFalse(boundary.contains(new TestPoint2D(-1, 1)));
191         Assertions.assertFalse(boundary.contains(new TestPoint2D(0, -1)));
192         Assertions.assertFalse(boundary.contains(new TestPoint2D(1, 1)));
193     }
194 
195     @Test
196     void testContains_nullHyperplaneSubsets() {
197         // arrange
198         final RegionCutBoundary<TestPoint2D> boundary = new RegionCutBoundary<>(null, null);
199 
200         // act/assert
201         Assertions.assertFalse(boundary.contains(new TestPoint2D(-1, 0)));
202         Assertions.assertFalse(boundary.contains(new TestPoint2D(0, 0)));
203         Assertions.assertFalse(boundary.contains(new TestPoint2D(1, 0)));
204     }
205 }