View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.geometry.euclidean.twod;
23  
24  import java.text.NumberFormat;
25  import java.util.Locale;
26  
27  import org.hipparchus.exception.LocalizedCoreFormats;
28  import org.hipparchus.exception.MathIllegalArgumentException;
29  import org.hipparchus.exception.MathRuntimeException;
30  import org.hipparchus.geometry.LocalizedGeometryFormats;
31  import org.hipparchus.util.Binary64Field;
32  import org.hipparchus.util.FastMath;
33  import org.hipparchus.util.SinCos;
34  import org.junit.Assert;
35  import org.junit.Test;
36  
37  public class Vector2DTest {
38  
39      @Test public void testConstructors() {
40          final double p40 =  4.0;
41          final double p20 =  2.0;
42          final double p25 =  2.5;
43          final double p10 =  1.0;
44          final double m05 = -0.5;
45          final double m30 = -3.0;
46          check(new Vector2D(p25, m05), 2.5, -0.5, 1.0e-15);
47          final double[] a = new double[2];
48          a[0] = 1.0;
49          a[1] = 0.0;
50          check(new Vector2D(a), 1.0, 0.0, 1.0e-15);
51          try {
52              new Vector2D(new double[3]);
53              Assert.fail("an exception should have been thrown");
54          } catch (MathIllegalArgumentException miae) {
55              Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
56              Assert.assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
57              Assert.assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
58          }
59          check(new Vector2D(p20, new Vector2D(p25, m05)), 5.0, -1.0, 1.0e-15);
60          check(new Vector2D(p20, new Vector2D(2.5, -0.5)), 5.0, -1.0, 1.0e-15);
61          check(new Vector2D(2, new Vector2D(p25, m05)), 5.0, -1.0, 1.0e-15);
62          check(new Vector2D(p20, new Vector2D(p25, m05), m30, new Vector2D(m05, p40)),
63                6.5, -13.0, 1.0e-15);
64          check(new Vector2D(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0)),
65                6.5, -13.0, 1.0e-15);
66          check(new Vector2D(2.0, new Vector2D(p25, m05), -3.0, new Vector2D(m05, p40)),
67                6.5, -13.0, 1.0e-15);
68          check(new Vector2D(p20, new Vector2D(p25, m05), m30, new Vector2D(m05, p40),
69                             p40, new Vector2D(p25, m30)),
70                16.5, -25.0, 1.0e-15);
71          check(new Vector2D(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0),
72                             p40, new Vector2D(2.5, -3.0)),
73                16.5, -25.0, 1.0e-15);
74          check(new Vector2D(2.0, new Vector2D(p25, m05), -3.0, new Vector2D(m05, p40),
75                             4.0, new Vector2D(p25, m30)),
76                16.5, -25.0, 1.0e-15);
77          check(new Vector2D(p20, new Vector2D(p25, m05), m30, new Vector2D(m05, p40),
78                             p40, new Vector2D(p25, m30), p10, new Vector2D(p10, p10)),
79                17.5, -24.0, 1.0e-15);
80          check(new Vector2D(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0),
81                             p40, new Vector2D(2.5, -3.0), p10, new Vector2D(1.0, 1.0)),
82                17.5, -24.0, 1.0e-15);
83          check(new Vector2D(2.0, new Vector2D(p25, m05), -3.0, new Vector2D(m05, p40),
84                             4.0, new Vector2D(p25, m30),  1.0, new Vector2D(p10, p10)),
85                17.5, -24.0, 1.0e-15);
86      }
87  
88      @Test public void testConstants() {
89          check(Vector2D.ZERO,    0.0,  0.0, 1.0e-15);
90          check(Vector2D.PLUS_I,   1.0,  0.0, 1.0e-15);
91          check(Vector2D.MINUS_I, -1.0,  0.0, 1.0e-15);
92          check(Vector2D.PLUS_J,   0.0,  1.0, 1.0e-15);
93          check(Vector2D.MINUS_J,  0.0, -1.0, 1.0e-15);
94          check(Vector2D.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0e-15);
95          check(Vector2D.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0e-15);
96          Assert.assertTrue(Double.isNaN(Vector2D.NaN.getX()));
97          Assert.assertTrue(Double.isNaN(Vector2D.NaN.getY()));
98          Assert.assertSame(Euclidean2D.getInstance(), Vector2D.NaN.getSpace());
99          Assert.assertSame(Vector2D.ZERO, new Vector2D(1.0, 2.0).getZero());
100     }
101 
102     @Test public void testToMethods() {
103         final Vector2D v = new Vector2D(2.5, -0.5);
104         Assert.assertEquals( 2,   v.toArray().length);
105         Assert.assertEquals( 2.5, v.toArray()[0], 1.0e-15);
106         Assert.assertEquals(-0.5, v.toArray()[1], 1.0e-15);
107         Assert.assertEquals("{2.5; -0.5}", v.toString().replaceAll(",", "."));
108         Assert.assertEquals("{2,5; -0,5}", v.toString(NumberFormat.getInstance(Locale.FRENCH)));
109     }
110 
111     @Test public void testNorms() {
112         final Vector2D v = new Vector2D(3.0, -4.0);
113         Assert.assertEquals( 7.0, v.getNorm1(),   1.0e-15);
114         Assert.assertEquals( 5.0, v.getNorm(),    1.0e-15);
115         Assert.assertEquals(25.0, v.getNormSq(),  1.0e-15);
116         Assert.assertEquals( 4.0, v.getNormInf(), 1.0e-15);
117     }
118 
119     @Test public void testDistances() {
120         final Vector2D u = new Vector2D( 2.0, -2.0);
121         final Vector2D v = new Vector2D(-1.0,  2.0);
122         Assert.assertEquals( 7.0, Vector2D.distance1(u, v),   1.0e-15);
123         Assert.assertEquals( 5.0, Vector2D.distance(u, v),    1.0e-15);
124         Assert.assertEquals(25.0, Vector2D.distanceSq(u, v),  1.0e-15);
125         Assert.assertEquals( 4.0, Vector2D.distanceInf(u, v), 1.0e-15);
126     }
127 
128     @Test public void testAdd() {
129         final Vector2D u = new Vector2D( 2.0, -2.0);
130         final Vector2D v = new Vector2D(-1.0,  2.0);
131         check(u.add(v), 1.0, 0.0, 1.0e-15);
132         check(u.add(5.0, v), -3.0, 8.0, 1.0e-15);
133     }
134 
135     @Test public void testSubtract() {
136         final Vector2D u = new Vector2D( 2.0, -2.0);
137         final Vector2D v = new Vector2D( 1.0, -2.0);
138         check(u.subtract(v), 1.0, 0.0, 1.0e-15);
139         check(u.subtract(5, v), -3.0, 8.0, 1.0e-15);
140     }
141 
142     @Test public void testNormalize() {
143         try {
144             Vector2D.ZERO.normalize();
145             Assert.fail("an exception should habe been thrown");
146         } catch (MathRuntimeException mre) {
147             Assert.assertEquals(LocalizedGeometryFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR, mre.getSpecifier());
148         }
149         check(new Vector2D(3, -4).normalize(), 0.6, -0.8, 1.0e-15);
150     }
151 
152     @Test public void testAngle() {
153         try {
154             Vector2D.angle(Vector2D.ZERO, Vector2D.PLUS_I);
155             Assert.fail("an exception should habe been thrown");
156         } catch (MathRuntimeException mre) {
157             Assert.assertEquals(LocalizedCoreFormats.ZERO_NORM, mre.getSpecifier());
158         }
159         final double alpha = 0.01;
160         final SinCos sc = FastMath.sinCos(alpha);
161         Assert.assertEquals(alpha,
162                             Vector2D.angle(new Vector2D(sc.cos(), sc.sin()),
163                                            Vector2D.PLUS_I),
164                             1.0e-15);
165         Assert.assertEquals(FastMath.PI - alpha,
166                             Vector2D.angle(new Vector2D(-sc.cos(), sc.sin()),
167                                            Vector2D.PLUS_I),
168                             1.0e-15);
169         Assert.assertEquals(0.5 * FastMath.PI - alpha,
170                             Vector2D.angle(new Vector2D(sc.sin(), sc.cos()),
171                                            Vector2D.PLUS_I),
172                             1.0e-15);
173         Assert.assertEquals(0.5 * FastMath.PI + alpha,
174                             Vector2D.angle(new Vector2D(-sc.sin(), sc.cos()),
175                                            Vector2D.PLUS_I),
176                             1.0e-15);
177     }
178 
179 
180     @Test public void testNegate() {
181         check(new Vector2D(3.0, -4.0).negate(), -3.0, 4.0, 1.0e-15);
182     }
183 
184     @Test public void testScalarMultiply() {
185         check(new Vector2D(3.0, -4.0).scalarMultiply(2.0), 6.0, -8.0, 1.0e-15);
186     }
187 
188     @Test public void testIsNaN() {
189         Assert.assertTrue(new Vector2D(Double.NaN, 0.0).isNaN());
190         Assert.assertTrue(new Vector2D(0.0, Double.NaN).isNaN());
191         Assert.assertTrue(new Vector2D(Double.NaN, Double.NaN).isNaN());
192         Assert.assertTrue(Vector2D.NaN.isNaN());
193         Assert.assertFalse(new Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isNaN());
194         Assert.assertFalse(Vector2D.MINUS_I.isNaN());
195     }
196 
197     @Test public void testIsInfinite() {
198         Assert.assertFalse(new Vector2D(Double.NaN, 0.0).isInfinite());
199         Assert.assertTrue(new Vector2D(Double.POSITIVE_INFINITY, 0.0).isInfinite());
200         Assert.assertTrue(new Vector2D(0.0, Double.POSITIVE_INFINITY).isInfinite());
201         Assert.assertTrue(new Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isInfinite());
202         Assert.assertTrue(new Vector2D(Double.NEGATIVE_INFINITY, 0.0).isInfinite());
203         Assert.assertTrue(new Vector2D(0.0, Double.NEGATIVE_INFINITY).isInfinite());
204         Assert.assertTrue(new Vector2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY).isInfinite());
205         Assert.assertFalse(Vector2D.NaN.isInfinite());
206         Assert.assertFalse(Vector2D.MINUS_I.isInfinite());
207     }
208 
209     @SuppressWarnings("unlikely-arg-type")
210     @Test public void testEquals() {
211         final Vector2D u1 = Vector2D.PLUS_I;
212         final Vector2D u2 = Vector2D.MINUS_I.negate();
213         final Vector2D v1 = new Vector2D(1.0, 0.001);
214         final Vector2D v2 = new Vector2D(0.001, 1.0);
215         Assert.assertTrue(u1.equals(u1));
216         Assert.assertTrue(u1.equals(u2));
217         Assert.assertFalse(u1.equals(v1));
218         Assert.assertFalse(u1.equals(v2));
219         Assert.assertFalse(u1.equals(FieldVector2D.getPlusI(Binary64Field.getInstance())));
220         Assert.assertTrue(new Vector2D(Double.NaN, u1).equals(Vector2D.NaN));
221         Assert.assertFalse(u1.equals(Vector2D.NaN));
222         Assert.assertFalse(Vector2D.NaN.equals(v2));
223     }
224 
225     @Test public void testEqualsIeee754() {
226         final Vector2D u1 = Vector2D.PLUS_I;
227         final Vector2D u2 = Vector2D.MINUS_I.negate();
228         final Vector2D v1 = new Vector2D(1.0, 0.001);
229         final Vector2D v2 = new Vector2D(0.001, 1.0);
230         Assert.assertTrue(u1.equalsIeee754(u1));
231         Assert.assertTrue(u1.equalsIeee754(u2));
232         Assert.assertFalse(u1.equalsIeee754(v1));
233         Assert.assertFalse(u1.equalsIeee754(v2));
234         Assert.assertFalse(u1.equalsIeee754(FieldVector2D.getPlusI(Binary64Field.getInstance())));
235         Assert.assertFalse(new Vector2D(Double.NaN, u1).equalsIeee754(Vector2D.NaN));
236         Assert.assertFalse(u1.equalsIeee754(Vector2D.NaN));
237         Assert.assertFalse(Vector2D.NaN.equalsIeee754(v2));
238         Assert.assertFalse(Vector2D.NaN.equalsIeee754(Vector2D.NaN));
239     }
240 
241     @Test public void testHashCode() {
242         Assert.assertEquals(542, Vector2D.NaN.hashCode());
243         Assert.assertEquals(1325400064, new Vector2D(1.5, -0.5).hashCode());
244     }
245 
246     @Test public void testCrossProduct() {
247         final double epsilon = 1e-10;
248 
249         Vector2D p1 = new Vector2D(1, 1);
250         Vector2D p2 = new Vector2D(2, 2);
251 
252         Vector2D p3 = new Vector2D(3, 3);
253         Assert.assertEquals(0.0, p3.crossProduct(p1, p2), epsilon);
254 
255         Vector2D p4 = new Vector2D(1, 2);
256         Assert.assertEquals(1.0, p4.crossProduct(p1, p2), epsilon);
257 
258         Vector2D p5 = new Vector2D(2, 1);
259         Assert.assertEquals(-1.0, p5.crossProduct(p1, p2), epsilon);
260 
261     }
262 
263     @Test public void testOrientation() {
264         Assert.assertTrue(Vector2D.orientation(new Vector2D(0, 0),
265                                                new Vector2D(1, 0),
266                                                new Vector2D(1, 1)) > 0);
267         Assert.assertTrue(Vector2D.orientation(new Vector2D(1, 0),
268                                                new Vector2D(0, 0),
269                                                new Vector2D(1, 1)) < 0);
270         Assert.assertEquals(0.0,
271                             Vector2D.orientation(new Vector2D(0, 0),
272                                                  new Vector2D(1, 0),
273                                                  new Vector2D(1, 0)),
274                             1.0e-15);
275         Assert.assertEquals(0.0,
276                             Vector2D.orientation(new Vector2D(0, 0),
277                                                  new Vector2D(1, 0),
278                                                  new Vector2D(2, 0)),
279                             1.0e-15);
280     }
281 
282     @Test
283     public void testArithmeticBlending() {
284 
285         // Given
286         final Vector2D v1 = new Vector2D(1,2);
287         final Vector2D v2 = new Vector2D(3,4);
288 
289         final double blendingValue = 0.7;
290 
291         // When
292         final Vector2D blendedVector = v1.blendArithmeticallyWith(v2, blendingValue);
293 
294         // Then
295         check(blendedVector, 2.4, 3.4, 1e-12);
296     }
297 
298     private void check(final Vector2D v, final double x, final double y, final double tol) {
299         Assert.assertEquals(x, v.getX(), tol);
300         Assert.assertEquals(y, v.getY(), tol);
301     }
302 
303 }