1 package org.djutils.draw.point;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertFalse;
5 import static org.junit.jupiter.api.Assertions.assertNotEquals;
6 import static org.junit.jupiter.api.Assertions.assertTrue;
7 import static org.junit.jupiter.api.Assertions.fail;
8
9 import java.awt.geom.Point2D;
10 import java.util.Iterator;
11 import java.util.NoSuchElementException;
12
13 import org.djutils.base.AngleUtil;
14 import org.djutils.draw.DrawRuntimeException;
15 import org.djutils.exceptions.Try;
16 import org.junit.jupiter.api.Test;
17
18
19
20
21
22
23
24
25
26
27
28
29 public class DirectedPoint2dTest
30 {
31
32
33
34 @SuppressWarnings({"unlikely-arg-type"})
35 @Test
36 public void testMethods()
37 {
38 DirectedPoint2d dp = new DirectedPoint2d(1, 2, 3);
39 assertEquals(1, dp.getX(), 0.0, "x can be retrieved");
40 assertEquals(2, dp.getY(), 0.0, "y can be retrieved");
41 assertEquals(3, dp.getDirZ(), 0.0, "DirZ can be retrieved");
42 assertEquals(1, dp.size(), "size is 1");
43 Iterator<? extends DirectedPoint2d> it = dp.getPoints();
44 assertTrue(it.hasNext(), "iterator has at least one point to provide");
45 DirectedPoint2d p = it.next();
46 assertEquals(p.x, dp.x, 0, "x matches");
47 assertEquals(p.y, dp.y, 0, "y matches");
48 assertEquals(p.dirZ, dp.dirZ, 0, "dirZ matches");
49 assertFalse(it.hasNext(), "iterator is now exhausted");
50 DirectedPoint2d neg = dp.neg();
51 assertEquals(-1, neg.x, 0, "x is negated");
52 assertEquals(-2, neg.y, 0, "y is negated");
53 assertEquals(AngleUtil.normalizeAroundZero(3 + Math.PI), neg.dirZ, 0.0001, "dirZ is altered by pi");
54 try
55 {
56 it.next();
57 fail("exhausted iterator should have thrown an exception");
58 }
59 catch (NoSuchElementException nse)
60 {
61
62 }
63 assertTrue(dp.toString().startsWith("DirectedPoint2d"));
64 assertTrue(dp.toString(false).startsWith("DirectedPoint2d"));
65 assertTrue(dp.toString(true).startsWith("["));
66 assertEquals(dp, dp, "Equals to itself");
67 assertFalse(dp.equals("bla"), "Not equal to some random string");
68 }
69
70
71
72
73 @SuppressWarnings("unlikely-arg-type")
74 @Test
75 public void testDirectedPoint2dConstruction()
76 {
77 DirectedPoint2d p = new DirectedPoint2d(10.0, -20.0, Math.PI);
78 assertEquals(10.0, p.x, 0, "x");
79 assertEquals(-20.0, p.y, 0, "y");
80 assertEquals(3.1415926, p.getDirZ(), 1E-6, "dirZ");
81
82 Point2d p2d = new Point2d(10, -20);
83 p = new DirectedPoint2d(p2d, Math.PI);
84 assertEquals(10.0, p.x, 0, "x");
85 assertEquals(-20.0, p.y, 0, "y");
86 assertEquals(3.1415926, p.getDirZ(), 1E-6, "dirZ");
87 assertEquals(3.1415926, p.dirZ, 1E-6, "dirZ");
88
89 try
90 {
91 new DirectedPoint2d(Double.NaN, 0, 0);
92 fail("NaN coordinate should have thrown an IllegalArgumentException");
93 }
94 catch (IllegalArgumentException iae)
95 {
96
97 }
98
99 try
100 {
101 new DirectedPoint2d(0, Double.NaN, 0);
102 fail("NaN coordinate should have thrown an IllegalArgumentException");
103 }
104 catch (IllegalArgumentException iae)
105 {
106
107 }
108
109 try
110 {
111 new DirectedPoint2d(0, 0, Double.NaN);
112 fail("NaN coordinate should have thrown an IllegalArgumentException");
113 }
114 catch (IllegalArgumentException iae)
115 {
116
117 }
118
119 double[] p2Arr = new double[] {5.0, 6.0};
120 p = new DirectedPoint2d(p2Arr, Math.PI / 2.0);
121 assertEquals(5.0, p.x, 1E-6);
122 assertEquals(6.0, p.y, 1E-6);
123 assertEquals(3.1415926 / 2.0, p.getDirZ(), 1E-6);
124 Point2D.Double p2DD = new Point2D.Double(-0.1, -0.2);
125 p = new DirectedPoint2d(p2DD, Math.PI / 4.0);
126 assertEquals(-0.1, p.x, 1E-6);
127 assertEquals(-0.2, p.y, 1E-6);
128 assertEquals(p2DD, p.toPoint2D());
129 assertEquals(3.1415926 / 4.0, p.getDirZ(), 1E-6);
130
131 Try.testFail(new Try.Execution()
132 {
133 @Override
134 public void execute() throws Throwable
135 {
136 new DirectedPoint2d((Point2D.Double) null, 0.0);
137 }
138 }, "Should throw NPE", NullPointerException.class);
139
140 Try.testFail(new Try.Execution()
141 {
142 @Override
143 public void execute() throws Throwable
144 {
145 new DirectedPoint2d((Point2D.Double) null, Math.PI);
146 }
147 }, "Should throw NPE", NullPointerException.class);
148
149 Try.testFail(new Try.Execution()
150 {
151 @Override
152 public void execute() throws Throwable
153 {
154 new DirectedPoint2d(new double[] {}, Math.PI / 2.0);
155 }
156 }, "Should throw IAE", IllegalArgumentException.class);
157
158 Try.testFail(new Try.Execution()
159 {
160 @Override
161 public void execute() throws Throwable
162 {
163 new DirectedPoint2d(new double[] {1.0}, Math.PI / 4.0);
164 }
165 }, "Should throw IAE", IllegalArgumentException.class);
166
167 Try.testFail(new Try.Execution()
168 {
169 @Override
170 public void execute() throws Throwable
171 {
172 new DirectedPoint2d(new double[] {1.0, 2.0, 3.0}, Math.PI);
173 }
174 }, "Should throw IAE", IllegalArgumentException.class);
175
176
177 assertTrue(p.equals(p));
178 assertEquals(p.hashCode(), p.hashCode());
179 DirectedPoint3d p3d = p.translate(1, 2, 3);
180 assertFalse(p.equals(p3d));
181 assertFalse(p.equals(null));
182 assertNotEquals(p3d.hashCode(), p.hashCode());
183 assertEquals(p.x + 1.0, p3d.x, 0.00001, "translated x");
184 assertEquals(p.y + 2.0, p3d.y, 0.00001, "translated y");
185 assertEquals(0 + 3.0, p3d.z, 0.00001, "translated z");
186 assertEquals(Math.PI / 4.0, p.getDirZ(), 1E-6);
187 assertTrue(p.equals(p.translate(0.0, 0.0)));
188 assertFalse(p.equals(p.translate(1.0, 0.0)));
189 assertFalse(p.equals(p.translate(0.0, 1.0)));
190 assertFalse(p.equals(p.rotate(0.1)));
191
192
193 p = new DirectedPoint2d(10.0, 20.0, Math.PI);
194 assertEquals("DirectedPoint2d [x=10.000000, y=20.000000, dirZ=3.141593]", p.toString());
195 assertEquals("DirectedPoint2d [x=10.0, y=20.0, dirZ=3.1]", p.toString("%.1f"));
196 assertEquals("[x=10, y=20, dirZ=3]", p.toString("%.0f", true));
197
198
199 DirectedPoint3d p3 = new DirectedPoint3d(p.translate(0.001, 0.0, 0.0), 0, p.dirZ);
200 DirectedPoint3d ref = new DirectedPoint3d(p.translate(0, 0, 0), 0, p.dirZ);
201 assertTrue(ref.epsilonEquals(p3, 0.09, 0.001));
202 assertTrue(p3.epsilonEquals(ref, 0.09, 0.001));
203 assertFalse(ref.epsilonEquals(p3, 0.0009, 0.001));
204 assertFalse(p3.epsilonEquals(ref, 0.0009, 0.001));
205 p3 = p.translate(0.0, 0.001, 0.0);
206 assertTrue(ref.epsilonEquals(p3, 0.09, 0.001));
207 assertTrue(p3.epsilonEquals(ref, 0.09, 0.001));
208 assertFalse(ref.epsilonEquals(p3, 0.0009, 0.001));
209 assertFalse(p3.epsilonEquals(ref, 0.0009, 0.001));
210 DirectedPoint2d p2 = p.translate(0.001, 0.0);
211 assertTrue(p.epsilonEquals(p2, 0.09, 0.001), "all");
212 assertFalse(p.epsilonEquals(p2, 0.0009, 0.001), "dx");
213 p2 = p.translate(0.0, 0.001);
214 assertTrue(p.epsilonEquals(p2, 0.09, 0.001), "all");
215 assertFalse(p.epsilonEquals(p2, 0.0009, 0.001), "dy");
216 p3 = p.translate(0.0, 0.0, 0.001);
217 assertTrue(ref.epsilonEquals(p3, 0.09, 0.001));
218 assertTrue(p3.epsilonEquals(ref, 0.09, 0.001));
219 assertFalse(ref.epsilonEquals(p3, 0.0009, 0.001));
220 assertFalse(p3.epsilonEquals(ref, 0.0009, 0.001));
221 DirectedPoint2d dp2 = p.rotate(0.001);
222 assertTrue(p.epsilonEquals(dp2, 0.09, 0.009));
223 assertTrue(dp2.epsilonEquals(p, 0.09, 0.009));
224 assertFalse(p.epsilonEquals(dp2, 0.0009, 0.0009));
225 assertFalse(dp2.epsilonEquals(p, 0.0009, 0.0009));
226 }
227
228
229
230
231 @Test
232 public void testDirectedPoint2dOperators()
233 {
234 DirectedPoint2d p = new DirectedPoint2d(-0.1, -0.2, -Math.PI / 7);
235 DirectedPoint2d out = new DirectedPoint2d(p.abs(), p.dirZ);
236 assertEquals(0.1, out.x, 1E-6, "x");
237 assertEquals(0.2, out.y, 1E-6, "y");
238 assertEquals(-Math.PI / 7, out.getDirZ(), 1E-6, "dirZ");
239
240 Iterator<? extends Point2d> i = p.getPoints();
241 assertTrue(i.hasNext(), "iterator has one point");
242 assertEquals(p, i.next(), "iterator returns p");
243 assertFalse(i.hasNext(), "iterator does not have another point");
244
245 out = p.neg();
246 assertEquals(0.1, out.x, 1E-6, "neg x");
247 assertEquals(0.2, out.y, 1E-6, "neg y");
248 assertEquals(Math.PI - Math.PI / 7, out.getDirZ(), 1E-6, "neg dirZ");
249
250 out = p.scale(1.0);
251 assertEquals(-0.1, out.x, 1E-6, "x");
252 assertEquals(-0.2, out.y, 1E-6, "y");
253 assertEquals(-Math.PI / 7, out.getDirZ(), 1E-6, "dirZ");
254
255 out = p.scale(10.0);
256 assertEquals(-1.0, out.x, 1E-6, "10 x");
257 assertEquals(-2.0, out.y, 1E-6, "10 y");
258 assertEquals(-Math.PI / 7, out.getDirZ(), 1E-6, "dirZ");
259
260 out = p.translate(5.0, -1.0);
261 assertEquals(4.9, out.x, 1E-6, "x");
262 assertEquals(-1.2, out.y, 1E-6, "y");
263 assertEquals(-Math.PI / 7, out.getDirZ(), 1E-6, "dirZ");
264
265 out = p.translate(1.0, 3.0);
266 assertEquals(0.9, out.x, 1E-6, "x");
267 assertEquals(2.8, out.y, 1E-6, "y");
268 assertEquals(-Math.PI / 7, out.getDirZ(), 1E-6, "dirZ");
269
270 out = p.rotate(- Math.PI / 4);
271 assertEquals(-0.1, out.x, 1E-6, "x");
272 assertEquals(-0.2, out.y, 1E-6, "y");
273 assertEquals(-Math.PI / 7 - Math.PI / 4, out.getDirZ(), 1E-6, "dirZ");
274
275
276 DirectedPoint2d p1 = new DirectedPoint2d(1.0, 1.0, 0.0);
277 DirectedPoint2d p2 = new DirectedPoint2d(5.0, 5.0, Math.PI / 2.0);
278 assertEquals(p1, p1.interpolate(p2, 0.0), "p1 interpolated to p2 at 0");
279 assertEquals(p2, p1.interpolate(p2, 1.0), "p1 interpolated to p2 at 1");
280 assertEquals(p2, p2.interpolate(p1, 0.0), "p2 interpolated to p1 at 0");
281 assertEquals(p1, p2.interpolate(p1, 1.0), "p2 interpolated to p1 at 1");
282 assertEquals(p1, p1.interpolate(p1, 0.0), "p1 interpolated to itself at 0");
283 assertEquals(new DirectedPoint2d(3.0, 3.0, Math.PI / 4.0), p1.interpolate(p2, 0.5), "interpolated at halfway");
284
285
286 assertEquals(Math.sqrt(32.0), p1.distance(p2), 0.001);
287 assertEquals(32.0, p1.distanceSquared(p2), 0.001);
288
289
290
291
292
293
294
295
296
297
298 DirectedPoint2d pn = new DirectedPoint2d(p2.normalize(), p.dirZ);
299 assertEquals(1.0 / Math.sqrt(2.0), pn.x, 0.001);
300 assertEquals(1.0 / Math.sqrt(2.0), pn.y, 0.001);
301
302 Try.testFail(new Try.Execution()
303 {
304 @Override
305 public void execute() throws Throwable
306 {
307 new DirectedPoint2d(0.0, 0.0, Math.PI / 4.0).normalize();
308 }
309 }, "Should throw DRtE", DrawRuntimeException.class);
310
311 Try.testFail(new Try.Execution()
312 {
313 @Override
314 public void execute() throws Throwable
315 {
316 p1.translate(Double.NaN, 2);
317 }
318 }, "Should throw IAE", IllegalArgumentException.class);
319
320 Try.testFail(new Try.Execution()
321 {
322 @Override
323 public void execute() throws Throwable
324 {
325 p1.translate(1, Double.NaN);
326 }
327 }, "Should throw IAE", IllegalArgumentException.class);
328
329 Try.testFail(new Try.Execution()
330 {
331 @Override
332 public void execute() throws Throwable
333 {
334 p1.translate(Double.NaN, 2, 3);
335 }
336 }, "Should throw IAE", IllegalArgumentException.class);
337
338 Try.testFail(new Try.Execution()
339 {
340 @Override
341 public void execute() throws Throwable
342 {
343 p1.translate(1, Double.NaN, 3);
344 }
345 }, "Should throw IAE", IllegalArgumentException.class);
346
347 Try.testFail(new Try.Execution()
348 {
349 @Override
350 public void execute() throws Throwable
351 {
352 p1.translate(1, 2, Double.NaN);
353 }
354 }, "Should throw IAE", IllegalArgumentException.class);
355
356 }
357
358
359
360
361 @Test
362 public void testDirectedPoint2dOperatorsNPE()
363 {
364 final DirectedPoint2d p1 = new DirectedPoint2d(1.0, 1.0, Math.PI / 4.0);
365
366 Try.testFail(new Try.Execution()
367 {
368 @Override
369 public void execute() throws Throwable
370 {
371 p1.interpolate(null, 0.5);
372 }
373 }, "Should throw NPE", NullPointerException.class);
374
375 Try.testFail(new Try.Execution()
376 {
377 @Override
378 public void execute() throws Throwable
379 {
380 p1.distance(null);
381 }
382 }, "Should throw NPE", NullPointerException.class);
383
384 Try.testFail(new Try.Execution()
385 {
386 @Override
387 public void execute() throws Throwable
388 {
389 p1.distanceSquared(null);
390 }
391 }, "Should throw NPE", NullPointerException.class);
392
393 }
394
395 }