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