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}