1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.euclidean.twod;
18
19 import java.util.regex.Pattern;
20
21 import org.apache.commons.numbers.angle.PlaneAngleRadians;
22 import org.junit.Assert;
23 import org.junit.Test;
24
25 public class PolarCoordinatesTest {
26
27 private static final double EPS = 1e-10;
28
29 @Test
30 public void testOf() {
31
32 checkPolar(PolarCoordinates.of(0, 0), 0, 0);
33
34 checkPolar(PolarCoordinates.of(2, 0), 2, 0);
35 checkPolar(PolarCoordinates.of(2, PlaneAngleRadians.PI_OVER_TWO), 2, PlaneAngleRadians.PI_OVER_TWO);
36 checkPolar(PolarCoordinates.of(2, PlaneAngleRadians.PI), 2, PlaneAngleRadians.PI);
37 checkPolar(PolarCoordinates.of(2, -PlaneAngleRadians.PI_OVER_TWO), 2, PlaneAngleRadians.THREE_PI_OVER_TWO);
38 }
39
40 @Test
41 public void testOf_unnormalizedAngles() {
42
43 checkPolar(PolarCoordinates.of(2, PlaneAngleRadians.TWO_PI), 2, 0);
44 checkPolar(PolarCoordinates.of(2, PlaneAngleRadians.PI_OVER_TWO + PlaneAngleRadians.TWO_PI), 2, PlaneAngleRadians.PI_OVER_TWO);
45 checkPolar(PolarCoordinates.of(2, -PlaneAngleRadians.PI), 2, PlaneAngleRadians.PI);
46 checkPolar(PolarCoordinates.of(2, -PlaneAngleRadians.PI * 1.5), 2, PlaneAngleRadians.PI_OVER_TWO);
47 }
48
49 @Test
50 public void testOf_azimuthWrapAround() {
51
52 final double delta = 1e-6;
53
54
55 checkAzimuthWrapAround(2, 0);
56 checkAzimuthWrapAround(2, delta);
57 checkAzimuthWrapAround(2, PlaneAngleRadians.PI - delta);
58 checkAzimuthWrapAround(2, PlaneAngleRadians.PI);
59
60 checkAzimuthWrapAround(2, PlaneAngleRadians.THREE_PI_OVER_TWO);
61 checkAzimuthWrapAround(2, PlaneAngleRadians.TWO_PI - delta);
62 }
63
64 private void checkAzimuthWrapAround(final double radius, final double azimuth) {
65 checkPolar(PolarCoordinates.of(radius, azimuth), radius, azimuth);
66
67 checkPolar(PolarCoordinates.of(radius, azimuth - PlaneAngleRadians.TWO_PI), radius, azimuth);
68 checkPolar(PolarCoordinates.of(radius, azimuth - (2 * PlaneAngleRadians.TWO_PI)), radius, azimuth);
69 checkPolar(PolarCoordinates.of(radius, azimuth - (3 * PlaneAngleRadians.TWO_PI)), radius, azimuth);
70
71 checkPolar(PolarCoordinates.of(radius, azimuth + PlaneAngleRadians.TWO_PI), radius, azimuth);
72 checkPolar(PolarCoordinates.of(radius, azimuth + (2 * PlaneAngleRadians.TWO_PI)), radius, azimuth);
73 checkPolar(PolarCoordinates.of(radius, azimuth + (3 * PlaneAngleRadians.TWO_PI)), radius, azimuth);
74 }
75
76 @Test
77 public void testOf_negativeRadius() {
78
79 checkPolar(PolarCoordinates.of(-1, 0), 1, PlaneAngleRadians.PI);
80 checkPolar(PolarCoordinates.of(-1e-6, PlaneAngleRadians.PI_OVER_TWO), 1e-6, PlaneAngleRadians.THREE_PI_OVER_TWO);
81 checkPolar(PolarCoordinates.of(-2, PlaneAngleRadians.PI), 2, 0);
82 checkPolar(PolarCoordinates.of(-3, -PlaneAngleRadians.PI_OVER_TWO), 3, PlaneAngleRadians.PI_OVER_TWO);
83 }
84
85 @Test
86 public void testOf_NaNAndInfinite() {
87
88 checkPolar(PolarCoordinates.of(Double.NaN, 0), Double.NaN, 0);
89 checkPolar(PolarCoordinates.of(Double.NEGATIVE_INFINITY, 0), Double.POSITIVE_INFINITY, PlaneAngleRadians.PI);
90 checkPolar(PolarCoordinates.of(Double.POSITIVE_INFINITY, 0), Double.POSITIVE_INFINITY, 0);
91
92 checkPolar(PolarCoordinates.of(0, Double.NaN), 0, Double.NaN);
93 checkPolar(PolarCoordinates.of(0, Double.NEGATIVE_INFINITY), 0, Double.NEGATIVE_INFINITY);
94 checkPolar(PolarCoordinates.of(0, Double.POSITIVE_INFINITY), 0, Double.POSITIVE_INFINITY);
95 }
96
97 @Test
98 public void testFromCartesian_coordinates() {
99
100 final double sqrt2 = Math.sqrt(2);
101
102
103 checkPolar(PolarCoordinates.fromCartesian(0, 0), 0, 0);
104
105 checkPolar(PolarCoordinates.fromCartesian(1, 0), 1, 0);
106 checkPolar(PolarCoordinates.fromCartesian(1, 1), sqrt2, 0.25 * PlaneAngleRadians.PI);
107 checkPolar(PolarCoordinates.fromCartesian(0, 1), 1, PlaneAngleRadians.PI_OVER_TWO);
108
109 checkPolar(PolarCoordinates.fromCartesian(-1, 1), sqrt2, 0.75 * PlaneAngleRadians.PI);
110 checkPolar(PolarCoordinates.fromCartesian(-1, 0), 1, PlaneAngleRadians.PI);
111 checkPolar(PolarCoordinates.fromCartesian(-1, -1), sqrt2, 1.25 * PlaneAngleRadians.PI);
112
113 checkPolar(PolarCoordinates.fromCartesian(0, -1), 1, 1.5 * PlaneAngleRadians.PI);
114 checkPolar(PolarCoordinates.fromCartesian(1, -1), sqrt2, 1.75 * PlaneAngleRadians.PI);
115 }
116
117 @Test
118 public void testFromCartesian_vector() {
119
120 final double sqrt2 = Math.sqrt(2);
121
122
123 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(0, 0)), 0, 0);
124
125 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(1, 0)), 1, 0);
126 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(1, 1)), sqrt2, 0.25 * PlaneAngleRadians.PI);
127 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(0, 1)), 1, PlaneAngleRadians.PI_OVER_TWO);
128
129 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(-1, 1)), sqrt2, 0.75 * PlaneAngleRadians.PI);
130 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(-1, 0)), 1, PlaneAngleRadians.PI);
131 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(-1, -1)), sqrt2, 1.25 * PlaneAngleRadians.PI);
132
133 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(0, -1)), 1, 1.5 * PlaneAngleRadians.PI);
134 checkPolar(PolarCoordinates.fromCartesian(Vector2D.of(1, -1)), sqrt2, 1.75 * PlaneAngleRadians.PI);
135 }
136
137 @Test
138 public void testDimension() {
139
140 final PolarCoordinates p = PolarCoordinates.of(1, 0);
141
142
143 Assert.assertEquals(2, p.getDimension());
144 }
145
146 @Test
147 public void testIsNaN() {
148
149 Assert.assertFalse(PolarCoordinates.of(1, 0).isNaN());
150 Assert.assertFalse(PolarCoordinates.of(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY).isNaN());
151
152 Assert.assertTrue(PolarCoordinates.of(Double.NaN, 0).isNaN());
153 Assert.assertTrue(PolarCoordinates.of(1, Double.NaN).isNaN());
154 Assert.assertTrue(PolarCoordinates.of(Double.NaN, Double.NaN).isNaN());
155 }
156
157 @Test
158 public void testIsInfinite() {
159
160 Assert.assertFalse(PolarCoordinates.of(1, 0).isInfinite());
161 Assert.assertFalse(PolarCoordinates.of(Double.NaN, Double.NaN).isInfinite());
162
163 Assert.assertTrue(PolarCoordinates.of(Double.POSITIVE_INFINITY, 0).isInfinite());
164 Assert.assertTrue(PolarCoordinates.of(Double.NEGATIVE_INFINITY, 0).isInfinite());
165 Assert.assertFalse(PolarCoordinates.of(Double.NEGATIVE_INFINITY, Double.NaN).isInfinite());
166
167 Assert.assertTrue(PolarCoordinates.of(0, Double.POSITIVE_INFINITY).isInfinite());
168 Assert.assertTrue(PolarCoordinates.of(0, Double.NEGATIVE_INFINITY).isInfinite());
169 Assert.assertFalse(PolarCoordinates.of(Double.NaN, Double.NEGATIVE_INFINITY).isInfinite());
170
171 Assert.assertTrue(PolarCoordinates.of(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY).isInfinite());
172 Assert.assertTrue(PolarCoordinates.of(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY).isInfinite());
173 }
174
175 @Test
176 public void testIsFinite() {
177
178 Assert.assertTrue(PolarCoordinates.of(1, 0).isFinite());
179 Assert.assertTrue(PolarCoordinates.of(1, PlaneAngleRadians.PI).isFinite());
180
181 Assert.assertFalse(PolarCoordinates.of(Double.NaN, Double.NaN).isFinite());
182
183 Assert.assertFalse(PolarCoordinates.of(Double.POSITIVE_INFINITY, 0).isFinite());
184 Assert.assertFalse(PolarCoordinates.of(Double.NEGATIVE_INFINITY, 0).isFinite());
185 Assert.assertFalse(PolarCoordinates.of(Double.NEGATIVE_INFINITY, Double.NaN).isFinite());
186
187 Assert.assertFalse(PolarCoordinates.of(0, Double.POSITIVE_INFINITY).isFinite());
188 Assert.assertFalse(PolarCoordinates.of(0, Double.NEGATIVE_INFINITY).isFinite());
189 Assert.assertFalse(PolarCoordinates.of(Double.NaN, Double.NEGATIVE_INFINITY).isFinite());
190
191 Assert.assertFalse(PolarCoordinates.of(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY).isFinite());
192 Assert.assertFalse(PolarCoordinates.of(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY).isFinite());
193 }
194
195 @Test
196 public void testHashCode() {
197
198 final PolarCoordinates a = PolarCoordinates.of(1, 2);
199 final PolarCoordinates b = PolarCoordinates.of(10, 2);
200 final PolarCoordinates c = PolarCoordinates.of(10, 20);
201 final PolarCoordinates d = PolarCoordinates.of(1, 20);
202
203 final PolarCoordinates e = PolarCoordinates.of(1, 2);
204
205
206 Assert.assertEquals(a.hashCode(), a.hashCode());
207 Assert.assertEquals(a.hashCode(), e.hashCode());
208
209 Assert.assertNotEquals(a.hashCode(), b.hashCode());
210 Assert.assertNotEquals(a.hashCode(), c.hashCode());
211 Assert.assertNotEquals(a.hashCode(), d.hashCode());
212 }
213
214 @Test
215 public void testHashCode_NaNInstancesHaveSameHashCode() {
216
217 final PolarCoordinates a = PolarCoordinates.of(1, Double.NaN);
218 final PolarCoordinates b = PolarCoordinates.of(Double.NaN, 1);
219
220
221 Assert.assertEquals(a.hashCode(), b.hashCode());
222 }
223
224 @Test
225 public void testEquals() {
226
227 final PolarCoordinates a = PolarCoordinates.of(1, 2);
228 final PolarCoordinates b = PolarCoordinates.of(10, 2);
229 final PolarCoordinates c = PolarCoordinates.of(10, 20);
230 final PolarCoordinates d = PolarCoordinates.of(1, 20);
231
232 final PolarCoordinates e = PolarCoordinates.of(1, 2);
233
234
235 Assert.assertFalse(a.equals(null));
236 Assert.assertFalse(a.equals(new Object()));
237
238 Assert.assertEquals(a, a);
239 Assert.assertEquals(a, e);
240
241 Assert.assertNotEquals(a, b);
242 Assert.assertNotEquals(a, c);
243 Assert.assertNotEquals(a, d);
244 }
245
246 @Test
247 public void testEquals_NaNInstancesEqual() {
248
249 final PolarCoordinates a = PolarCoordinates.of(1, Double.NaN);
250 final PolarCoordinates b = PolarCoordinates.of(Double.NaN, 1);
251
252
253 Assert.assertEquals(a, b);
254 }
255
256 @Test
257 public void testEqualsAndHashCode_signedZeroConsistency() {
258
259 final PolarCoordinates a = PolarCoordinates.of(0.0, -0.0);
260 final PolarCoordinates b = PolarCoordinates.of(-0.0, 0.0);
261 final PolarCoordinates c = PolarCoordinates.of(0.0, -0.0);
262 final PolarCoordinates d = PolarCoordinates.of(-0.0, 0.0);
263
264
265 Assert.assertFalse(a.equals(b));
266
267 Assert.assertTrue(a.equals(c));
268 Assert.assertEquals(a.hashCode(), c.hashCode());
269
270 Assert.assertTrue(b.equals(d));
271 Assert.assertEquals(b.hashCode(), d.hashCode());
272 }
273
274 @Test
275 public void testToCartesian() {
276
277 final double sqrt2 = Math.sqrt(2);
278
279
280 checkVector(PolarCoordinates.of(0, 0).toCartesian(), 0, 0);
281
282 checkVector(PolarCoordinates.of(1, 0).toCartesian(), 1, 0);
283 checkVector(PolarCoordinates.of(sqrt2, 0.25 * PlaneAngleRadians.PI).toCartesian(), 1, 1);
284 checkVector(PolarCoordinates.of(1, PlaneAngleRadians.PI_OVER_TWO).toCartesian(), 0, 1);
285
286 checkVector(PolarCoordinates.of(sqrt2, 0.75 * PlaneAngleRadians.PI).toCartesian(), -1, 1);
287 checkVector(PolarCoordinates.of(1, PlaneAngleRadians.PI).toCartesian(), -1, 0);
288 checkVector(PolarCoordinates.of(sqrt2, -0.75 * PlaneAngleRadians.PI).toCartesian(), -1, -1);
289
290 checkVector(PolarCoordinates.of(1, -PlaneAngleRadians.PI_OVER_TWO).toCartesian(), 0, -1);
291 checkVector(PolarCoordinates.of(sqrt2, -0.25 * PlaneAngleRadians.PI).toCartesian(), 1, -1);
292 }
293
294 @Test
295 public void testToCartesian_static() {
296
297 final double sqrt2 = Math.sqrt(2);
298
299
300 checkVector(PolarCoordinates.toCartesian(0, 0), 0, 0);
301
302 checkPoint(PolarCoordinates.toCartesian(1, 0), 1, 0);
303 checkPoint(PolarCoordinates.toCartesian(sqrt2, 0.25 * PlaneAngleRadians.PI), 1, 1);
304 checkPoint(PolarCoordinates.toCartesian(1, PlaneAngleRadians.PI_OVER_TWO), 0, 1);
305
306 checkPoint(PolarCoordinates.toCartesian(sqrt2, 0.75 * PlaneAngleRadians.PI), -1, 1);
307 checkPoint(PolarCoordinates.toCartesian(1, PlaneAngleRadians.PI), -1, 0);
308 checkPoint(PolarCoordinates.toCartesian(sqrt2, -0.75 * PlaneAngleRadians.PI), -1, -1);
309
310 checkPoint(PolarCoordinates.toCartesian(1, -PlaneAngleRadians.PI_OVER_TWO), 0, -1);
311 checkPoint(PolarCoordinates.toCartesian(sqrt2, -0.25 * PlaneAngleRadians.PI), 1, -1);
312 }
313
314 @Test
315 public void testToCartesian_static_NaNAndInfinite() {
316
317 Assert.assertTrue(PolarCoordinates.toCartesian(Double.NaN, 0).isNaN());
318 Assert.assertTrue(PolarCoordinates.toCartesian(0, Double.NaN).isNaN());
319
320 Assert.assertTrue(PolarCoordinates.toCartesian(Double.POSITIVE_INFINITY, 0).isNaN());
321 Assert.assertTrue(PolarCoordinates.toCartesian(0, Double.POSITIVE_INFINITY).isNaN());
322 Assert.assertTrue(PolarCoordinates.toCartesian(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isNaN());
323
324 Assert.assertTrue(PolarCoordinates.toCartesian(Double.NEGATIVE_INFINITY, 0).isNaN());
325 Assert.assertTrue(PolarCoordinates.toCartesian(0, Double.NEGATIVE_INFINITY).isNaN());
326 Assert.assertTrue(PolarCoordinates.toCartesian(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY).isNaN());
327 }
328
329 @Test
330 public void testToString() {
331
332 final PolarCoordinates polar = PolarCoordinates.of(1, 2);
333 final Pattern pattern = Pattern.compile("\\(1.{0,2}, 2.{0,2}\\)");
334
335
336 final String str = polar.toString();
337
338
339 Assert.assertTrue("Expected string " + str + " to match regex " + pattern,
340 pattern.matcher(str).matches());
341 }
342
343 @Test
344 public void testParse() {
345
346 checkPolar(PolarCoordinates.parse("(1, 2)"), 1, 2);
347 checkPolar(PolarCoordinates.parse("( -1 , 0.5 )"), 1, 0.5 + PlaneAngleRadians.PI);
348 checkPolar(PolarCoordinates.parse("(NaN,-Infinity)"), Double.NaN, Double.NEGATIVE_INFINITY);
349 }
350
351 @Test(expected = IllegalArgumentException.class)
352 public void testParse_failure() {
353
354 PolarCoordinates.parse("abc");
355 }
356
357 @Test
358 public void testNormalizeAzimuth() {
359
360 Assert.assertEquals(0.0, PolarCoordinates.normalizeAzimuth(0), EPS);
361
362 Assert.assertEquals(PlaneAngleRadians.PI_OVER_TWO, PolarCoordinates.normalizeAzimuth(PlaneAngleRadians.PI_OVER_TWO), EPS);
363 Assert.assertEquals(PlaneAngleRadians.PI, PolarCoordinates.normalizeAzimuth(PlaneAngleRadians.PI), EPS);
364 Assert.assertEquals(PlaneAngleRadians.THREE_PI_OVER_TWO, PolarCoordinates.normalizeAzimuth(PlaneAngleRadians.THREE_PI_OVER_TWO), EPS);
365 Assert.assertEquals(0.0, PolarCoordinates.normalizeAzimuth(PlaneAngleRadians.TWO_PI), EPS);
366
367 Assert.assertEquals(PlaneAngleRadians.THREE_PI_OVER_TWO, PolarCoordinates.normalizeAzimuth(-PlaneAngleRadians.PI_OVER_TWO), EPS);
368 Assert.assertEquals(PlaneAngleRadians.PI, PolarCoordinates.normalizeAzimuth(-PlaneAngleRadians.PI), EPS);
369 Assert.assertEquals(PlaneAngleRadians.PI_OVER_TWO, PolarCoordinates.normalizeAzimuth(-PlaneAngleRadians.PI - PlaneAngleRadians.PI_OVER_TWO), EPS);
370 Assert.assertEquals(0.0, PolarCoordinates.normalizeAzimuth(-PlaneAngleRadians.TWO_PI), EPS);
371 }
372
373 @Test
374 public void testNormalizeAzimuth_NaNAndInfinite() {
375
376 Assert.assertEquals(Double.NaN, PolarCoordinates.normalizeAzimuth(Double.NaN), EPS);
377 Assert.assertEquals(Double.NEGATIVE_INFINITY, PolarCoordinates.normalizeAzimuth(Double.NEGATIVE_INFINITY), EPS);
378 Assert.assertEquals(Double.POSITIVE_INFINITY, PolarCoordinates.normalizeAzimuth(Double.POSITIVE_INFINITY), EPS);
379 }
380
381 private void checkPolar(final PolarCoordinates polar, final double radius, final double azimuth) {
382 Assert.assertEquals(radius, polar.getRadius(), EPS);
383 Assert.assertEquals(azimuth, polar.getAzimuth(), EPS);
384 }
385
386 private void checkVector(final Vector2D v, final double x, final double y) {
387 Assert.assertEquals(x, v.getX(), EPS);
388 Assert.assertEquals(y, v.getY(), EPS);
389 }
390
391 private void checkPoint(final Vector2D p, final double x, final double y) {
392 Assert.assertEquals(x, p.getX(), EPS);
393 Assert.assertEquals(y, p.getY(), EPS);
394 }
395 }