1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
292 final Vector2D blendedVector = v1.blendArithmeticallyWith(v2, blendingValue);
293
294
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 }