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