• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2005 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.common.geometry;
17 
18 
19 public strictfp class S1IntervalTest extends GeometryTestCase {
20 
testIntervalOps(S1Interval x, S1Interval y, String expectedRelation, S1Interval expectedUnion, S1Interval expectedIntersection)21   private void testIntervalOps(S1Interval x, S1Interval y, String expectedRelation,
22       S1Interval expectedUnion, S1Interval expectedIntersection) {
23     // Test all of the interval operations on the given pair of intervals.
24     // "expected_relation" is a sequence of "T" and "F" characters corresponding
25     // to the expected results of Contains(), InteriorContains(), Intersects(),
26     // and InteriorIntersects() respectively.
27 
28     assertEquals(x.contains(y), expectedRelation.charAt(0) == 'T');
29     assertEquals(x.interiorContains(y), expectedRelation.charAt(1) == 'T');
30     assertEquals(x.intersects(y), expectedRelation.charAt(2) == 'T');
31     assertEquals(x.interiorIntersects(y), expectedRelation.charAt(3) == 'T');
32 
33     // bounds() returns a const reference to a member variable, so we need to
34     // make a copy when invoking it on a temporary object.
35     assertEquals(expectedUnion, x.union(y));
36     assertEquals(expectedIntersection, x.intersection(y));
37 
38     assertEquals(x.contains(y), x.union(y) == x);
39     assertEquals(x.intersects(y), !x.intersection(y).isEmpty());
40 
41     if (y.lo() == y.hi()) {
42       S1Interval r = x.addPoint(y.lo());
43       assertEquals(expectedUnion, r);
44     }
45   }
46 
testBasic()47   public void testBasic() {
48     // "Quadrants" are numbered as follows:
49     // quad1 == [0, Pi/2]
50     // quad2 == [Pi/2, Pi]
51     // quad3 == [-Pi, -Pi/2]
52     // quad4 == [-Pi/2, 0]
53 
54     // Constructors and accessors.
55     S1Interval quad12 = new S1Interval(0, -S2.M_PI);
56     assertEquals(quad12.lo(), 0.0);
57     assertEquals(quad12.hi(), S2.M_PI);
58     S1Interval quad34 = new S1Interval(-S2.M_PI, 0);
59     assertEquals(quad34.lo(), S2.M_PI);
60     assertEquals(quad34.hi(), 0.0);
61     S1Interval pi = new S1Interval(S2.M_PI, S2.M_PI);
62     assertEquals(pi.lo(), S2.M_PI);
63     assertEquals(pi.hi(), S2.M_PI);
64     S1Interval mipi = new S1Interval(-S2.M_PI, -S2.M_PI);
65     assertEquals(mipi.lo(), S2.M_PI);
66     assertEquals(mipi.hi(), S2.M_PI);
67     S1Interval quad23 = new S1Interval(S2.M_PI_2, -S2.M_PI_2); // inverted
68     assertEquals(quad23.lo(), S2.M_PI_2);
69     assertEquals(quad23.hi(), -S2.M_PI_2);
70     S1Interval quad1 = new S1Interval(0, S2.M_PI_2);
71 
72     // is_valid(), is_empty(), is_inverted()
73     S1Interval zero = new S1Interval(0, 0);
74     assertTrue(zero.isValid() && !zero.isEmpty() && !zero.isFull());
75     S1Interval empty = S1Interval.empty();
76     assertTrue(empty.isValid() && empty.isEmpty() && !empty.isFull());
77     assertTrue(empty.isInverted());
78     S1Interval full = S1Interval.full();
79     assertTrue(full.isValid() && !full.isEmpty() && full.isFull());
80     assertTrue(!quad12.isEmpty() && !quad12.isFull() && !quad12.isInverted());
81     assertTrue(!quad23.isEmpty() && !quad23.isFull() && quad23.isInverted());
82     assertTrue(pi.isValid() && !pi.isEmpty() && !pi.isInverted());
83     assertTrue(mipi.isValid() && !mipi.isEmpty() && !mipi.isInverted());
84 
85     // GetCenter(), GetLength()
86     assertEquals(quad12.getCenter(), S2.M_PI_2);
87     assertEquals(quad12.getLength(), S2.M_PI);
88     assertDoubleNear(new S1Interval(3.1, 2.9).getCenter(), 3.0 - S2.M_PI);
89     assertDoubleNear(new S1Interval(-2.9, -3.1).getCenter(), S2.M_PI - 3.0);
90     assertDoubleNear(new S1Interval(2.1, -2.1).getCenter(), S2.M_PI);
91     assertEquals(pi.getCenter(), S2.M_PI);
92     assertEquals(pi.getLength(), 0.0);
93     assertEquals(mipi.getCenter(), S2.M_PI);
94     assertEquals(mipi.getLength(), 0.0);
95     assertEquals(Math.abs(quad23.getCenter()), S2.M_PI);
96     assertEquals(Math.abs(quad23.getLength()), S2.M_PI);
97     S1Interval quad123 = new S1Interval(0, -S2.M_PI_2);
98     assertDoubleNear(quad123.getCenter(), 0.75 * S2.M_PI);
99     assertDoubleNear(quad123.getLength(), 1.5 * S2.M_PI);
100     assertTrue(empty.getLength() < 0);
101     assertEquals(full.getLength(), 2 * S2.M_PI);
102 
103     // Complement()
104     assertTrue(empty.complement().isFull());
105     assertTrue(full.complement().isEmpty());
106     assertTrue(pi.complement().isFull());
107     assertTrue(mipi.complement().isFull());
108     assertTrue(zero.complement().isFull());
109     assertTrue(quad12.complement().approxEquals(quad34));
110     assertTrue(quad34.complement().approxEquals(quad12));
111     S1Interval quad4 = new S1Interval(-S2.M_PI_2, 0);
112     assertTrue(quad123.complement().approxEquals(quad4));
113     S1Interval quad234 = new S1Interval(S2.M_PI_2, 0);
114 
115     // Contains(double), InteriorContains(double)
116     assertTrue(!empty.contains(0) && !empty.contains(S2.M_PI) && !empty.contains(-S2.M_PI));
117     assertTrue(!empty.interiorContains(S2.M_PI) && !empty.interiorContains(-S2.M_PI));
118     assertTrue(full.contains(0) && full.contains(S2.M_PI) && full.contains(-S2.M_PI));
119     assertTrue(full.interiorContains(S2.M_PI) && full.interiorContains(-S2.M_PI));
120     assertTrue(quad12.contains(0) && quad12.contains(S2.M_PI) && quad12.contains(-S2.M_PI));
121     assertTrue(quad12.interiorContains(S2.M_PI_2) && !quad12.interiorContains(0));
122     assertTrue(!quad12.interiorContains(S2.M_PI) && !quad12.interiorContains(-S2.M_PI));
123     assertTrue(quad23.contains(S2.M_PI_2) && quad23.contains(-S2.M_PI_2));
124     assertTrue(quad23.contains(S2.M_PI) && quad23.contains(-S2.M_PI));
125     assertTrue(!quad23.contains(0));
126     assertTrue(!quad23.interiorContains(S2.M_PI_2) && !quad23.interiorContains(-S2.M_PI_2));
127     assertTrue(quad23.interiorContains(S2.M_PI) && quad23.interiorContains(-S2.M_PI));
128     assertTrue(!quad23.interiorContains(0));
129     assertTrue(pi.contains(S2.M_PI) && pi.contains(-S2.M_PI) && !pi.contains(0));
130     assertTrue(!pi.interiorContains(S2.M_PI) && !pi.interiorContains(-S2.M_PI));
131     assertTrue(mipi.contains(S2.M_PI) && mipi.contains(-S2.M_PI) && !mipi.contains(0));
132     assertTrue(!mipi.interiorContains(S2.M_PI) && !mipi.interiorContains(-S2.M_PI));
133     assertTrue(zero.contains(0) && !zero.interiorContains(0));
134 
135     // Contains(S1Interval), InteriorContains(S1Interval),
136     // Intersects(), InteriorIntersects(), Union(), Intersection()
137     S1Interval quad2 = new S1Interval(S2.M_PI_2, -S2.M_PI);
138     S1Interval quad3 = new S1Interval(S2.M_PI, -S2.M_PI_2);
139     S1Interval pi2 = new S1Interval(S2.M_PI_2, S2.M_PI_2);
140     S1Interval mipi2 = new S1Interval(-S2.M_PI_2, -S2.M_PI_2);
141 
142     testIntervalOps(empty, empty, "TTFF", empty, empty);
143     testIntervalOps(empty, full, "FFFF", full, empty);
144     testIntervalOps(empty, zero, "FFFF", zero, empty);
145     testIntervalOps(empty, pi, "FFFF", pi, empty);
146     testIntervalOps(empty, mipi, "FFFF", mipi, empty);
147 
148     testIntervalOps(full, empty, "TTFF", full, empty);
149     testIntervalOps(full, full, "TTTT", full, full);
150     testIntervalOps(full, zero, "TTTT", full, zero);
151     testIntervalOps(full, pi, "TTTT", full, pi);
152     testIntervalOps(full, mipi, "TTTT", full, mipi);
153     testIntervalOps(full, quad12, "TTTT", full, quad12);
154     testIntervalOps(full, quad23, "TTTT", full, quad23);
155 
156     testIntervalOps(zero, empty, "TTFF", zero, empty);
157     testIntervalOps(zero, full, "FFTF", full, zero);
158     testIntervalOps(zero, zero, "TFTF", zero, zero);
159     testIntervalOps(zero, pi, "FFFF", new S1Interval(0, S2.M_PI), empty);
160     testIntervalOps(zero, pi2, "FFFF", quad1, empty);
161     testIntervalOps(zero, mipi, "FFFF", quad12, empty);
162     testIntervalOps(zero, mipi2, "FFFF", quad4, empty);
163     testIntervalOps(zero, quad12, "FFTF", quad12, zero);
164     testIntervalOps(zero, quad23, "FFFF", quad123, empty);
165 
166     testIntervalOps(pi2, empty, "TTFF", pi2, empty);
167     testIntervalOps(pi2, full, "FFTF", full, pi2);
168     testIntervalOps(pi2, zero, "FFFF", quad1, empty);
169     testIntervalOps(pi2, pi, "FFFF", new S1Interval(S2.M_PI_2, S2.M_PI), empty);
170     testIntervalOps(pi2, pi2, "TFTF", pi2, pi2);
171     testIntervalOps(pi2, mipi, "FFFF", quad2, empty);
172     testIntervalOps(pi2, mipi2, "FFFF", quad23, empty);
173     testIntervalOps(pi2, quad12, "FFTF", quad12, pi2);
174     testIntervalOps(pi2, quad23, "FFTF", quad23, pi2);
175 
176     testIntervalOps(pi, empty, "TTFF", pi, empty);
177     testIntervalOps(pi, full, "FFTF", full, pi);
178     testIntervalOps(pi, zero, "FFFF", new S1Interval(S2.M_PI, 0), empty);
179     testIntervalOps(pi, pi, "TFTF", pi, pi);
180     testIntervalOps(pi, pi2, "FFFF", new S1Interval(S2.M_PI_2, S2.M_PI), empty);
181     testIntervalOps(pi, mipi, "TFTF", pi, pi);
182     testIntervalOps(pi, mipi2, "FFFF", quad3, empty);
183     testIntervalOps(pi, quad12, "FFTF", new S1Interval(0, S2.M_PI), pi);
184     testIntervalOps(pi, quad23, "FFTF", quad23, pi);
185 
186     testIntervalOps(mipi, empty, "TTFF", mipi, empty);
187     testIntervalOps(mipi, full, "FFTF", full, mipi);
188     testIntervalOps(mipi, zero, "FFFF", quad34, empty);
189     testIntervalOps(mipi, pi, "TFTF", mipi, mipi);
190     testIntervalOps(mipi, pi2, "FFFF", quad2, empty);
191     testIntervalOps(mipi, mipi, "TFTF", mipi, mipi);
192     testIntervalOps(mipi, mipi2, "FFFF", new S1Interval(-S2.M_PI, -S2.M_PI_2), empty);
193     testIntervalOps(mipi, quad12, "FFTF", quad12, mipi);
194     testIntervalOps(mipi, quad23, "FFTF", quad23, mipi);
195 
196     testIntervalOps(quad12, empty, "TTFF", quad12, empty);
197     testIntervalOps(quad12, full, "FFTT", full, quad12);
198     testIntervalOps(quad12, zero, "TFTF", quad12, zero);
199     testIntervalOps(quad12, pi, "TFTF", quad12, pi);
200     testIntervalOps(quad12, mipi, "TFTF", quad12, mipi);
201     testIntervalOps(quad12, quad12, "TFTT", quad12, quad12);
202     testIntervalOps(quad12, quad23, "FFTT", quad123, quad2);
203     testIntervalOps(quad12, quad34, "FFTF", full, quad12);
204 
205     testIntervalOps(quad23, empty, "TTFF", quad23, empty);
206     testIntervalOps(quad23, full, "FFTT", full, quad23);
207     testIntervalOps(quad23, zero, "FFFF", quad234, empty);
208     testIntervalOps(quad23, pi, "TTTT", quad23, pi);
209     testIntervalOps(quad23, mipi, "TTTT", quad23, mipi);
210     testIntervalOps(quad23, quad12, "FFTT", quad123, quad2);
211     testIntervalOps(quad23, quad23, "TFTT", quad23, quad23);
212     testIntervalOps(quad23, quad34, "FFTT", quad234, new S1Interval(-S2.M_PI, -S2.M_PI_2));
213 
214     testIntervalOps(quad1, quad23, "FFTF", quad123, new S1Interval(S2.M_PI_2, S2.M_PI_2));
215     testIntervalOps(quad2, quad3, "FFTF", quad23, mipi);
216     testIntervalOps(quad3, quad2, "FFTF", quad23, pi);
217     testIntervalOps(quad2, pi, "TFTF", quad2, pi);
218     testIntervalOps(quad2, mipi, "TFTF", quad2, mipi);
219     testIntervalOps(quad3, pi, "TFTF", quad3, pi);
220     testIntervalOps(quad3, mipi, "TFTF", quad3, mipi);
221 
222     S1Interval mid12 = new S1Interval(S2.M_PI_2 - 0.02, S2.M_PI_2 + 0.01);
223     S1Interval mid23 = new S1Interval(S2.M_PI - 0.01, -S2.M_PI + 0.02);
224     S1Interval mid34 = new S1Interval(-S2.M_PI_2 - 0.02, -S2.M_PI_2 + 0.01);
225     S1Interval mid41 = new S1Interval(-0.01, 0.02);
226 
227     S1Interval quad2hi = new S1Interval(mid23.lo(), quad12.hi());
228     S1Interval quad1lo = new S1Interval(quad12.lo(), mid41.hi());
229     S1Interval quad12eps = new S1Interval(quad12.lo(), mid23.hi());
230     S1Interval quadeps12 = new S1Interval(mid41.lo(), quad12.hi());
231     S1Interval quad123eps = new S1Interval(quad12.lo(), mid34.hi());
232     testIntervalOps(quad12, mid12, "TTTT", quad12, mid12);
233     testIntervalOps(mid12, quad12, "FFTT", quad12, mid12);
234     testIntervalOps(quad12, mid23, "FFTT", quad12eps, quad2hi);
235     testIntervalOps(mid23, quad12, "FFTT", quad12eps, quad2hi);
236     testIntervalOps(quad12, mid34, "FFFF", quad123eps, empty);
237     testIntervalOps(mid34, quad12, "FFFF", quad123eps, empty);
238     testIntervalOps(quad12, mid41, "FFTT", quadeps12, quad1lo);
239     testIntervalOps(mid41, quad12, "FFTT", quadeps12, quad1lo);
240 
241     S1Interval quad2lo = new S1Interval(quad23.lo(), mid12.hi());
242     S1Interval quad3hi = new S1Interval(mid34.lo(), quad23.hi());
243     S1Interval quadeps23 = new S1Interval(mid12.lo(), quad23.hi());
244     S1Interval quad23eps = new S1Interval(quad23.lo(), mid34.hi());
245     S1Interval quadeps123 = new S1Interval(mid41.lo(), quad23.hi());
246     testIntervalOps(quad23, mid12, "FFTT", quadeps23, quad2lo);
247     testIntervalOps(mid12, quad23, "FFTT", quadeps23, quad2lo);
248     testIntervalOps(quad23, mid23, "TTTT", quad23, mid23);
249     testIntervalOps(mid23, quad23, "FFTT", quad23, mid23);
250     testIntervalOps(quad23, mid34, "FFTT", quad23eps, quad3hi);
251     testIntervalOps(mid34, quad23, "FFTT", quad23eps, quad3hi);
252     testIntervalOps(quad23, mid41, "FFFF", quadeps123, empty);
253     testIntervalOps(mid41, quad23, "FFFF", quadeps123, empty);
254 
255     // AddPoint()
256     S1Interval r = S1Interval.empty();
257     S1Interval res;
258     res = r.addPoint(0);
259     assertEquals(res, zero);
260 
261     res = r.addPoint(S2.M_PI);
262     assertEquals(res, pi);
263 
264     res = r.addPoint(-S2.M_PI);
265     assertEquals(res, mipi);
266 
267     res = r.addPoint(S2.M_PI);
268     res = res.addPoint(-S2.M_PI);
269     assertEquals(res, pi);
270 
271     res = res.addPoint(-S2.M_PI);
272     res.addPoint(S2.M_PI);
273     assertEquals(res, mipi);
274 
275     res = r.addPoint(mid12.lo());
276     res = res.addPoint(mid12.hi());
277     assertEquals(res, mid12);
278 
279     res = r.addPoint(mid23.lo());
280     res = res.addPoint(mid23.hi());
281     assertEquals(res, mid23);
282 
283     res = quad1.addPoint(-0.9 * S2.M_PI);
284     res = res.addPoint(-S2.M_PI_2);
285     assertEquals(res, quad123);
286 
287     r = S1Interval.full();
288     res = r.addPoint(0);
289     assertTrue(res.isFull());
290 
291     res = r.addPoint(S2.M_PI);
292     assertTrue(res.isFull());
293 
294     res = r.addPoint(-S2.M_PI);
295     assertTrue(res.isFull());
296 
297     // FromPointPair()
298     assertEquals(S1Interval.fromPointPair(-S2.M_PI, S2.M_PI), pi);
299     assertEquals(S1Interval.fromPointPair(S2.M_PI, -S2.M_PI), pi);
300     assertEquals(S1Interval.fromPointPair(mid34.hi(), mid34.lo()), mid34);
301     assertEquals(S1Interval.fromPointPair(mid23.lo(), mid23.hi()), mid23);
302 
303     // Expanded()
304     assertEquals(empty.expanded(1), empty);
305     assertEquals(full.expanded(1), full);
306     assertEquals(zero.expanded(1), new S1Interval(-1, 1));
307     assertEquals(mipi.expanded(0.01), new S1Interval(S2.M_PI - 0.01, -S2.M_PI + 0.01));
308     assertEquals(pi.expanded(27), full);
309     assertEquals(pi.expanded(S2.M_PI_2), quad23);
310     assertEquals(pi2.expanded(S2.M_PI_2), quad12);
311     assertEquals(mipi2.expanded(S2.M_PI_2), quad34);
312 
313     // ApproxEquals()
314     assertTrue(empty.approxEquals(empty));
315     assertTrue(zero.approxEquals(empty) && empty.approxEquals(zero));
316     assertTrue(pi.approxEquals(empty) && empty.approxEquals(pi));
317     assertTrue(mipi.approxEquals(empty) && empty.approxEquals(mipi));
318     assertTrue(pi.approxEquals(mipi) && mipi.approxEquals(pi));
319     assertTrue(pi.union(mipi).approxEquals(pi));
320     assertTrue(mipi.union(pi).approxEquals(pi));
321     assertTrue(pi.union(mid12).union(zero).approxEquals(quad12));
322     assertTrue(quad2.intersection(quad3).approxEquals(pi));
323     assertTrue(quad3.intersection(quad2).approxEquals(pi));
324   }
325 }
326