001/**
002 * Copyright (c) 2008-2014 Ardor Labs, Inc.
003 *
004 * This file is part of Ardor3D.
005 *
006 * Ardor3D is free software: you can redistribute it and/or modify it 
007 * under the terms of its license which may be found in the accompanying
008 * LICENSE file or at <http://www.ardor3d.com/LICENSE>.
009 */
010
011package com.ardor3d.math;
012
013import static org.junit.Assert.*;
014
015import org.junit.Test;
016
017public class TestVector2 {
018
019    @Test
020    public void testAdd() {
021        final Vector2 vec1 = new Vector2();
022        final Vector2 vec2 = new Vector2(Vector2.ONE);
023
024        vec1.addLocal(1, 2);
025        assertEquals(new Vector2(1, 2), vec1);
026        vec1.addLocal(-1, -2);
027        assertEquals(Vector2.ZERO, vec1);
028
029        vec1.zero();
030        vec1.addLocal(vec2);
031        assertEquals(Vector2.ONE, vec1);
032
033        vec1.zero();
034        final Vector2 vec3 = vec1.add(vec2, new Vector2());
035        assertEquals(Vector2.ZERO, vec1);
036        assertEquals(Vector2.ONE, vec3);
037
038        final Vector2 vec4 = vec1.add(1, 0, null);
039        assertEquals(Vector2.ZERO, vec1);
040        assertEquals(Vector2.UNIT_X, vec4);
041    }
042
043    @Test
044    public void testSubtract() {
045        final Vector2 vec1 = new Vector2();
046        final Vector2 vec2 = new Vector2(Vector2.ONE);
047
048        vec1.subtractLocal(1, 2);
049        assertEquals(new Vector2(-1, -2), vec1);
050        vec1.subtractLocal(-1, -2);
051        assertEquals(Vector2.ZERO, vec1);
052
053        vec1.zero();
054        vec1.subtractLocal(vec2);
055        assertEquals(Vector2.NEG_ONE, vec1);
056
057        vec1.zero();
058        final Vector2 vec3 = vec1.subtract(vec2, new Vector2());
059        assertEquals(Vector2.ZERO, vec1);
060        assertEquals(Vector2.NEG_ONE, vec3);
061
062        final Vector2 vec4 = vec1.subtract(1, 0, null);
063        assertEquals(Vector2.ZERO, vec1);
064        assertEquals(Vector2.NEG_UNIT_X, vec4);
065    }
066
067    @Test
068    public void testGetSet() {
069        final Vector2 vec1 = new Vector2();
070        vec1.setX(0);
071        assertTrue(vec1.getX() == 0.0);
072        vec1.setX(Double.POSITIVE_INFINITY);
073        assertTrue(vec1.getX() == Double.POSITIVE_INFINITY);
074        vec1.setX(Double.NEGATIVE_INFINITY);
075        assertTrue(vec1.getX() == Double.NEGATIVE_INFINITY);
076        assertTrue(vec1.getValue(0) == Double.NEGATIVE_INFINITY);
077
078        vec1.setY(0);
079        assertTrue(vec1.getY() == 0.0);
080        vec1.setY(Double.POSITIVE_INFINITY);
081        assertTrue(vec1.getY() == Double.POSITIVE_INFINITY);
082        vec1.setY(Double.NEGATIVE_INFINITY);
083        assertTrue(vec1.getY() == Double.NEGATIVE_INFINITY);
084        assertTrue(vec1.getValue(1) == Double.NEGATIVE_INFINITY);
085
086        vec1.set(Math.PI, Math.PI);
087        assertTrue(vec1.getXf() == (float) Math.PI);
088        assertTrue(vec1.getYf() == (float) Math.PI);
089
090        final Vector2 vec2 = new Vector2();
091        vec2.set(vec1);
092        assertEquals(vec1, vec2);
093
094        vec1.setValue(0, 0);
095        vec1.setValue(1, 0);
096        assertEquals(Vector2.ZERO, vec1);
097
098        // catch a few expected exceptions
099        try {
100            vec2.getValue(2);
101            fail("getValue(2) should have thrown IllegalArgumentException.");
102        } catch (final IllegalArgumentException e) {
103        }
104        try {
105            vec2.getValue(-1);
106            fail("getValue(-1) should have thrown IllegalArgumentException.");
107        } catch (final IllegalArgumentException e) {
108        }
109        try {
110            vec2.setValue(-1, 0);
111            fail("setValue(-1, 0) should have thrown IllegalArgumentException.");
112        } catch (final IllegalArgumentException e) {
113        }
114        try {
115            vec2.setValue(2, 0);
116            fail("setValue(2, 0) should have thrown IllegalArgumentException.");
117        } catch (final IllegalArgumentException e) {
118        }
119        // above exceptions shouldn't have altered vec2
120        assertEquals(new Vector2(Math.PI, Math.PI), vec2);
121    }
122
123    @Test
124    public void testPolarAngle() {
125        final Vector2 vec1 = new Vector2();
126        assertTrue(0.0 == vec1.getPolarAngle());
127
128        vec1.set(1.0, 0.0); // 0
129        assertTrue(Math.abs(0 - vec1.getPolarAngle()) <= MathUtils.EPSILON);
130
131        vec1.set(0.0, 1.0); // -HALF_PI
132        assertTrue(Math.abs(-MathUtils.HALF_PI - vec1.getPolarAngle()) <= MathUtils.EPSILON);
133
134        vec1.set(-1.0, 0.0); // -PI
135        assertTrue(Math.abs(-MathUtils.PI - vec1.getPolarAngle()) <= MathUtils.EPSILON);
136
137        vec1.set(0, -1.0); // HALF_PI
138        assertTrue(Math.abs(MathUtils.HALF_PI - vec1.getPolarAngle()) <= MathUtils.EPSILON);
139    }
140
141    @Test
142    public void testToArray() {
143        final Vector2 vec1 = new Vector2();
144        vec1.set(Math.PI, Double.MAX_VALUE);
145        final double[] array = vec1.toArray(null);
146        final double[] array2 = vec1.toArray(new double[2]);
147        assertNotNull(array);
148        assertTrue(array.length == 2);
149        assertTrue(array[0] == Math.PI);
150        assertTrue(array[1] == Double.MAX_VALUE);
151        assertNotNull(array2);
152        assertTrue(array2.length == 2);
153        assertTrue(array2[0] == Math.PI);
154        assertTrue(array2[1] == Double.MAX_VALUE);
155
156        try {
157            vec1.toArray(new double[1]);
158            fail("toArray(d[1]) should have thrown ArrayIndexOutOfBoundsException.");
159        } catch (final ArrayIndexOutOfBoundsException e) {
160        }
161    }
162
163    @Test
164    public void testMultiply() {
165        final Vector2 vec1 = new Vector2(1, -1);
166        final Vector2 vec2 = vec1.multiply(2.0, null);
167        final Vector2 vec2B = vec1.multiply(2.0, new Vector2());
168        assertEquals(new Vector2(2.0, -2.0), vec2);
169        assertEquals(new Vector2(2.0, -2.0), vec2B);
170
171        vec2.multiplyLocal(0.5);
172        assertEquals(new Vector2(1.0, -1.0), vec2);
173
174        final Vector2 vec3 = vec1.multiply(vec2, null);
175        final Vector2 vec3B = vec1.multiply(vec2, new Vector2());
176        assertEquals(Vector2.ONE, vec3);
177        assertEquals(Vector2.ONE, vec3B);
178
179        final Vector2 vec4 = vec1.multiply(2, 3, null);
180        final Vector2 vec4B = vec1.multiply(2, 3, new Vector2());
181        assertEquals(new Vector2(2, -3), vec4);
182        assertEquals(new Vector2(2, -3), vec4B);
183
184        vec1.multiplyLocal(0.5, 0.5);
185        assertEquals(new Vector2(0.5, -0.5), vec1);
186
187        vec1.multiplyLocal(vec2);
188        assertEquals(new Vector2(0.5, 0.5), vec1);
189    }
190
191    @Test
192    public void testDivide() {
193        final Vector2 vec1 = new Vector2(1, -1);
194        final Vector2 vec2 = vec1.divide(2.0, null);
195        final Vector2 vec2B = vec1.divide(2.0, new Vector2());
196        assertEquals(new Vector2(0.5, -0.5), vec2);
197        assertEquals(new Vector2(0.5, -0.5), vec2B);
198
199        vec2.divideLocal(0.5);
200        assertEquals(new Vector2(1.0, -1.0), vec2);
201
202        final Vector2 vec3 = vec1.divide(vec2, null);
203        final Vector2 vec3B = vec1.divide(vec2, new Vector2());
204        assertEquals(Vector2.ONE, vec3);
205        assertEquals(Vector2.ONE, vec3B);
206
207        final Vector2 vec4 = vec1.divide(2, 3, null);
208        final Vector2 vec4B = vec1.divide(2, 3, new Vector2());
209        assertEquals(new Vector2(1 / 2., -1 / 3.), vec4);
210        assertEquals(new Vector2(1 / 2., -1 / 3.), vec4B);
211
212        vec1.divideLocal(0.5, 0.5);
213        assertEquals(new Vector2(2, -2), vec1);
214
215        vec1.divideLocal(vec2);
216        assertEquals(new Vector2(2, 2), vec1);
217    }
218
219    @Test
220    public void testScaleAdd() {
221        final Vector2 vec1 = new Vector2(1, 1);
222        final Vector2 vec2 = vec1.scaleAdd(2.0, new Vector2(1, 2), null);
223        final Vector2 vec2B = vec1.scaleAdd(2.0, new Vector2(1, 2), new Vector2());
224        assertEquals(new Vector2(3.0, 4.0), vec2);
225        assertEquals(new Vector2(3.0, 4.0), vec2B);
226
227        vec1.scaleAddLocal(2.0, new Vector2(1, 2));
228        assertEquals(vec2, vec1);
229    }
230
231    @Test
232    public void testNegate() {
233        final Vector2 vec1 = new Vector2(2, 1);
234        final Vector2 vec2 = vec1.negate(null);
235        assertEquals(new Vector2(-2, -1), vec2);
236
237        vec1.negateLocal();
238        assertEquals(vec2, vec1);
239    }
240
241    @Test
242    public void testNormalize() {
243        final Vector2 vec1 = new Vector2(2, 1);
244        assertTrue(vec1.length() == Math.sqrt(5));
245
246        final Vector2 vec2 = vec1.normalize(null);
247        final double invLength = MathUtils.inverseSqrt(2 * 2 + 1 * 1);
248        assertEquals(new Vector2(2 * invLength, 1 * invLength), vec2);
249
250        vec1.normalizeLocal();
251        assertEquals(new Vector2(2 * invLength, 1 * invLength), vec1);
252
253        vec1.zero();
254        vec1.normalize(vec2);
255        assertEquals(vec1, vec2);
256
257        // ensure no exception thrown
258        vec1.normalizeLocal();
259        vec1.normalize(null);
260    }
261
262    @Test
263    public void testDistance() {
264        final Vector2 vec1 = new Vector2(0, 0);
265        assertTrue(3.0 == vec1.distance(0, 3));
266        assertTrue(4.0 == vec1.distance(4, 0));
267
268        final Vector2 vec2 = new Vector2(1, 1);
269        assertTrue(Math.sqrt(2) == vec1.distance(vec2));
270    }
271
272    @Test
273    public void testLerp() {
274        final Vector2 vec1 = new Vector2(8, 3);
275        final Vector2 vec2 = new Vector2(2, 1);
276        assertEquals(new Vector2(5, 2), vec1.lerp(vec2, 0.5, null));
277        assertEquals(new Vector2(5, 2), vec1.lerp(vec2, 0.5, new Vector2()));
278        assertEquals(new Vector2(5, 2), Vector2.lerp(vec1, vec2, 0.5, null));
279        assertEquals(new Vector2(5, 2), Vector2.lerp(vec1, vec2, 0.5, new Vector2()));
280
281        vec1.set(14, 5);
282        vec1.lerpLocal(vec2, 0.25);
283        assertEquals(new Vector2(11, 4), vec1);
284
285        vec1.set(15, 7);
286        final Vector2 vec3 = new Vector2(-1, -1);
287        vec3.lerpLocal(vec1, vec2, 0.5);
288        assertEquals(new Vector2(8.5, 4.0), vec3);
289    }
290
291    @Test
292    public void testRotate() {
293        final Vector2 vec1 = new Vector2(1, 0);
294        final Vector2 vec2 = vec1.rotateAroundOrigin(MathUtils.HALF_PI, true, null);
295        final Vector2 vec2B = vec1.rotateAroundOrigin(MathUtils.HALF_PI, false, new Vector2());
296        assertEquals(new Vector2(0, -1), vec2);
297        assertEquals(new Vector2(0, 1), vec2B);
298        vec2.rotateAroundOriginLocal(MathUtils.HALF_PI, false);
299        assertEquals(new Vector2(1, 0), vec2);
300        vec2.rotateAroundOriginLocal(MathUtils.PI, true);
301        assertTrue(Math.abs(vec2.getX() - -1) <= MathUtils.EPSILON);
302        assertTrue(Math.abs(vec2.getY() - 0) <= MathUtils.EPSILON);
303    }
304
305    @Test
306    public void testAngle() {
307        final Vector2 vec1 = new Vector2(1, 0);
308        assertTrue(MathUtils.HALF_PI == vec1.angleBetween(new Vector2(0, 1)));
309        assertTrue(-MathUtils.HALF_PI == vec1.angleBetween(new Vector2(0, -1)));
310
311        assertTrue(MathUtils.HALF_PI == vec1.smallestAngleBetween(new Vector2(0, -1)));
312    }
313
314    @Test
315    public void testDot() {
316        final Vector2 vec1 = new Vector2(7, 2);
317        assertTrue(23.0 == vec1.dot(3, 1));
318
319        assertTrue(-5.0 == vec1.dot(new Vector2(-1, 1)));
320    }
321
322    @Test
323    public void testClone() {
324        final Vector2 vec1 = new Vector2(0, 0);
325        final Vector2 vec2 = vec1.clone();
326        assertEquals(vec1, vec2);
327        assertNotSame(vec1, vec2);
328    }
329
330    @Test
331    public void testValid() {
332        final Vector2 vec1 = new Vector2(0, 0);
333        final Vector2 vec2 = new Vector2(Double.POSITIVE_INFINITY, 0);
334        final Vector2 vec3 = new Vector2(0, Double.NEGATIVE_INFINITY);
335        final Vector2 vec4 = new Vector2(Double.NaN, 0);
336        final Vector2 vec5 = new Vector2(0, Double.NaN);
337
338        assertTrue(Vector2.isValid(vec1));
339        assertFalse(Vector2.isValid(vec2));
340        assertFalse(Vector2.isValid(vec3));
341        assertFalse(Vector2.isValid(vec4));
342        assertFalse(Vector2.isValid(vec5));
343
344        vec5.zero();
345        assertTrue(Vector2.isValid(vec5));
346
347        assertFalse(Vector2.isValid(null));
348
349        // couple of equals validity tests
350        assertEquals(vec1, vec1);
351        assertFalse(vec1.equals(null));
352        assertFalse(vec1.equals(new Vector3()));
353
354        // throw in a couple pool accesses for coverage
355        final Vector2 vec6 = Vector2.fetchTempInstance();
356        vec6.set(vec1);
357        assertEquals(vec1, vec6);
358        assertNotSame(vec1, vec6);
359        Vector2.releaseTempInstance(vec6);
360
361        // cover more of equals
362        vec1.set(0, 1);
363        assertFalse(vec1.equals(new Vector2(0, 2)));
364    }
365
366    @Test
367    public void testSimpleHash() {
368        // Just a simple sanity check.
369        final Vector2 vec1 = new Vector2(1, 2);
370        final Vector2 vec2 = new Vector2(1, 2);
371        final Vector2 vec3 = new Vector2(2, 2);
372
373        assertTrue(vec1.hashCode() == vec2.hashCode());
374        assertTrue(vec1.hashCode() != vec3.hashCode());
375    }
376}