1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.geometry.euclidean.twod;
18
19 import java.text.NumberFormat;
20 import java.util.Locale;
21
22 import org.hipparchus.Field;
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.exception.LocalizedCoreFormats;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.exception.MathRuntimeException;
27 import org.hipparchus.geometry.LocalizedGeometryFormats;
28 import org.hipparchus.util.Binary64Field;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.MathArrays;
31 import org.hipparchus.util.SinCos;
32 import org.junit.Assert;
33 import org.junit.Test;
34
35 public class FieldVector2DTest {
36
37 @Test
38 public void testConstructors() {
39 doTestConstructors(Binary64Field.getInstance());
40 }
41
42 @Test
43 public void testConstants() {
44 doTestConstants(Binary64Field.getInstance());
45 }
46
47 @Test
48 public void testToMethods() {
49 doTestToMethods(Binary64Field.getInstance());
50 }
51
52 @Test
53 public void testNorms() {
54 doTestNorms(Binary64Field.getInstance());
55 }
56
57 @Test
58 public void testDistances() {
59 doTestDistances(Binary64Field.getInstance());
60 }
61
62 @Test
63 public void testAdd() {
64 doTestAdd(Binary64Field.getInstance());
65 }
66
67 @Test
68 public void testSubtract() {
69 doTestSubtract(Binary64Field.getInstance());
70 }
71
72 @Test
73 public void testNormalize() {
74 doTestNormalize(Binary64Field.getInstance());
75 }
76
77 @Test
78 public void testAngle() {
79 doTestAngle(Binary64Field.getInstance());
80 }
81
82 @Test
83 public void testNegate() {
84 doTestNegate(Binary64Field.getInstance());
85 }
86
87 @Test
88 public void testScalarMultiply() {
89 doTestScalarMultiply(Binary64Field.getInstance());
90 }
91
92 @Test
93 public void testIsNaN() {
94 doTestIsNaN(Binary64Field.getInstance());
95 }
96
97 @Test
98 public void testIsInfinite() {
99 doTestIsInfinite(Binary64Field.getInstance());
100 }
101
102 @Test
103 public void testEquals() {
104 doTestEquals(Binary64Field.getInstance());
105 }
106
107 @Test
108 public void testHashCode() {
109 doTestHashCode(Binary64Field.getInstance());
110 }
111
112 @Test
113 public void testCrossProduct() {
114 doTestCrossProduct(Binary64Field.getInstance());
115 }
116
117 @Test
118 public void testOrientation() {
119 doTestOrientation(Binary64Field.getInstance());
120 }
121
122 private <T extends CalculusFieldElement<T>> void doTestConstructors(final Field<T> field) {
123 final T p40 = field.getZero().add( 4.0);
124 final T p20 = field.getZero().add( 2.0);
125 final T p25 = field.getZero().add( 2.5);
126 final T p10 = field.getOne();
127 final T m05 = field.getZero().add(-0.5);
128 final T m30 = field.getZero().add(-3.0);
129 check(new FieldVector2D<>(p25, m05), 2.5, -0.5, 1.0e-15);
130 final T[] a = MathArrays.buildArray(field, 2);
131 a[0] = field.getOne();
132 a[1] = field.getZero();
133 check(new FieldVector2D<>(a), 1.0, 0.0, 1.0e-15);
134 try {
135 new FieldVector2D<>(MathArrays.buildArray(field, 3));
136 Assert.fail("an exception should have been thrown");
137 } catch (MathIllegalArgumentException miae) {
138 Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
139 Assert.assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
140 Assert.assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
141 }
142 check(new FieldVector2D<>(p20, new FieldVector2D<>(p25, m05)), 5.0, -1.0, 1.0e-15);
143 check(new FieldVector2D<>(p20, new Vector2D(2.5, -0.5)), 5.0, -1.0, 1.0e-15);
144 check(new FieldVector2D<>(2, new FieldVector2D<>(p25, m05)), 5.0, -1.0, 1.0e-15);
145 check(new FieldVector2D<>(p20, new FieldVector2D<>(p25, m05), m30, new FieldVector2D<>(m05, p40)),
146 6.5, -13.0, 1.0e-15);
147 check(new FieldVector2D<>(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0)),
148 6.5, -13.0, 1.0e-15);
149 check(new FieldVector2D<>(2.0, new FieldVector2D<>(p25, m05), -3.0, new FieldVector2D<>(m05, p40)),
150 6.5, -13.0, 1.0e-15);
151 check(new FieldVector2D<>(p20, new FieldVector2D<>(p25, m05), m30, new FieldVector2D<>(m05, p40),
152 p40, new FieldVector2D<>(p25, m30)),
153 16.5, -25.0, 1.0e-15);
154 check(new FieldVector2D<>(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0),
155 p40, new Vector2D(2.5, -3.0)),
156 16.5, -25.0, 1.0e-15);
157 check(new FieldVector2D<>(2.0, new FieldVector2D<>(p25, m05), -3.0, new FieldVector2D<>(m05, p40),
158 4.0, new FieldVector2D<>(p25, m30)),
159 16.5, -25.0, 1.0e-15);
160 check(new FieldVector2D<>(p20, new FieldVector2D<>(p25, m05), m30, new FieldVector2D<>(m05, p40),
161 p40, new FieldVector2D<>(p25, m30), p10, new FieldVector2D<>(p10, p10)),
162 17.5, -24.0, 1.0e-15);
163 check(new FieldVector2D<>(p20, new Vector2D(2.5, -0.5), m30, new Vector2D(-0.5, 4.0),
164 p40, new Vector2D(2.5, -3.0), p10, new Vector2D(1.0, 1.0)),
165 17.5, -24.0, 1.0e-15);
166 check(new FieldVector2D<>(2.0, new FieldVector2D<>(p25, m05), -3.0, new FieldVector2D<>(m05, p40),
167 4.0, new FieldVector2D<>(p25, m30), 1.0, new FieldVector2D<>(p10, p10)),
168 17.5, -24.0, 1.0e-15);
169 }
170
171 private <T extends CalculusFieldElement<T>> void doTestConstants(final Field<T> field) {
172 check(FieldVector2D.getZero(field), 0.0, 0.0, 1.0e-15);
173 check(FieldVector2D.getPlusI(field), 1.0, 0.0, 1.0e-15);
174 check(FieldVector2D.getMinusI(field), -1.0, 0.0, 1.0e-15);
175 check(FieldVector2D.getPlusJ(field), 0.0, 1.0, 1.0e-15);
176 check(FieldVector2D.getMinusJ(field), 0.0, -1.0, 1.0e-15);
177 check(FieldVector2D.getPositiveInfinity(field), Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0e-15);
178 check(FieldVector2D.getNegativeInfinity(field), Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0e-15);
179 Assert.assertTrue(Double.isNaN(FieldVector2D.getNaN(field).getX().getReal()));
180 Assert.assertTrue(Double.isNaN(FieldVector2D.getNaN(field).getY().getReal()));
181 }
182
183 private <T extends CalculusFieldElement<T>> void doTestToMethods(final Field<T> field) {
184 final FieldVector2D<T> v = new FieldVector2D<>(field, new Vector2D(2.5, -0.5));
185 Assert.assertEquals( 2, v.toArray().length);
186 Assert.assertEquals( 2.5, v.toArray()[0].getReal(), 1.0e-15);
187 Assert.assertEquals(-0.5, v.toArray()[1].getReal(), 1.0e-15);
188 Assert.assertEquals(new Vector2D(2.5, -0.5), v.toVector2D());
189 Assert.assertEquals("{2.5; -0.5}", v.toString().replaceAll(",", "."));
190 Assert.assertEquals("{2,5; -0,5}", v.toString(NumberFormat.getInstance(Locale.FRENCH)));
191 }
192
193 private <T extends CalculusFieldElement<T>> void doTestNorms(final Field<T> field) {
194 final FieldVector2D<T> v = new FieldVector2D<>(field, new Vector2D(3.0, -4.0));
195 Assert.assertEquals( 7.0, v.getNorm1().getReal(), 1.0e-15);
196 Assert.assertEquals( 5.0, v.getNorm().getReal(), 1.0e-15);
197 Assert.assertEquals(25.0, v.getNormSq().getReal(), 1.0e-15);
198 Assert.assertEquals( 4.0, v.getNormInf().getReal(), 1.0e-15);
199 }
200
201 private <T extends CalculusFieldElement<T>> void doTestDistances(final Field<T> field) {
202 final FieldVector2D<T> u = new FieldVector2D<>(field, new Vector2D( 2.0, -2.0));
203 final FieldVector2D<T> v = new FieldVector2D<>(field, new Vector2D(-1.0, 2.0));
204 Assert.assertEquals( 7.0, FieldVector2D.distance1(u, v).getReal(), 1.0e-15);
205 Assert.assertEquals( 5.0, FieldVector2D.distance(u, v).getReal(), 1.0e-15);
206 Assert.assertEquals(25.0, FieldVector2D.distanceSq(u, v).getReal(), 1.0e-15);
207 Assert.assertEquals( 4.0, FieldVector2D.distanceInf(u, v).getReal(), 1.0e-15);
208 Assert.assertEquals( 7.0, FieldVector2D.distance1(u, v.toVector2D()).getReal(), 1.0e-15);
209 Assert.assertEquals( 5.0, FieldVector2D.distance(u, v.toVector2D()).getReal(), 1.0e-15);
210 Assert.assertEquals(25.0, FieldVector2D.distanceSq(u, v.toVector2D()).getReal(), 1.0e-15);
211 Assert.assertEquals( 4.0, FieldVector2D.distanceInf(u, v.toVector2D()).getReal(), 1.0e-15);
212 Assert.assertEquals( 7.0, FieldVector2D.distance1(u.toVector2D(), v).getReal(), 1.0e-15);
213 Assert.assertEquals( 5.0, FieldVector2D.distance(u.toVector2D(), v).getReal(), 1.0e-15);
214 Assert.assertEquals(25.0, FieldVector2D.distanceSq(u.toVector2D(), v).getReal(), 1.0e-15);
215 Assert.assertEquals( 4.0, FieldVector2D.distanceInf(u.toVector2D(), v).getReal(), 1.0e-15);
216 }
217
218 private <T extends CalculusFieldElement<T>> void doTestAdd(final Field<T> field) {
219 final FieldVector2D<T> u = new FieldVector2D<>(field, new Vector2D( 2.0, -2.0));
220 final FieldVector2D<T> v = new FieldVector2D<>(field, new Vector2D(-1.0, 2.0));
221 check(u.add(v), 1.0, 0.0, 1.0e-15);
222 check(u.add(v.toVector2D()), 1.0, 0.0, 1.0e-15);
223 check(u.add(field.getZero().add(5), v), -3.0, 8.0, 1.0e-15);
224 check(u.add(field.getZero().add(5), v.toVector2D()), -3.0, 8.0, 1.0e-15);
225 check(u.add(5.0, v), -3.0, 8.0, 1.0e-15);
226 check(u.add(5.0, v.toVector2D()), -3.0, 8.0, 1.0e-15);
227 }
228
229 private <T extends CalculusFieldElement<T>> void doTestSubtract(final Field<T> field) {
230 final FieldVector2D<T> u = new FieldVector2D<>(field, new Vector2D( 2.0, -2.0));
231 final FieldVector2D<T> v = new FieldVector2D<>(field, new Vector2D( 1.0, -2.0));
232 check(u.subtract(v), 1.0, 0.0, 1.0e-15);
233 check(u.subtract(v.toVector2D()), 1.0, 0.0, 1.0e-15);
234 check(u.subtract(field.getZero().add(5), v), -3.0, 8.0, 1.0e-15);
235 check(u.subtract(field.getZero().add(5), v.toVector2D()), -3.0, 8.0, 1.0e-15);
236 check(u.subtract(5.0, v), -3.0, 8.0, 1.0e-15);
237 check(u.subtract(5.0, v.toVector2D()), -3.0, 8.0, 1.0e-15);
238 }
239
240 private <T extends CalculusFieldElement<T>> void doTestNormalize(final Field<T> field) {
241 try {
242 FieldVector2D.getZero(field).normalize();
243 Assert.fail("an exception should habe been thrown");
244 } catch (MathRuntimeException mre) {
245 Assert.assertEquals(LocalizedGeometryFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR, mre.getSpecifier());
246 }
247 check(new FieldVector2D<>(field, new Vector2D(3, -4)).normalize(), 0.6, -0.8, 1.0e-15);
248 }
249
250 private <T extends CalculusFieldElement<T>> void doTestAngle(final Field<T> field) {
251 try {
252 FieldVector2D.angle(FieldVector2D.getZero(field), FieldVector2D.getPlusI(field));
253 Assert.fail("an exception should habe been thrown");
254 } catch (MathRuntimeException mre) {
255 Assert.assertEquals(LocalizedCoreFormats.ZERO_NORM, mre.getSpecifier());
256 }
257 final double alpha = 0.01;
258 final SinCos sc = FastMath.sinCos(alpha);
259 Assert.assertEquals(alpha,
260 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(sc.cos(), sc.sin())),
261 FieldVector2D.getPlusI(field)).getReal(),
262 1.0e-15);
263 Assert.assertEquals(FastMath.PI - alpha,
264 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(-sc.cos(), sc.sin())),
265 FieldVector2D.getPlusI(field)).getReal(),
266 1.0e-15);
267 Assert.assertEquals(0.5 * FastMath.PI - alpha,
268 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(sc.sin(), sc.cos())),
269 FieldVector2D.getPlusI(field)).getReal(),
270 1.0e-15);
271 Assert.assertEquals(0.5 * FastMath.PI + alpha,
272 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(-sc.sin(), sc.cos())),
273 FieldVector2D.getPlusI(field)).getReal(),
274 1.0e-15);
275 try {
276 FieldVector2D.angle(FieldVector2D.getZero(field), Vector2D.PLUS_I);
277 Assert.fail("an exception should habe been thrown");
278 } catch (MathRuntimeException mre) {
279 Assert.assertEquals(LocalizedCoreFormats.ZERO_NORM, mre.getSpecifier());
280 }
281 Assert.assertEquals(alpha,
282 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(sc.cos(), sc.sin())),
283 Vector2D.PLUS_I).getReal(),
284 1.0e-15);
285 Assert.assertEquals(FastMath.PI - alpha,
286 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(-sc.cos(), sc.sin())),
287 Vector2D.PLUS_I).getReal(),
288 1.0e-15);
289 Assert.assertEquals(0.5 * FastMath.PI - alpha,
290 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(sc.sin(), sc.cos())),
291 Vector2D.PLUS_I).getReal(),
292 1.0e-15);
293 Assert.assertEquals(0.5 * FastMath.PI + alpha,
294 FieldVector2D.angle(new FieldVector2D<>(field, new Vector2D(-sc.sin(), sc.cos())),
295 Vector2D.PLUS_I).getReal(),
296 1.0e-15);
297 try {
298 FieldVector2D.angle(Vector2D.ZERO, FieldVector2D.getPlusI(field));
299 Assert.fail("an exception should habe been thrown");
300 } catch (MathRuntimeException mre) {
301 Assert.assertEquals(LocalizedCoreFormats.ZERO_NORM, mre.getSpecifier());
302 }
303 Assert.assertEquals(alpha,
304 FieldVector2D.angle(new Vector2D(sc.cos(), sc.sin()),
305 FieldVector2D.getPlusI(field)).getReal(),
306 1.0e-15);
307 Assert.assertEquals(FastMath.PI - alpha,
308 FieldVector2D.angle(new Vector2D(-sc.cos(), sc.sin()),
309 FieldVector2D.getPlusI(field)).getReal(),
310 1.0e-15);
311 Assert.assertEquals(0.5 * FastMath.PI - alpha,
312 FieldVector2D.angle(new Vector2D(sc.sin(), sc.cos()),
313 FieldVector2D.getPlusI(field)).getReal(),
314 1.0e-15);
315 Assert.assertEquals(0.5 * FastMath.PI + alpha,
316 FieldVector2D.angle(new Vector2D(-sc.sin(), sc.cos()),
317 FieldVector2D.getPlusI(field)).getReal(),
318 1.0e-15);
319 }
320
321
322 private <T extends CalculusFieldElement<T>> void doTestNegate(final Field<T> field) {
323 check(new FieldVector2D<>(field, new Vector2D(3.0, -4.0)).negate(), -3.0, 4.0, 1.0e-15);
324 }
325
326 private <T extends CalculusFieldElement<T>> void doTestScalarMultiply(final Field<T> field) {
327 check(new FieldVector2D<>(field, new Vector2D(3.0, -4.0)).scalarMultiply(2.0), 6.0, -8.0, 1.0e-15);
328 check(new FieldVector2D<>(field, new Vector2D(3.0, -4.0)).scalarMultiply(field.getZero().add(2.0)), 6.0, -8.0, 1.0e-15);
329 }
330
331 private <T extends CalculusFieldElement<T>> void doTestIsNaN(final Field<T> field) {
332 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.NaN, 0.0)).isNaN());
333 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(0.0, Double.NaN)).isNaN());
334 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.NaN, Double.NaN)).isNaN());
335 Assert.assertTrue(FieldVector2D.getNaN(field).isNaN());
336 Assert.assertFalse(new FieldVector2D<>(field, new Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)).isNaN());
337 Assert.assertFalse(FieldVector2D.getMinusI(field).isNaN());
338 }
339
340 private <T extends CalculusFieldElement<T>> void doTestIsInfinite(final Field<T> field) {
341 Assert.assertFalse(new FieldVector2D<>(field, new Vector2D(Double.NaN, 0.0)).isInfinite());
342 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.POSITIVE_INFINITY, 0.0)).isInfinite());
343 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(0.0, Double.POSITIVE_INFINITY)).isInfinite());
344 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)).isInfinite());
345 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.NEGATIVE_INFINITY, 0.0)).isInfinite());
346 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(0.0, Double.NEGATIVE_INFINITY)).isInfinite());
347 Assert.assertTrue(new FieldVector2D<>(field, new Vector2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY)).isInfinite());
348 Assert.assertFalse(FieldVector2D.getNaN(field).isInfinite());
349 Assert.assertFalse(FieldVector2D.getMinusI(field).isInfinite());
350 }
351
352 private <T extends CalculusFieldElement<T>> void doTestEquals(final Field<T> field) {
353 final FieldVector2D<T> u1 = new FieldVector2D<>(field, Vector2D.PLUS_I);
354 final FieldVector2D<T> u2 = new FieldVector2D<>(field, Vector2D.MINUS_I.negate());
355 final FieldVector2D<T> v1 = new FieldVector2D<>(field, new Vector2D(1.0, 0.001));
356 final FieldVector2D<T> v2 = new FieldVector2D<>(field, new Vector2D(0.001, 1.0));
357 Assert.assertEquals(u1, u1);
358 Assert.assertEquals(u1, u2);
359 Assert.assertNotEquals(u1, v1);
360 Assert.assertNotEquals(u1, v2);
361 Assert.assertNotEquals(u1, Vector2D.PLUS_I);
362 Assert.assertEquals(u1.toVector2D(), Vector2D.PLUS_I);
363 Assert.assertEquals(new FieldVector2D<>(Double.NaN, u1), FieldVector2D.getNaN(field));
364 Assert.assertNotEquals(u1, FieldVector2D.getNaN(field));
365 Assert.assertNotEquals(FieldVector2D.getNaN(field), v2);
366 }
367
368 private <T extends CalculusFieldElement<T>> void doTestHashCode(final Field<T> field) {
369 Assert.assertEquals(542, FieldVector2D.getNaN(field).hashCode());
370 Assert.assertEquals(1325400064, new FieldVector2D<>(field, new Vector2D(1.5, -0.5)).hashCode());
371 }
372
373 private <T extends CalculusFieldElement<T>> void doTestCrossProduct(final Field<T> field) {
374 final double epsilon = 1e-10;
375
376 FieldVector2D<T> p1 = new FieldVector2D<>(field, new Vector2D(1, 1));
377 FieldVector2D<T> p2 = new FieldVector2D<>(field, new Vector2D(2, 2));
378
379 FieldVector2D<T> p3 = new FieldVector2D<>(field, new Vector2D(3, 3));
380 Assert.assertEquals(0.0, p3.crossProduct(p1, p2).getReal(), epsilon);
381
382 FieldVector2D<T> p4 = new FieldVector2D<>(field, new Vector2D(1, 2));
383 Assert.assertEquals(1.0, p4.crossProduct(p1, p2).getReal(), epsilon);
384
385 FieldVector2D<T> p5 = new FieldVector2D<>(field, new Vector2D(2, 1));
386 Assert.assertEquals(-1.0, p5.crossProduct(p1, p2).getReal(), epsilon);
387 Assert.assertEquals(-1.0, p5.crossProduct(p1.toVector2D(), p2.toVector2D()).getReal(), epsilon);
388 }
389
390 private <T extends CalculusFieldElement<T>> void doTestOrientation(final Field<T> field) {
391 Assert.assertTrue(FieldVector2D.orientation(new FieldVector2D<>(field, new Vector2D(0, 0)),
392 new FieldVector2D<>(field, new Vector2D(1, 0)),
393 new FieldVector2D<>(field, new Vector2D(1, 1))).getReal() > 0);
394 Assert.assertTrue(FieldVector2D.orientation(new FieldVector2D<>(field, new Vector2D(1, 0)),
395 new FieldVector2D<>(field, new Vector2D(0, 0)),
396 new FieldVector2D<>(field, new Vector2D(1, 1))).getReal() < 0);
397 Assert.assertEquals(0.0,
398 FieldVector2D.orientation(new FieldVector2D<>(field, new Vector2D(0, 0)),
399 new FieldVector2D<>(field, new Vector2D(1, 0)),
400 new FieldVector2D<>(field, new Vector2D(1, 0))).getReal(),
401 1.0e-15);
402 Assert.assertEquals(0.0,
403 FieldVector2D.orientation(new FieldVector2D<>(field, new Vector2D(0, 0)),
404 new FieldVector2D<>(field, new Vector2D(1, 0)),
405 new FieldVector2D<>(field, new Vector2D(2, 0))).getReal(),
406 1.0e-15);
407 }
408
409 private <T extends CalculusFieldElement<T>> void check(final FieldVector2D<T> v,
410 final double x, final double y, final double tol) {
411 Assert.assertEquals(x, v.getX().getReal(), tol);
412 Assert.assertEquals(y, v.getY().getReal(), tol);
413 }
414
415 }