1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.spherical.oned;
18
19 import java.util.Comparator;
20
21 import org.apache.commons.geometry.core.GeometryTestUtils;
22 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
23 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
24 import org.apache.commons.geometry.euclidean.twod.PolarCoordinates;
25 import org.apache.commons.geometry.euclidean.twod.Vector2D;
26 import org.apache.commons.numbers.angle.PlaneAngle;
27 import org.apache.commons.numbers.angle.PlaneAngleRadians;
28 import org.junit.Assert;
29 import org.junit.Test;
30
31 public class Point1STest {
32
33 private static final double TEST_EPS = 1e-10;
34
35 @Test
36 public void testConstants() {
37
38 Assert.assertEquals(0.0, Point1S.ZERO.getAzimuth(), TEST_EPS);
39 Assert.assertEquals(Math.PI, Point1S.PI.getAzimuth(), TEST_EPS);
40 }
41
42 @Test
43 public void testNormalizedAzimuthComparator() {
44
45 final Comparator<Point1S> comp = Point1S.NORMALIZED_AZIMUTH_ASCENDING_ORDER;
46
47
48 Assert.assertEquals(0, comp.compare(Point1S.of(1), Point1S.of(1)));
49 Assert.assertEquals(-1, comp.compare(Point1S.of(0), Point1S.of(1)));
50 Assert.assertEquals(1, comp.compare(Point1S.of(1), Point1S.of(0)));
51 Assert.assertEquals(1, comp.compare(Point1S.of(1), Point1S.of(0.1 + PlaneAngleRadians.TWO_PI)));
52
53 Assert.assertEquals(1, comp.compare(null, Point1S.of(0)));
54 Assert.assertEquals(-1, comp.compare(Point1S.of(0), null));
55 Assert.assertEquals(0, comp.compare(null, null));
56 }
57
58 @Test
59 public void testOf() {
60
61 checkPoint(Point1S.of(0), 0, 0);
62 checkPoint(Point1S.of(1), 1, 1);
63 checkPoint(Point1S.of(-1), -1, PlaneAngleRadians.TWO_PI - 1);
64
65 checkPoint(Point1S.of(PlaneAngle.ofDegrees(90)), PlaneAngleRadians.PI_OVER_TWO, PlaneAngleRadians.PI_OVER_TWO);
66 checkPoint(Point1S.of(PlaneAngle.ofTurns(0.5)), PlaneAngleRadians.PI, PlaneAngleRadians.PI);
67 checkPoint(Point1S.of(-PlaneAngleRadians.PI_OVER_TWO), -PlaneAngleRadians.PI_OVER_TWO, 1.5 * PlaneAngleRadians.PI);
68
69 final double base = PlaneAngleRadians.PI_OVER_TWO;
70 for (int k = -3; k <= 3; ++k) {
71 final double az = base + (k * PlaneAngleRadians.TWO_PI);
72 checkPoint(Point1S.of(az), az, base);
73 }
74 }
75
76 @Test
77 public void testFrom_vector() {
78
79 checkPoint(Point1S.from(Vector2D.of(2, 0)), 0.0);
80 checkPoint(Point1S.from(Vector2D.of(0, 0.1)), PlaneAngleRadians.PI_OVER_TWO);
81 checkPoint(Point1S.from(Vector2D.of(-0.5, 0)), PlaneAngleRadians.PI);
82 checkPoint(Point1S.from(Vector2D.of(0, -100)), 1.5 * PlaneAngleRadians.PI);
83 }
84
85 @Test
86 public void testFrom_polar() {
87
88 checkPoint(Point1S.from(PolarCoordinates.of(100, 0)), 0.0);
89 checkPoint(Point1S.from(PolarCoordinates.of(1, PlaneAngleRadians.PI_OVER_TWO)), PlaneAngleRadians.PI_OVER_TWO);
90 checkPoint(Point1S.from(PolarCoordinates.of(0.5, PlaneAngleRadians.PI)), PlaneAngleRadians.PI);
91 checkPoint(Point1S.from(PolarCoordinates.of(1e-4, -PlaneAngleRadians.PI_OVER_TWO)), 1.5 * PlaneAngleRadians.PI);
92 }
93
94 @Test
95 public void testFrom_polar_invalidAzimuths() {
96
97 checkPoint(Point1S.from(PolarCoordinates.of(100, Double.POSITIVE_INFINITY)), Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
98 checkPoint(Point1S.from(PolarCoordinates.of(100, Double.NEGATIVE_INFINITY)), Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
99 checkPoint(Point1S.from(PolarCoordinates.of(100, Double.NaN)), Double.NaN, Double.NaN);
100 }
101
102 @Test
103 public void testNaN() {
104
105 final Point1S pt = Point1S.of(Double.NaN);
106
107
108 Assert.assertTrue(pt.isNaN());
109 Assert.assertTrue(Point1S.NaN.isNaN());
110
111 Assert.assertTrue(Double.isNaN(pt.getAzimuth()));
112 Assert.assertTrue(Double.isNaN(pt.getNormalizedAzimuth()));
113 Assert.assertNull(pt.getVector());
114
115 Assert.assertEquals(Point1S.NaN, pt);
116 Assert.assertNotEquals(Point1S.of(1.0), Point1S.NaN);
117 }
118
119 @Test
120 public void testGetDimension() {
121
122 final Point1S p = Point1S.of(0.0);
123
124
125 Assert.assertEquals(1, p.getDimension());
126 }
127
128 @Test
129 public void testInfinite() {
130
131 Assert.assertTrue(Point1S.of(Double.POSITIVE_INFINITY).isInfinite());
132 Assert.assertTrue(Point1S.of(Double.NEGATIVE_INFINITY).isInfinite());
133
134 Assert.assertFalse(Point1S.NaN.isInfinite());
135 Assert.assertFalse(Point1S.of(1).isInfinite());
136 }
137
138 @Test
139 public void testFinite() {
140
141 Assert.assertTrue(Point1S.of(0).isFinite());
142 Assert.assertTrue(Point1S.of(1).isFinite());
143
144 Assert.assertFalse(Point1S.of(Double.POSITIVE_INFINITY).isFinite());
145 Assert.assertFalse(Point1S.of(Double.NEGATIVE_INFINITY).isFinite());
146 Assert.assertFalse(Point1S.NaN.isFinite());
147 }
148
149 @Test
150 public void testAntipodal() {
151 for (double az = -6 * PlaneAngleRadians.PI; az <= 6 * PlaneAngleRadians.PI; az += 0.1) {
152
153 final Point1S pt = Point1S.of(az);
154
155
156 final Point1S result = pt.antipodal();
157
158
159 Assert.assertTrue(result.getAzimuth() >= 0 && result.getAzimuth() < PlaneAngleRadians.TWO_PI);
160 Assert.assertEquals(PlaneAngleRadians.PI, pt.distance(result), TEST_EPS);
161 }
162 }
163
164 @Test
165 public void testHashCode() {
166
167 final Point1S a = Point1S.of(1.0);
168 final Point1S b = Point1S.of(2.0);
169 final Point1S c = Point1S.of(1.0);
170 final Point1S d = Point1S.of(1.0 + PlaneAngleRadians.PI);
171
172 final int hash = a.hashCode();
173
174
175 Assert.assertEquals(hash, a.hashCode());
176 Assert.assertNotEquals(hash, b.hashCode());
177 Assert.assertEquals(hash, c.hashCode());
178 Assert.assertNotEquals(hash, d.hashCode());
179
180 Assert.assertEquals(Point1S.NaN.hashCode(), Point1S.of(Double.NaN).hashCode());
181 }
182
183 @Test
184 public void testEquals() {
185
186 final Point1S a = Point1S.of(1.0);
187 final Point1S b = Point1S.of(2.0);
188 final Point1S c = Point1S.of(1.0 + PlaneAngleRadians.PI);
189 final Point1S d = Point1S.of(1.0);
190 final Point1S e = Point1S.of(Double.NaN);
191
192
193 Assert.assertFalse(a.equals(null));
194 Assert.assertFalse(a.equals(new Object()));
195
196 Assert.assertEquals(a, a);
197
198 Assert.assertNotEquals(a, b);
199 Assert.assertNotEquals(b, a);
200
201 Assert.assertNotEquals(a, c);
202 Assert.assertNotEquals(c, a);
203
204 Assert.assertEquals(a, d);
205 Assert.assertEquals(d, a);
206
207 Assert.assertNotEquals(a, e);
208 Assert.assertEquals(Point1S.NaN, e);
209 }
210
211 @Test
212 public void testEqualsAndHashCode_signedZeroConsistency() {
213
214 final Point1S a = Point1S.of(0.0);
215 final Point1S b = Point1S.of(-0.0);
216 final Point1S c = Point1S.of(0.0);
217 final Point1S d = Point1S.of(-0.0);
218
219
220 Assert.assertFalse(a.equals(b));
221 Assert.assertNotEquals(a.hashCode(), b.hashCode());
222
223 Assert.assertTrue(a.equals(c));
224 Assert.assertEquals(a.hashCode(), c.hashCode());
225
226 Assert.assertTrue(b.equals(d));
227 Assert.assertEquals(b.hashCode(), d.hashCode());
228 }
229
230 @Test
231 public void testEq() {
232
233 final DoublePrecisionContext highPrecision = new EpsilonDoublePrecisionContext(1e-10);
234 final DoublePrecisionContext lowPrecision = new EpsilonDoublePrecisionContext(1e-2);
235
236 final Point1S a = Point1S.of(1);
237 final Point1S b = Point1S.of(0.9999);
238 final Point1S c = Point1S.of(1.00001);
239 final Point1S d = Point1S.of(1 + (3 * PlaneAngleRadians.TWO_PI));
240
241
242 Assert.assertTrue(a.eq(a, highPrecision));
243 Assert.assertTrue(a.eq(a, lowPrecision));
244
245 Assert.assertFalse(a.eq(b, highPrecision));
246 Assert.assertTrue(a.eq(b, lowPrecision));
247
248 Assert.assertFalse(a.eq(c, highPrecision));
249 Assert.assertTrue(a.eq(c, lowPrecision));
250
251 Assert.assertTrue(a.eq(d, highPrecision));
252 Assert.assertTrue(a.eq(d, lowPrecision));
253 }
254
255 @Test
256 public void testEq_wrapAround() {
257
258 final DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-2);
259
260 final Point1S a = Point1S.ZERO;
261 final Point1S b = Point1S.of(1e-3);
262 final Point1S c = Point1S.of(-1e-3);
263
264
265 Assert.assertTrue(a.eq(a, precision));
266
267 Assert.assertTrue(a.eq(b, precision));
268 Assert.assertTrue(b.eq(a, precision));
269
270 Assert.assertTrue(a.eq(c, precision));
271 Assert.assertTrue(c.eq(a, precision));
272 }
273
274 @Test
275 public void testDistance() {
276
277 final Point1S a = Point1S.of(0.0);
278 final Point1S b = Point1S.of(PlaneAngleRadians.PI - 0.5);
279 final Point1S c = Point1S.of(PlaneAngleRadians.PI);
280 final Point1S d = Point1S.of(PlaneAngleRadians.PI + 0.5);
281 final Point1S e = Point1S.of(4.0);
282
283
284 Assert.assertEquals(0.0, a.distance(a), TEST_EPS);
285 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.distance(b), TEST_EPS);
286 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, b.distance(a), TEST_EPS);
287
288 Assert.assertEquals(PlaneAngleRadians.PI, a.distance(c), TEST_EPS);
289 Assert.assertEquals(PlaneAngleRadians.PI, c.distance(a), TEST_EPS);
290
291 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.distance(d), TEST_EPS);
292 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, d.distance(a), TEST_EPS);
293
294 Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, a.distance(e), TEST_EPS);
295 Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, e.distance(a), TEST_EPS);
296 }
297
298 @Test
299 public void testSignedDistance() {
300
301 final Point1S a = Point1S.of(0.0);
302 final Point1S b = Point1S.of(PlaneAngleRadians.PI - 0.5);
303 final Point1S c = Point1S.of(PlaneAngleRadians.PI);
304 final Point1S d = Point1S.of(PlaneAngleRadians.PI + 0.5);
305 final Point1S e = Point1S.of(4.0);
306
307
308 Assert.assertEquals(0.0, a.signedDistance(a), TEST_EPS);
309 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, a.signedDistance(b), TEST_EPS);
310 Assert.assertEquals(-PlaneAngleRadians.PI + 0.5, b.signedDistance(a), TEST_EPS);
311
312 Assert.assertEquals(-PlaneAngleRadians.PI, a.signedDistance(c), TEST_EPS);
313 Assert.assertEquals(-PlaneAngleRadians.PI, c.signedDistance(a), TEST_EPS);
314
315 Assert.assertEquals(-PlaneAngleRadians.PI + 0.5, a.signedDistance(d), TEST_EPS);
316 Assert.assertEquals(PlaneAngleRadians.PI - 0.5, d.signedDistance(a), TEST_EPS);
317
318 Assert.assertEquals(-PlaneAngleRadians.TWO_PI + 4, a.signedDistance(e), TEST_EPS);
319 Assert.assertEquals(PlaneAngleRadians.TWO_PI - 4, e.signedDistance(a), TEST_EPS);
320 }
321
322 @Test
323 public void testDistance_inRangeZeroToPi() {
324 for (double a = -4 * PlaneAngleRadians.PI; a < 4 * PlaneAngleRadians.PI; a += 0.1) {
325 for (double b = -4 * PlaneAngleRadians.PI; b < 4 * PlaneAngleRadians.PI; b += 0.1) {
326
327 final Point1S p1 = Point1S.of(a);
328 final Point1S p2 = Point1S.of(b);
329
330
331 final double d1 = p1.distance(p2);
332 Assert.assertTrue(d1 >= 0 && d1 <= PlaneAngleRadians.PI);
333
334 final double d2 = p2.distance(p1);
335 Assert.assertTrue(d2 >= 0 && d2 <= PlaneAngleRadians.PI);
336 }
337 }
338 }
339
340 @Test
341 public void testNormalize() {
342 for (double az = -PlaneAngleRadians.TWO_PI; az < 2 * PlaneAngleRadians.TWO_PI; az += 0.2) {
343
344 final Point1S pt = Point1S.of(az);
345
346 final double expectedPiNorm = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(az);
347 final double expectedZeroNorm = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(az);
348
349
350 final Point1S piNorm = pt.normalize(Point1S.PI);
351 final Point1S zeroNorm = pt.normalize(0.0);
352
353
354 Assert.assertEquals(expectedPiNorm, piNorm.getAzimuth(), TEST_EPS);
355 Assert.assertEquals(pt.getNormalizedAzimuth(), piNorm.getNormalizedAzimuth(), TEST_EPS);
356
357 Assert.assertEquals(expectedZeroNorm, zeroNorm.getAzimuth(), TEST_EPS);
358 Assert.assertEquals(pt.getNormalizedAzimuth(), zeroNorm.getNormalizedAzimuth(), TEST_EPS);
359 }
360 }
361
362 @Test
363 public void testNormalize_nonFinite() {
364
365 GeometryTestUtils.assertThrows(() -> {
366 Point1S.of(Double.POSITIVE_INFINITY).normalize(0.0);
367 }, IllegalArgumentException.class);
368
369 GeometryTestUtils.assertThrows(() -> {
370 Point1S.of(Double.NEGATIVE_INFINITY).normalize(0.0);
371 }, IllegalArgumentException.class);
372
373 GeometryTestUtils.assertThrows(() -> {
374 Point1S.of(Double.NaN).normalize(Point1S.ZERO);
375 }, IllegalArgumentException.class);
376 }
377
378 @Test
379 public void testAbove() {
380
381 final Point1S p1 = Point1S.ZERO;
382 final Point1S p2 = Point1S.of(PlaneAngle.ofDegrees(90));
383 final Point1S p3 = Point1S.PI;
384 final Point1S p4 = Point1S.of(PlaneAngle.ofDegrees(-90));
385 final Point1S p5 = Point1S.of(PlaneAngleRadians.TWO_PI);
386
387
388 checkPoint(p1.above(p1), 0);
389 checkPoint(p2.above(p1), PlaneAngleRadians.PI_OVER_TWO);
390 checkPoint(p3.above(p1), PlaneAngleRadians.PI);
391 checkPoint(p4.above(p1), 1.5 * PlaneAngleRadians.PI);
392 checkPoint(p5.above(p1), 0);
393
394 checkPoint(p1.above(p3), PlaneAngleRadians.TWO_PI);
395 checkPoint(p2.above(p3), 2.5 * PlaneAngleRadians.PI);
396 checkPoint(p3.above(p3), PlaneAngleRadians.PI);
397 checkPoint(p4.above(p3), 1.5 * PlaneAngleRadians.PI);
398 checkPoint(p5.above(p3), PlaneAngleRadians.TWO_PI);
399 }
400
401 @Test
402 public void testAbove_nonFinite() {
403
404 GeometryTestUtils.assertThrows(() -> {
405 Point1S.of(Double.POSITIVE_INFINITY).above(Point1S.ZERO);
406 }, IllegalArgumentException.class);
407
408 GeometryTestUtils.assertThrows(() -> {
409 Point1S.of(Double.NEGATIVE_INFINITY).above(Point1S.ZERO);
410 }, IllegalArgumentException.class);
411
412 GeometryTestUtils.assertThrows(() -> {
413 Point1S.of(Double.NaN).above(Point1S.ZERO);
414 }, IllegalArgumentException.class);
415 }
416
417 @Test
418 public void testBelow() {
419
420 final Point1S p1 = Point1S.ZERO;
421 final Point1S p2 = Point1S.of(PlaneAngle.ofDegrees(90));
422 final Point1S p3 = Point1S.PI;
423 final Point1S p4 = Point1S.of(PlaneAngle.ofDegrees(-90));
424 final Point1S p5 = Point1S.of(PlaneAngleRadians.TWO_PI);
425
426
427 checkPoint(p1.below(p1), -PlaneAngleRadians.TWO_PI);
428 checkPoint(p2.below(p1), -1.5 * PlaneAngleRadians.PI);
429 checkPoint(p3.below(p1), -PlaneAngleRadians.PI);
430 checkPoint(p4.below(p1), -PlaneAngleRadians.PI_OVER_TWO);
431 checkPoint(p5.below(p1), -PlaneAngleRadians.TWO_PI);
432
433 checkPoint(p1.below(p3), 0.0);
434 checkPoint(p2.below(p3), PlaneAngleRadians.PI_OVER_TWO);
435 checkPoint(p3.below(p3), -PlaneAngleRadians.PI);
436 checkPoint(p4.below(p3), -PlaneAngleRadians.PI_OVER_TWO);
437 checkPoint(p5.below(p3), 0.0);
438 }
439
440 @Test
441 public void testBelow_nonFinite() {
442
443 GeometryTestUtils.assertThrows(() -> {
444 Point1S.of(Double.POSITIVE_INFINITY).below(Point1S.ZERO);
445 }, IllegalArgumentException.class);
446
447 GeometryTestUtils.assertThrows(() -> {
448 Point1S.of(Double.NEGATIVE_INFINITY).below(Point1S.ZERO);
449 }, IllegalArgumentException.class);
450
451 GeometryTestUtils.assertThrows(() -> {
452 Point1S.of(Double.NaN).below(Point1S.ZERO);
453 }, IllegalArgumentException.class);
454 }
455
456 @Test
457 public void testToString() {
458
459 Assert.assertEquals("(0.0)", Point1S.of(0.0).toString());
460 Assert.assertEquals("(1.0)", Point1S.of(1.0).toString());
461 }
462
463 @Test
464 public void testParse() {
465
466 checkPoint(Point1S.parse("(0)"), 0.0);
467 checkPoint(Point1S.parse("(1)"), 1.0);
468 }
469
470 @Test(expected = IllegalArgumentException.class)
471 public void testParse_failure() {
472
473 Point1S.parse("abc");
474 }
475
476 private static void checkPoint(final Point1S pt, final double az) {
477 checkPoint(pt, az, PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(az));
478 }
479
480 private static void checkPoint(final Point1S pt, final double az, final double normAz) {
481 Assert.assertEquals(az, pt.getAzimuth(), TEST_EPS);
482 Assert.assertEquals(normAz, pt.getNormalizedAzimuth(), TEST_EPS);
483
484 Assert.assertEquals(1, pt.getDimension());
485
486 Assert.assertEquals(Double.isFinite(az), pt.isFinite());
487 Assert.assertEquals(Double.isInfinite(az), pt.isInfinite());
488
489 final Vector2D vec = pt.getVector();
490 if (pt.isFinite()) {
491 Assert.assertEquals(1, vec.norm(), TEST_EPS);
492 Assert.assertEquals(normAz, PolarCoordinates.fromCartesian(vec).getAzimuth(), TEST_EPS);
493 } else {
494 Assert.assertNull(vec);
495 }
496 }
497 }