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