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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.geometry.euclidean.oned;
23  
24  import org.hipparchus.geometry.partitioning.BSPTree;
25  import org.hipparchus.geometry.partitioning.Region;
26  import org.hipparchus.geometry.partitioning.RegionFactory;
27  import org.hipparchus.util.FastMath;
28  import org.hipparchus.util.Precision;
29  import org.junit.jupiter.api.Test;
30  
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.List;
34  
35  import static org.junit.jupiter.api.Assertions.assertEquals;
36  import static org.junit.jupiter.api.Assertions.assertNull;
37  import static org.junit.jupiter.api.Assertions.assertSame;
38  import static org.junit.jupiter.api.Assertions.assertTrue;
39  import static org.junit.jupiter.api.Assertions.fail;
40  
41  class IntervalsSetTest {
42  
43      @Test
44      void testInterval() {
45          IntervalsSet set = new IntervalsSet(Arrays.asList(new OrientedPoint(new Vector1D(2.3), false, 1.0e-10).wholeHyperplane(),
46                                                            new OrientedPoint(new Vector1D(5.7), true, 1.0e-10).wholeHyperplane()),
47                                              1.0e-10);
48          assertEquals(3.4, set.getSize(), 1.0e-10);
49          assertEquals(4.0, set.getBarycenter().getX(), 1.0e-10);
50          assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(2.3)));
51          assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(5.7)));
52          assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(1.2)));
53          assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(8.7)));
54          assertEquals(Region.Location.INSIDE,   set.checkPoint(new Vector1D(3.0)));
55          assertEquals(2.3, set.getInf(), 1.0e-10);
56          assertEquals(5.7, set.getSup(), 1.0e-10);
57          assertEquals(Region.Location.INSIDE, set.checkPoint(set.getInteriorPoint()));
58  
59          OrientedPoint op = set.getTree(false).getCut().getHyperplane();
60          assertEquals(0.0, op.emptyHyperplane().getSize(), 1.0e-10);
61          assertEquals(1.0e-10, op.getTolerance(), 1.0e-20);
62          assertTrue(Double.isInfinite(op.wholeSpace().getSize()));
63          assertEquals(2.3, op.getLocation().getX(), 1.0e-10);
64          assertEquals(-0.7, op.getOffset(new Vector1D(3.0)), 1.0e-10);
65          assertSame(op.getLocation(), op.project(new Vector1D(3.0)));
66  
67          // beware that after changing point orientation, we completely mess up interval tree
68          // so we cannot use it anymore
69          op.revertSelf();
70          assertEquals(+0.7, op.getOffset(new Vector1D(3.0)), 1.0e-10);
71  
72      }
73  
74      @Test
75      void testNoBoundaries() {
76          IntervalsSet set = new IntervalsSet(new ArrayList<>(), 1.0e-10);
77          assertEquals(Region.Location.INSIDE, set.checkPoint(new Vector1D(-Double.MAX_VALUE)));
78          assertEquals(Region.Location.INSIDE, set.checkPoint(new Vector1D(+Double.MAX_VALUE)));
79          assertTrue(Double.isInfinite(set.getSize()));
80          assertEquals(Region.Location.INSIDE, set.checkPoint(set.getInteriorPoint()));
81      }
82  
83      @Test
84      void testInfinite() {
85          IntervalsSet set = new IntervalsSet(9.0, Double.POSITIVE_INFINITY, 1.0e-10);
86          assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(9.0)));
87          assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(8.4)));
88          for (double e = 1.0; e <= 6.0; e += 1.0) {
89              assertEquals(Region.Location.INSIDE,
90                                  set.checkPoint(new Vector1D(FastMath.pow(10.0, e))));
91          }
92          assertTrue(Double.isInfinite(set.getSize()));
93          assertEquals(9.0, set.getInf(), 1.0e-10);
94          assertTrue(Double.isInfinite(set.getSup()));
95  
96          set = (IntervalsSet) new RegionFactory<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint>().getComplement(set);
97          assertEquals(9.0, set.getSup(), 1.0e-10);
98          assertTrue(Double.isInfinite(set.getInf()));
99          assertEquals(Region.Location.INSIDE, set.checkPoint(set.getInteriorPoint()));
100     }
101 
102     @Test
103     void testMultiple() {
104         RegionFactory<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint> factory = new RegionFactory<>();
105         IntervalsSet set = (IntervalsSet) factory.intersection(factory.union(factory.difference(new IntervalsSet(1.0, 6.0, 1.0e-10),
106                                                                                                 new IntervalsSet(3.0, 5.0, 1.0e-10)),
107                                                                              new IntervalsSet(9.0, Double.POSITIVE_INFINITY, 1.0e-10)),
108                                                                new IntervalsSet(Double.NEGATIVE_INFINITY, 11.0, 1.0e-10));
109         assertEquals(5.0, set.getSize(), 1.0e-10);
110         assertEquals(5.9, set.getBarycenter().getX(), 1.0e-10);
111         assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(0.0)));
112         assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(4.0)));
113         assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(8.0)));
114         assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new Vector1D(12.0)));
115         assertEquals(Region.Location.INSIDE,   set.checkPoint(new Vector1D(1.2)));
116         assertEquals(Region.Location.INSIDE,   set.checkPoint(new Vector1D(5.9)));
117         assertEquals(Region.Location.INSIDE,   set.checkPoint(new Vector1D(9.01)));
118         assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(5.0)));
119         assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(11.0)));
120         assertEquals( 1.0, set.getInf(), 1.0e-10);
121         assertEquals(11.0, set.getSup(), 1.0e-10);
122 
123         List<Interval> list = set.asList();
124         assertEquals(3, list.size());
125         assertEquals( 1.0, list.get(0).getInf(), 1.0e-10);
126         assertEquals( 3.0, list.get(0).getSup(), 1.0e-10);
127         assertEquals( 5.0, list.get(1).getInf(), 1.0e-10);
128         assertEquals( 6.0, list.get(1).getSup(), 1.0e-10);
129         assertEquals( 9.0, list.get(2).getInf(), 1.0e-10);
130         assertEquals(11.0, list.get(2).getSup(), 1.0e-10);
131 
132         assertEquals(Region.Location.INSIDE, set.checkPoint(set.getInteriorPoint()));
133 
134     }
135 
136     @Test
137     void testInteriorPoint() {
138 
139         final IntervalsSet wholeSpace = new IntervalsSet(1.0e-10);
140         final RegionFactory<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint> factory = new RegionFactory<>();
141         final Region<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint> empty = factory.getComplement(wholeSpace);
142         assertNull(empty.getInteriorPoint());
143 
144         final IntervalsSet is1 = new IntervalsSet(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0);
145         final Vector1D     v1  = is1.getInteriorPoint();
146         assertEquals(0.0, v1.getX(), 1.0e-10);
147         assertEquals(Region.Location.INSIDE, is1.checkPoint(v1));
148 
149         final IntervalsSet is2 = new IntervalsSet(Double.NEGATIVE_INFINITY, 100.0, 1.0);
150         final Vector1D     v2  = is2.getInteriorPoint();
151         assertEquals(-999999900.0, v2.getX(), 1.0e-10);
152         assertEquals(Region.Location.INSIDE, is2.checkPoint(v2));
153 
154         final IntervalsSet is3 = new IntervalsSet(-100.0, Double.POSITIVE_INFINITY, 1.0);
155         final Vector1D     v3  = is3.getInteriorPoint();
156         assertEquals(999999900.0, v3.getX(), 1.0e-10);
157         assertEquals(Region.Location.INSIDE, is3.checkPoint(v3));
158 
159         final IntervalsSet is4 = new IntervalsSet(11.0, 13.0, 1.0);
160         final Vector1D     v4  = is4.getInteriorPoint();
161         assertEquals(12.0, v4.getX(), 1.0e-10);
162         assertEquals(Region.Location.INSIDE, is4.checkPoint(v4));
163 
164         final IntervalsSet is5  = (IntervalsSet) factory.union(factory.union(new IntervalsSet(11.0, 13.0, 1.0),
165                                                                              new IntervalsSet( 9.0,  9.5, 1.0)),
166                                                                new IntervalsSet(100.0, 120.0, 1.0));
167         final Vector1D     v5  = is5.getInteriorPoint();
168         assertEquals(110.0, v5.getX(), 1.0e-10);
169         assertEquals(Region.Location.INSIDE, is5.checkPoint(v5));
170 
171     }
172 
173     @Test
174     void testSinglePoint() {
175         IntervalsSet set = new IntervalsSet(1.0, 1.0, 1.0e-10);
176         assertEquals(0.0, set.getSize(), Precision.SAFE_MIN);
177         assertEquals(1.0, set.getBarycenter().getX(), Precision.EPSILON);
178         try {
179             set.iterator().remove();
180             fail("an exception should have been thrown");
181         } catch (UnsupportedOperationException uoe) {
182             // expected
183         }
184     }
185 
186     @Test
187     void testShuffledTreeNonRepresentable() {
188         doTestShuffledTree(FastMath.toRadians( 85.0), FastMath.toRadians( 95.0),
189                            FastMath.toRadians(265.0), FastMath.toRadians(275.0),
190                            1.0e-10);
191     }
192 
193     @Test
194     void testShuffledTreeRepresentable() {
195         doTestShuffledTree(1.0, 2.0,
196                            4.0, 5.0,
197                            1.0e-10);
198     }
199 
200     private void doTestShuffledTree(final double a0, final double a1,
201                                     final double a2, final double a3,
202                                     final double tol) {
203 
204         // intervals set [ a0 ; a1 ] U [ a2 ; a3 ]
205         final IntervalsSet setA =
206                         new IntervalsSet(new BSPTree<>(new OrientedPoint(new Vector1D(a0), false, tol).wholeHyperplane(),
207                                                        new BSPTree<>(Boolean.FALSE),
208                                                        new BSPTree<>(new OrientedPoint(new Vector1D(a1), true, tol).wholeHyperplane(),
209                                                                      new BSPTree<>(new OrientedPoint(new Vector1D(a2), false, tol).wholeHyperplane(),
210                                                                                    new BSPTree<>(Boolean.FALSE),
211                                                                                    new BSPTree<>(new OrientedPoint(new Vector1D(a3), true, tol).wholeHyperplane(),
212                                                                                                  new BSPTree<>(Boolean.FALSE),
213                                                                                                  new BSPTree<>(Boolean.TRUE),
214                                                                                                  null),
215                                                                                    null),
216                                                                      new BSPTree<>(Boolean.TRUE),
217                                                                      null),
218                                                        null),
219                                          1.0e-10);
220         assertEquals((a1 - a0) + (a3 - a2), setA.getSize(), 1.0e-10);
221         assertEquals(2, setA.asList().size());
222         assertEquals(a0, setA.asList().get(0).getInf(), 1.0e-15);
223         assertEquals(a1, setA.asList().get(0).getSup(), 1.0e-15);
224         assertEquals(a2, setA.asList().get(1).getInf(), 1.0e-15);
225         assertEquals(a3, setA.asList().get(1).getSup(), 1.0e-15);
226 
227         // same intervals set [ a0 ; a1 ] U [ a2 ; a3 ], but with a different tree organization
228         final IntervalsSet setB =
229                         new IntervalsSet(new BSPTree<>(new OrientedPoint(new Vector1D(a2), false, tol).wholeHyperplane(),
230                                                        new BSPTree<>(new OrientedPoint(new Vector1D(a0), false, tol).wholeHyperplane(),
231                                                                      new BSPTree<>(Boolean.FALSE),
232                                                                      new BSPTree<>(new OrientedPoint(new Vector1D(a1), true, tol).wholeHyperplane(),
233                                                                                    new BSPTree<>(Boolean.FALSE),
234                                                                                    new BSPTree<>(Boolean.TRUE),
235                                                                                    null),
236                                                                      null),
237                                                        new BSPTree<>(new OrientedPoint(new Vector1D(a3), true, tol).wholeHyperplane(),
238                                                                      new BSPTree<>(Boolean.FALSE),
239                                                                      new BSPTree<>(Boolean.TRUE),
240                                                                      null),
241                                                        null),
242                                          1.0e-10);
243         assertEquals((a1 - a0) + (a3 - a2), setB.getSize(), 1.0e-10);
244         assertEquals(2, setB.asList().size());
245         assertEquals(a0, setB.asList().get(0).getInf(), 1.0e-15);
246         assertEquals(a1, setB.asList().get(0).getSup(), 1.0e-15);
247         assertEquals(a2, setB.asList().get(1).getInf(), 1.0e-15);
248         assertEquals(a3, setB.asList().get(1).getSup(), 1.0e-15);
249 
250         final IntervalsSet intersection = (IntervalsSet) new RegionFactory<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint>().
251                                           intersection(setA, setB);
252         assertEquals((a1 - a0) + (a3 - a2), intersection.getSize(), 1.0e-10);
253         assertEquals(2, intersection.asList().size());
254         assertEquals(a0, intersection.asList().get(0).getInf(), 1.0e-15);
255         assertEquals(a1, intersection.asList().get(0).getSup(), 1.0e-15);
256         assertEquals(a2, intersection.asList().get(1).getInf(), 1.0e-15);
257         assertEquals(a3, intersection.asList().get(1).getSup(), 1.0e-15);
258 
259     }
260 
261 }