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 TestVector4 {
018
019    @Test
020    public void testAdd() {
021        final Vector4 vec1 = new Vector4();
022        final Vector4 vec2 = new Vector4(Vector4.ONE);
023
024        vec1.addLocal(1, 2, 3, 4);
025        assertEquals(new Vector4(1, 2, 3, 4), vec1);
026        vec1.addLocal(-1, -2, -3, -4);
027        assertEquals(Vector4.ZERO, vec1);
028
029        vec1.zero();
030        vec1.addLocal(vec2);
031        assertEquals(Vector4.ONE, vec1);
032
033        vec1.zero();
034        final Vector4 vec3 = vec1.add(vec2, new Vector4());
035        assertEquals(Vector4.ZERO, vec1);
036        assertEquals(Vector4.ONE, vec3);
037
038        final Vector4 vec4 = vec1.add(0, 0, 0, 1, null);
039        assertEquals(Vector4.ZERO, vec1);
040        assertEquals(Vector4.UNIT_W, vec4);
041    }
042
043    @Test
044    public void testSubtract() {
045        final Vector4 vec1 = new Vector4();
046        final Vector4 vec2 = new Vector4(Vector4.ONE);
047
048        vec1.subtractLocal(1, 2, 3, 4);
049        assertEquals(new Vector4(-1, -2, -3, -4), vec1);
050        vec1.subtractLocal(-1, -2, -3, -4);
051        assertEquals(Vector4.ZERO, vec1);
052
053        vec1.zero();
054        vec1.subtractLocal(vec2);
055        assertEquals(Vector4.NEG_ONE, vec1);
056
057        vec1.zero();
058        final Vector4 vec3 = vec1.subtract(vec2, new Vector4());
059        assertEquals(Vector4.ZERO, vec1);
060        assertEquals(Vector4.NEG_ONE, vec3);
061
062        final Vector4 vec4 = vec1.subtract(0, 0, 0, 1, null);
063        assertEquals(Vector4.ZERO, vec1);
064        assertEquals(Vector4.NEG_UNIT_W, vec4);
065    }
066
067    @Test
068    public void testGetSet() {
069        final Vector4 vec1 = new Vector4();
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.setZ(0);
087        assertTrue(vec1.getZ() == 0.0);
088        vec1.setZ(Double.POSITIVE_INFINITY);
089        assertTrue(vec1.getZ() == Double.POSITIVE_INFINITY);
090        vec1.setZ(Double.NEGATIVE_INFINITY);
091        assertTrue(vec1.getZ() == Double.NEGATIVE_INFINITY);
092        assertTrue(vec1.getValue(2) == Double.NEGATIVE_INFINITY);
093
094        vec1.setW(0);
095        assertTrue(vec1.getW() == 0.0);
096        vec1.setW(Double.POSITIVE_INFINITY);
097        assertTrue(vec1.getW() == Double.POSITIVE_INFINITY);
098        vec1.setW(Double.NEGATIVE_INFINITY);
099        assertTrue(vec1.getW() == Double.NEGATIVE_INFINITY);
100        assertTrue(vec1.getValue(3) == Double.NEGATIVE_INFINITY);
101
102        vec1.set(Math.PI, Math.PI, Math.PI, Math.PI);
103        assertTrue(vec1.getXf() == (float) Math.PI);
104        assertTrue(vec1.getYf() == (float) Math.PI);
105        assertTrue(vec1.getZf() == (float) Math.PI);
106        assertTrue(vec1.getWf() == (float) Math.PI);
107
108        final Vector4 vec2 = new Vector4();
109        vec2.set(vec1);
110        assertEquals(vec1, vec2);
111
112        vec1.setValue(0, 0);
113        vec1.setValue(1, 0);
114        vec1.setValue(2, 0);
115        vec1.setValue(3, 0);
116        assertEquals(Vector4.ZERO, vec1);
117
118        // catch a few expected exceptions
119        try {
120            vec2.getValue(4);
121            fail("getValue(4) should have thrown IllegalArgumentException.");
122        } catch (final IllegalArgumentException e) {
123        }
124        try {
125            vec2.getValue(-1);
126            fail("getValue(-1) should have thrown IllegalArgumentException.");
127        } catch (final IllegalArgumentException e) {
128        }
129        try {
130            vec2.setValue(-1, 0);
131            fail("setValue(-1, 0) should have thrown IllegalArgumentException.");
132        } catch (final IllegalArgumentException e) {
133        }
134        try {
135            vec2.setValue(4, 0);
136            fail("setValue(4, 0) should have thrown IllegalArgumentException.");
137        } catch (final IllegalArgumentException e) {
138        }
139        // above exceptions shouldn't have altered vec2
140        assertEquals(new Vector4(Math.PI, Math.PI, Math.PI, Math.PI), vec2);
141    }
142
143    @Test
144    public void testToArray() {
145        final Vector4 vec1 = new Vector4();
146        vec1.set(Math.PI, Double.MAX_VALUE, 42, -1);
147        final double[] array = vec1.toArray(null);
148        final double[] array2 = vec1.toArray(new double[4]);
149        assertNotNull(array);
150        assertTrue(array.length == 4);
151        assertTrue(array[0] == Math.PI);
152        assertTrue(array[1] == Double.MAX_VALUE);
153        assertTrue(array[2] == 42);
154        assertTrue(array[3] == -1);
155        assertNotNull(array2);
156        assertTrue(array2.length == 4);
157        assertTrue(array2[0] == Math.PI);
158        assertTrue(array2[1] == Double.MAX_VALUE);
159        assertTrue(array2[2] == 42);
160        assertTrue(array2[3] == -1);
161
162        try {
163            vec1.toArray(new double[1]);
164            fail("toArray(d[1]) should have thrown ArrayIndexOutOfBoundsException.");
165        } catch (final ArrayIndexOutOfBoundsException e) {
166        }
167    }
168
169    @Test
170    public void testMultiply() {
171        final Vector4 vec1 = new Vector4(1, -1, 2, -2);
172        final Vector4 vec2 = vec1.multiply(2.0, null);
173        final Vector4 vec2B = vec1.multiply(2.0, new Vector4());
174        assertEquals(new Vector4(2.0, -2.0, 4.0, -4.0), vec2);
175        assertEquals(new Vector4(2.0, -2.0, 4.0, -4.0), vec2B);
176
177        vec2.multiplyLocal(0.5);
178        assertEquals(new Vector4(1.0, -1.0, 2.0, -2.0), vec2);
179
180        final Vector4 vec3 = vec1.multiply(vec2, null);
181        final Vector4 vec3B = vec1.multiply(vec2, new Vector4());
182        assertEquals(new Vector4(1, 1, 4, 4), vec3);
183        assertEquals(new Vector4(1, 1, 4, 4), vec3B);
184
185        final Vector4 vec4 = vec1.multiply(2, 3, 2, 3, null);
186        final Vector4 vec4B = vec1.multiply(2, 3, 2, 3, new Vector4());
187        assertEquals(new Vector4(2, -3, 4, -6), vec4);
188        assertEquals(new Vector4(2, -3, 4, -6), vec4B);
189
190        vec1.multiplyLocal(0.5, 0.5, 0.5, 0.5);
191        assertEquals(new Vector4(0.5, -0.5, 1.0, -1.0), vec1);
192
193        vec1.multiplyLocal(vec2);
194        assertEquals(new Vector4(0.5, 0.5, 2.0, 2.0), vec1);
195    }
196
197    @Test
198    public void testDivide() {
199        final Vector4 vec1 = new Vector4(1, -1, 2, -2);
200        final Vector4 vec2 = vec1.divide(2.0, null);
201        final Vector4 vec2B = vec1.divide(2.0, new Vector4());
202        assertEquals(new Vector4(0.5, -0.5, 1.0, -1.0), vec2);
203        assertEquals(new Vector4(0.5, -0.5, 1.0, -1.0), vec2B);
204
205        vec2.divideLocal(0.5);
206        assertEquals(new Vector4(1.0, -1.0, 2.0, -2.0), vec2);
207
208        final Vector4 vec3 = vec1.divide(vec2, null);
209        final Vector4 vec3B = vec1.divide(vec2, new Vector4());
210        assertEquals(Vector4.ONE, vec3);
211        assertEquals(Vector4.ONE, vec3B);
212
213        final Vector4 vec4 = vec1.divide(2, 3, 4, 5, null);
214        final Vector4 vec4B = vec1.divide(2, 3, 4, 5, new Vector4());
215        assertEquals(new Vector4(0.5, -1 / 3., 0.5, -0.4), vec4);
216        assertEquals(new Vector4(0.5, -1 / 3., 0.5, -0.4), vec4B);
217
218        vec1.divideLocal(0.5, 0.5, 0.5, 0.5);
219        assertEquals(new Vector4(2, -2, 4, -4), vec1);
220
221        vec1.divideLocal(vec2);
222        assertEquals(new Vector4(2, 2, 2, 2), vec1);
223    }
224
225    @Test
226    public void testScaleAdd() {
227        final Vector4 vec1 = new Vector4(1, 1, 1, 1);
228        final Vector4 vec2 = vec1.scaleAdd(2.0, new Vector4(1, 2, 3, 4), null);
229        final Vector4 vec2B = vec1.scaleAdd(2.0, new Vector4(1, 2, 3, 4), new Vector4());
230        assertEquals(new Vector4(3.0, 4.0, 5.0, 6.0), vec2);
231        assertEquals(new Vector4(3.0, 4.0, 5.0, 6.0), vec2B);
232
233        vec1.scaleAddLocal(2.0, new Vector4(1, 2, 3, 4));
234        assertEquals(vec2, vec1);
235    }
236
237    @Test
238    public void testNegate() {
239        final Vector4 vec1 = new Vector4(3, 2, -1, 1);
240        final Vector4 vec2 = vec1.negate(null);
241        assertEquals(new Vector4(-3, -2, 1, -1), vec2);
242
243        vec1.negateLocal();
244        assertEquals(vec2, vec1);
245    }
246
247    @Test
248    public void testNormalize() {
249        final Vector4 vec1 = new Vector4(2, 1, 3, -1);
250        assertTrue(vec1.length() == Math.sqrt(15));
251
252        final Vector4 vec2 = vec1.normalize(null);
253        final double invLength = MathUtils.inverseSqrt(2 * 2 + 1 * 1 + 3 * 3 + -1 * -1);
254        assertEquals(new Vector4(2 * invLength, 1 * invLength, 3 * invLength, -1 * invLength), vec2);
255
256        vec1.normalizeLocal();
257        assertEquals(new Vector4(2 * invLength, 1 * invLength, 3 * invLength, -1 * invLength), vec1);
258
259        vec1.zero();
260        vec1.normalize(vec2);
261        assertEquals(vec1, vec2);
262
263        // ensure no exception thrown
264        vec1.normalizeLocal();
265        vec1.normalize(null);
266    }
267
268    @Test
269    public void testDistance() {
270        final Vector4 vec1 = new Vector4(0, 0, 0, 0);
271        assertTrue(4.0 == vec1.distance(4, 0, 0, 0));
272        assertTrue(3.0 == vec1.distance(0, 3, 0, 0));
273        assertTrue(2.0 == vec1.distance(0, 0, 2, 0));
274        assertTrue(1.0 == vec1.distance(0, 0, 0, 1));
275
276        final Vector4 vec2 = new Vector4(1, 1, 1, 1);
277        assertTrue(Math.sqrt(4) == vec1.distance(vec2));
278    }
279
280    @Test
281    public void testLerp() {
282        final Vector4 vec1 = new Vector4(8, 3, -2, 2);
283        final Vector4 vec2 = new Vector4(2, 1, 0, -2);
284        assertEquals(new Vector4(5, 2, -1, 0), vec1.lerp(vec2, 0.5, null));
285        assertEquals(new Vector4(5, 2, -1, 0), vec1.lerp(vec2, 0.5, new Vector4()));
286        assertEquals(new Vector4(5, 2, -1, 0), Vector4.lerp(vec1, vec2, 0.5, null));
287        assertEquals(new Vector4(5, 2, -1, 0), Vector4.lerp(vec1, vec2, 0.5, new Vector4()));
288
289        vec1.set(14, 5, 4, 2);
290        vec1.lerpLocal(vec2, 0.25);
291        assertEquals(new Vector4(11, 4, 3, 1), vec1);
292
293        vec1.set(15, 7, 6, 8);
294        final Vector4 vec3 = new Vector4(-1, -1, -1, -1);
295        vec3.lerpLocal(vec1, vec2, 0.5);
296        assertEquals(new Vector4(8.5, 4.0, 3.0, 3.0), vec3);
297
298        // coverage
299        assertEquals(vec1.lerp(vec1, .25, null), vec1);
300        assertEquals(vec2.lerpLocal(vec2, .25), vec2);
301        assertEquals(vec2.lerpLocal(vec2, vec2, .25), vec2);
302        assertEquals(Vector4.lerp(vec1, vec1, .25, null), vec1);
303    }
304
305    @Test
306    public void testDot() {
307        final Vector4 vec1 = new Vector4(7, 2, 5, -1);
308        assertTrue(35.0 == vec1.dot(3, 1, 2, -2));
309
310        assertTrue(-11.0 == vec1.dot(new Vector4(-1, 1, -1, 1)));
311    }
312
313    @Test
314    public void testClone() {
315        final Vector4 vec1 = new Vector4(0, 0, 0, 0);
316        final Vector4 vec2 = vec1.clone();
317        assertEquals(vec1, vec2);
318        assertNotSame(vec1, vec2);
319    }
320
321    @Test
322    public void testValid() {
323        final Vector4 vec1 = new Vector4(0, 0, 0, 0);
324        final Vector4 vec2A = new Vector4(Double.POSITIVE_INFINITY, 0, 0, 0);
325        final Vector4 vec2B = new Vector4(0, Double.NEGATIVE_INFINITY, 0, 0);
326        final Vector4 vec2C = new Vector4(0, 0, Double.POSITIVE_INFINITY, 0);
327        final Vector4 vec2D = new Vector4(0, 0, 0, Double.POSITIVE_INFINITY);
328        final Vector4 vec3A = new Vector4(Double.NaN, 0, 0, 0);
329        final Vector4 vec3B = new Vector4(0, Double.NaN, 0, 0);
330        final Vector4 vec3C = new Vector4(0, 0, Double.NaN, 0);
331        final Vector4 vec3D = new Vector4(0, 0, 0, Double.NaN);
332
333        assertTrue(Vector4.isValid(vec1));
334        assertFalse(Vector4.isValid(vec2A));
335        assertFalse(Vector4.isValid(vec2B));
336        assertFalse(Vector4.isValid(vec2C));
337        assertFalse(Vector4.isValid(vec2D));
338        assertFalse(Vector4.isValid(vec3A));
339        assertFalse(Vector4.isValid(vec3B));
340        assertFalse(Vector4.isValid(vec3C));
341        assertFalse(Vector4.isValid(vec3D));
342
343        vec3C.zero();
344        assertTrue(Vector4.isValid(vec3C));
345
346        assertFalse(Vector4.isValid(null));
347
348        // couple of equals validity tests
349        assertEquals(vec1, vec1);
350        assertFalse(vec1.equals(null));
351        assertFalse(vec1.equals(new Vector2()));
352
353        // throw in a couple pool accesses for coverage
354        final Vector4 vec6 = Vector4.fetchTempInstance();
355        vec6.set(vec1);
356        assertEquals(vec1, vec6);
357        assertNotSame(vec1, vec6);
358        Vector4.releaseTempInstance(vec6);
359
360        // cover more of equals
361        vec1.set(0, 1, 2, 3);
362        assertFalse(vec1.equals(new Vector4(0, 4, 4, 4)));
363        assertFalse(vec1.equals(new Vector4(0, 1, 4, 4)));
364        assertFalse(vec1.equals(new Vector4(0, 1, 2, 4)));
365    }
366
367    @Test
368    public void testSimpleHash() {
369        // Just a simple sanity check.
370        final Vector4 vec1 = new Vector4(1, 2, 3, 4);
371        final Vector4 vec2 = new Vector4(1, 2, 3, 4);
372        final Vector4 vec3 = new Vector4(2, 2, 2, 2);
373
374        assertTrue(vec1.hashCode() == vec2.hashCode());
375        assertTrue(vec1.hashCode() != vec3.hashCode());
376    }
377}