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 java.nio.DoubleBuffer; 016import java.nio.FloatBuffer; 017 018import org.junit.Test; 019 020public class TestMatrix3 { 021 022 @Test 023 public void testGetSet() { 024 final Matrix3 mat3A = new Matrix3(); 025 assertEquals(Matrix3.IDENTITY, mat3A); 026 027 mat3A.setM00(0.0); 028 mat3A.setM01(0.1); 029 mat3A.setM02(0.2); 030 mat3A.setM10(1.0); 031 mat3A.setM11(1.1); 032 mat3A.setM12(1.2); 033 mat3A.setM20(2.0); 034 mat3A.setM21(2.1); 035 mat3A.setM22(2.2); 036 037 assertTrue(0.0 == mat3A.getM00()); 038 assertTrue(0.1 == mat3A.getM01()); 039 assertTrue(0.2 == mat3A.getM02()); 040 assertTrue(1.0 == mat3A.getM10()); 041 assertTrue(1.1 == mat3A.getM11()); 042 assertTrue(1.2 == mat3A.getM12()); 043 assertTrue(2.0 == mat3A.getM20()); 044 assertTrue(2.1 == mat3A.getM21()); 045 assertTrue(2.2 == mat3A.getM22()); 046 047 final Matrix3 mat3B = new Matrix3(mat3A); 048 assertTrue(0.0 == mat3B.getM00()); 049 assertTrue(0.1 == mat3B.getM01()); 050 assertTrue(0.2 == mat3B.getM02()); 051 assertTrue(1.0 == mat3B.getM10()); 052 assertTrue(1.1 == mat3B.getM11()); 053 assertTrue(1.2 == mat3B.getM12()); 054 assertTrue(2.0 == mat3B.getM20()); 055 assertTrue(2.1 == mat3B.getM21()); 056 assertTrue(2.2 == mat3B.getM22()); 057 058 final Matrix3 mat3C = new Matrix3(0.0, 0.1, 0.2, 1.0, 1.1, 1.2, 2.0, 2.1, 2.2); 059 assertTrue(0.0 == mat3C.getM00()); 060 assertTrue(0.1 == mat3C.getM01()); 061 assertTrue(0.2 == mat3C.getM02()); 062 assertTrue(1.0 == mat3C.getM10()); 063 assertTrue(1.1 == mat3C.getM11()); 064 assertTrue(1.2 == mat3C.getM12()); 065 assertTrue(2.0 == mat3C.getM20()); 066 assertTrue(2.1 == mat3C.getM21()); 067 assertTrue(2.2 == mat3C.getM22()); 068 069 mat3C.setIdentity(); 070 assertTrue(mat3C.isIdentity()); 071 072 for (int x = 0; x < 3; x++) { 073 for (int y = 0; y < 3; y++) { 074 final double value = (10 * x + y) / 10.; 075 mat3C.setValue(x, y, value); 076 assertTrue(value == mat3C.getValue(x, y)); 077 } 078 } 079 080 mat3C.setIdentity(); 081 mat3C.set(0.0, 0.1, 0.2, 2.0, 2.1, 2.2, 4.0, 4.1, 4.2); 082 for (int x = 0; x < 3; x++) { 083 for (int y = 0; y < 3; y++) { 084 assertTrue((20 * x + y) / 10.f == mat3C.getValuef(x, y)); 085 } 086 } 087 088 final Matrix3 store = new Matrix3(mat3C); 089 // catch a few expected exceptions 090 try { 091 mat3C.getValue(-1, 0); 092 fail("getValue(-1, 0) should have thrown IllegalArgumentException."); 093 } catch (final IllegalArgumentException e) { 094 } 095 try { 096 mat3C.getValue(0, 3); 097 fail("getValue(0, 3) should have thrown IllegalArgumentException."); 098 } catch (final IllegalArgumentException e) { 099 } 100 try { 101 mat3C.getValue(1, -1); 102 fail("getValue(1, -1) should have thrown IllegalArgumentException."); 103 } catch (final IllegalArgumentException e) { 104 } 105 try { 106 mat3C.getValue(2, 3); 107 fail("getValue(2, 3) should have thrown IllegalArgumentException."); 108 } catch (final IllegalArgumentException e) { 109 } 110 try { 111 mat3C.getValue(3, 0); 112 fail("getValue(3, 0) should have thrown IllegalArgumentException."); 113 } catch (final IllegalArgumentException e) { 114 } 115 116 try { 117 mat3C.setValue(-1, 0, 0); 118 fail("setValue(-1, 0, 0) should have thrown IllegalArgumentException."); 119 } catch (final IllegalArgumentException e) { 120 } 121 try { 122 mat3C.setValue(0, -1, 0); 123 fail("setValue(0, -1, 0) should have thrown IllegalArgumentException."); 124 } catch (final IllegalArgumentException e) { 125 } 126 try { 127 mat3C.setValue(1, 3, 0); 128 fail("setValue(1, 3, 0) should have thrown IllegalArgumentException."); 129 } catch (final IllegalArgumentException e) { 130 } 131 try { 132 mat3C.setValue(2, -1, 0); 133 fail("setValue(2, -1, 0) should have thrown IllegalArgumentException."); 134 } catch (final IllegalArgumentException e) { 135 } 136 try { 137 mat3C.setValue(3, 0, 0); 138 fail("setValue(3, 0, 0) should have thrown IllegalArgumentException."); 139 } catch (final IllegalArgumentException e) { 140 } 141 // above exceptions shouldn't have altered mat3C 142 assertEquals(store, mat3C); 143 } 144 145 @Test 146 public void testColumns() { 147 final Matrix3 mat3A = new Matrix3(); 148 mat3A.setColumn(0, new Vector3(0, 3, 6)); 149 mat3A.setColumn(1, new Vector3(1, 4, 7)); 150 mat3A.setColumn(2, new Vector3(2, 5, 8)); 151 assertEquals(new Vector3(0, 3, 6), mat3A.getColumn(0, new Vector3())); 152 assertEquals(new Vector3(1, 4, 7), mat3A.getColumn(1, null)); 153 assertEquals(new Vector3(2, 5, 8), mat3A.getColumn(2, null)); 154 try { 155 mat3A.getColumn(-1, null); 156 fail("getColumn(-1, null) should have thrown IllegalArgumentException."); 157 } catch (final IllegalArgumentException e) { 158 } 159 try { 160 mat3A.getColumn(3, null); 161 fail("getColumn(3, null) should have thrown IllegalArgumentException."); 162 } catch (final IllegalArgumentException e) { 163 } 164 try { 165 mat3A.setColumn(-1, new Vector3()); 166 fail("setColumn(-1, Vector3) should have thrown IllegalArgumentException."); 167 } catch (final IllegalArgumentException e) { 168 } 169 try { 170 mat3A.setColumn(4, new Vector3()); 171 fail("setColumn(4, Vector3) should have thrown IllegalArgumentException."); 172 } catch (final IllegalArgumentException e) { 173 } 174 175 mat3A.fromAxes(new Vector3(1, 2, 3), new Vector3(4, 5, 6), new Vector3(7, 8, 9)); 176 mat3A.setColumn(0, new Vector3(1, 2, 3)); 177 mat3A.setColumn(1, new Vector3(4, 5, 6)); 178 mat3A.setColumn(2, new Vector3(7, 8, 9)); 179 } 180 181 @Test 182 public void testRows() { 183 final Matrix3 mat3A = new Matrix3(); 184 mat3A.setRow(0, new Vector3(0, 1, 2)); 185 mat3A.setRow(1, new Vector3(3, 4, 5)); 186 mat3A.setRow(2, new Vector3(6, 7, 8)); 187 assertEquals(new Vector3(0, 1, 2), mat3A.getRow(0, new Vector3())); 188 assertEquals(new Vector3(3, 4, 5), mat3A.getRow(1, null)); 189 assertEquals(new Vector3(6, 7, 8), mat3A.getRow(2, null)); 190 try { 191 mat3A.getRow(-1, null); 192 fail("getRow(-1, null) should have thrown IllegalArgumentException."); 193 } catch (final IllegalArgumentException e) { 194 } 195 try { 196 mat3A.getRow(3, null); 197 fail("getRow(3, null) should have thrown IllegalArgumentException."); 198 } catch (final IllegalArgumentException e) { 199 } 200 try { 201 mat3A.setRow(-1, new Vector3()); 202 fail("setRow(-1, Vector3) should have thrown IllegalArgumentException."); 203 } catch (final IllegalArgumentException e) { 204 } 205 try { 206 mat3A.setRow(3, new Vector3()); 207 fail("setRow(3, Vector3]) should have thrown IllegalArgumentException."); 208 } catch (final IllegalArgumentException e) { 209 } 210 } 211 212 @Test 213 public void testSetRotation() { 214 final Matrix3 mat3A = new Matrix3(); 215 // rotate identity 90 degrees around Y 216 final double a = MathUtils.HALF_PI; 217 final Quaternion quaternion = new Quaternion(); 218 quaternion.fromAngleAxis(a, Vector3.UNIT_Y); 219 mat3A.set(quaternion); 220 221 assertEquals(new Matrix3( // 222 Math.cos(a), 0, Math.sin(a), // 223 0, 1, 0, // 224 -Math.sin(a), 0, Math.cos(a)), mat3A); 225 } 226 227 @Test 228 public void testFromBuffer() { 229 final FloatBuffer fb = FloatBuffer.allocate(9); 230 fb.put(new float[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }); 231 fb.flip(); 232 // row major 233 final Matrix3 mat3A = new Matrix3().fromFloatBuffer(fb); 234 assertTrue(0 == mat3A.getM00()); 235 assertTrue(1 == mat3A.getM01()); 236 assertTrue(2 == mat3A.getM02()); 237 assertTrue(3 == mat3A.getM10()); 238 assertTrue(4 == mat3A.getM11()); 239 assertTrue(5 == mat3A.getM12()); 240 assertTrue(6 == mat3A.getM20()); 241 assertTrue(7 == mat3A.getM21()); 242 assertTrue(8 == mat3A.getM22()); 243 244 // column major 245 fb.rewind(); 246 mat3A.setIdentity(); 247 mat3A.fromFloatBuffer(fb, false); 248 assertTrue(0 == mat3A.getM00()); 249 assertTrue(3 == mat3A.getM01()); 250 assertTrue(6 == mat3A.getM02()); 251 assertTrue(1 == mat3A.getM10()); 252 assertTrue(4 == mat3A.getM11()); 253 assertTrue(7 == mat3A.getM12()); 254 assertTrue(2 == mat3A.getM20()); 255 assertTrue(5 == mat3A.getM21()); 256 assertTrue(8 == mat3A.getM22()); 257 258 final DoubleBuffer db = DoubleBuffer.allocate(16); 259 db.put(new double[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); 260 db.flip(); 261 // row major 262 mat3A.setIdentity(); 263 mat3A.fromDoubleBuffer(db); 264 assertTrue(0 == mat3A.getM00()); 265 assertTrue(1 == mat3A.getM01()); 266 assertTrue(2 == mat3A.getM02()); 267 assertTrue(3 == mat3A.getM10()); 268 assertTrue(4 == mat3A.getM11()); 269 assertTrue(5 == mat3A.getM12()); 270 assertTrue(6 == mat3A.getM20()); 271 assertTrue(7 == mat3A.getM21()); 272 assertTrue(8 == mat3A.getM22()); 273 274 // column major 275 db.rewind(); 276 mat3A.setIdentity(); 277 mat3A.fromDoubleBuffer(db, false); 278 assertTrue(0 == mat3A.getM00()); 279 assertTrue(3 == mat3A.getM01()); 280 assertTrue(6 == mat3A.getM02()); 281 assertTrue(1 == mat3A.getM10()); 282 assertTrue(4 == mat3A.getM11()); 283 assertTrue(7 == mat3A.getM12()); 284 assertTrue(2 == mat3A.getM20()); 285 assertTrue(5 == mat3A.getM21()); 286 assertTrue(8 == mat3A.getM22()); 287 } 288 289 @Test 290 public void testToBuffer() { 291 final double[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 292 final double[] colmajor = { 0, 3, 6, 1, 4, 7, 2, 5, 8 }; 293 294 final Matrix3 mat3A = new Matrix3().fromArray(values); 295 296 // row major 297 final FloatBuffer fb = mat3A.toFloatBuffer(FloatBuffer.allocate(9)); 298 fb.flip(); 299 for (int i = 0; i < 9; i++) { 300 assertTrue(values[i] == fb.get()); 301 } 302 303 // column major 304 fb.rewind(); 305 mat3A.toFloatBuffer(fb, false); 306 fb.flip(); 307 for (int i = 0; i < 9; i++) { 308 assertTrue(colmajor[i] == fb.get()); 309 } 310 311 // row major 312 final DoubleBuffer db = mat3A.toDoubleBuffer(DoubleBuffer.allocate(9)); 313 db.flip(); 314 for (int i = 0; i < 9; i++) { 315 assertTrue(values[i] == db.get()); 316 } 317 318 // column major 319 db.rewind(); 320 mat3A.toDoubleBuffer(db, false); 321 db.flip(); 322 for (int i = 0; i < 9; i++) { 323 assertTrue(colmajor[i] == db.get()); 324 } 325 } 326 327 @Test 328 public void testFromArray() { 329 final double[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 330 final Matrix3 mat3A = new Matrix3(); 331 332 // row major 333 mat3A.fromArray(values); 334 assertTrue(0 == mat3A.getM00()); 335 assertTrue(1 == mat3A.getM01()); 336 assertTrue(2 == mat3A.getM02()); 337 assertTrue(3 == mat3A.getM10()); 338 assertTrue(4 == mat3A.getM11()); 339 assertTrue(5 == mat3A.getM12()); 340 assertTrue(6 == mat3A.getM20()); 341 assertTrue(7 == mat3A.getM21()); 342 assertTrue(8 == mat3A.getM22()); 343 344 // column major 345 mat3A.setIdentity(); 346 mat3A.fromArray(values, false); 347 assertTrue(0 == mat3A.getM00()); 348 assertTrue(3 == mat3A.getM01()); 349 assertTrue(6 == mat3A.getM02()); 350 assertTrue(1 == mat3A.getM10()); 351 assertTrue(4 == mat3A.getM11()); 352 assertTrue(7 == mat3A.getM12()); 353 assertTrue(2 == mat3A.getM20()); 354 assertTrue(5 == mat3A.getM21()); 355 assertTrue(8 == mat3A.getM22()); 356 } 357 358 @Test 359 public void testToArray() { 360 final double[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 361 final Matrix3 mat3A = new Matrix3().fromArray(values); 362 363 // row major 364 final double[] dbls1 = mat3A.toArray(null); 365 for (int i = 0; i < 9; i++) { 366 assertTrue(values[i] == dbls1[i]); 367 } 368 369 // column major 370 final double[] colmajor = { 0, 3, 6, 1, 4, 7, 2, 5, 8 }; 371 mat3A.toArray(dbls1, false); 372 for (int i = 0; i < 9; i++) { 373 assertTrue(colmajor[i] == dbls1[i]); 374 } 375 } 376 377 @Test(expected = IllegalArgumentException.class) 378 public void testBadArray() { 379 final Matrix3 mat3A = new Matrix3(); 380 mat3A.toArray(new double[4]); 381 } 382 383 @Test(expected = IllegalArgumentException.class) 384 public void testBadAnglesArray() { 385 final Matrix3 mat3A = new Matrix3(); 386 mat3A.toAngles(new double[2]); 387 } 388 389 @Test 390 public void testAngleAxis() { 391 final Matrix3 mat3A = new Matrix3(); 392 // rotate identity 90 degrees around X 393 final double angle = MathUtils.HALF_PI; 394 mat3A.fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X); 395 assertEquals(new Matrix3( // 396 1, 0, 0, // 397 0, Math.cos(angle), -Math.sin(angle), // 398 0, Math.sin(angle), Math.cos(angle)), mat3A); 399 } 400 401 @Test 402 public void testRotations() { 403 final Vector3 rotated = new Vector3(1, 1, 1); 404 final Vector3 expected = new Vector3(1, 1, 1); 405 406 // rotated 407 final Matrix3 mat3A = new Matrix3().fromAngles(MathUtils.HALF_PI, MathUtils.QUARTER_PI, MathUtils.PI); 408 mat3A.applyPost(rotated, rotated); 409 410 // expected - post 411 final Matrix3 worker = new Matrix3().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X); 412 worker.applyPost(expected, expected); 413 worker.fromAngleAxis(MathUtils.PI, Vector3.UNIT_Z); 414 worker.applyPost(expected, expected); 415 worker.fromAngleAxis(MathUtils.QUARTER_PI, Vector3.UNIT_Y); 416 worker.applyPost(expected, expected); 417 418 // test how close it came out 419 assertTrue(rotated.distance(expected) <= MathUtils.EPSILON); 420 421 // Try a new way with new angles... 422 final Matrix3 mat3B = new Matrix3().fromAngles(MathUtils.QUARTER_PI, MathUtils.PI, MathUtils.HALF_PI); 423 rotated.set(1, 1, 1); 424 mat3B.applyPost(rotated, rotated); 425 426 // expected 427 expected.set(1, 1, 1); 428 worker.setIdentity(); 429 // put together matrix, then apply to vector, so YZX 430 worker.applyRotationY(MathUtils.PI); 431 worker.applyRotationZ(MathUtils.HALF_PI); 432 worker.applyRotationX(MathUtils.QUARTER_PI); 433 worker.applyPost(expected, expected); 434 435 // test how close it came out 436 assertTrue(rotated.distance(expected) <= MathUtils.EPSILON); 437 438 // test axis rotation methods against general purpose 439 // X AXIS 440 expected.set(1, 1, 1); 441 rotated.set(1, 1, 1); 442 worker.setIdentity().applyRotationX(MathUtils.QUARTER_PI).applyPost(expected, expected); 443 worker.setIdentity().applyRotation(MathUtils.QUARTER_PI, 1, 0, 0).applyPost(rotated, rotated); 444 assertTrue(rotated.distance(expected) <= MathUtils.EPSILON); 445 446 // Y AXIS 447 expected.set(1, 1, 1); 448 rotated.set(1, 1, 1); 449 worker.setIdentity().applyRotationY(MathUtils.QUARTER_PI).applyPost(expected, expected); 450 worker.setIdentity().applyRotation(MathUtils.QUARTER_PI, 0, 1, 0).applyPost(rotated, rotated); 451 assertTrue(rotated.distance(expected) <= MathUtils.EPSILON); 452 453 // Z AXIS 454 expected.set(1, 1, 1); 455 rotated.set(1, 1, 1); 456 worker.setIdentity().applyRotationZ(MathUtils.QUARTER_PI).applyPost(expected, expected); 457 worker.setIdentity().applyRotation(MathUtils.QUARTER_PI, 0, 0, 1).applyPost(rotated, rotated); 458 assertTrue(rotated.distance(expected) <= MathUtils.EPSILON); 459 460 // test toAngles - not necessarily the same values as fromAngles, but should be same resulting Matrix. 461 mat3A.fromAngles(MathUtils.HALF_PI, MathUtils.QUARTER_PI, MathUtils.PI); 462 final double[] angles = mat3A.toAngles(null); 463 worker.fromAngles(angles[0], angles[1], angles[2]); 464 assertEquals(mat3A, worker); 465 466 mat3A.fromAngles(MathUtils.HALF_PI, MathUtils.QUARTER_PI, MathUtils.HALF_PI); 467 mat3A.toAngles(angles); 468 worker.fromAngles(angles[0], angles[1], angles[2]); 469 assertEquals(mat3A, worker); 470 471 mat3A.fromAngles(MathUtils.HALF_PI, MathUtils.QUARTER_PI, -MathUtils.HALF_PI); 472 mat3A.toAngles(angles); 473 worker.fromAngles(angles[0], angles[1], angles[2]); 474 assertEquals(mat3A, worker); 475 } 476 477 @Test 478 public void testMultiplyDiagonal() { 479 final Matrix3 mat3A = new Matrix3(); 480 Matrix3 result = mat3A.multiplyDiagonalPost(new Vector3(2, 4, 6), null); 481 assertEquals(new Matrix3( // 482 2, 0, 0, // 483 0, 4, 0, // 484 0, 0, 6), result); 485 mat3A.multiplyDiagonalPre(new Vector3(-2, -4, -6), result); 486 assertEquals(new Matrix3( // 487 -2, 0, 0, // 488 0, -4, 0, // 489 0, 0, -6), result); 490 491 final double a = MathUtils.HALF_PI; 492 mat3A.applyRotationY(a); 493 mat3A.multiplyDiagonalPost(new Vector3(2, 4, 6), result); 494 assertEquals(new Matrix3( // 495 2 * Math.cos(a), 4 * 0, 6 * Math.sin(a), // 496 2 * 0, 4 * 1, 6 * 0, // 497 2 * -Math.sin(a), 4 * 0, 6 * Math.cos(a)), result); 498 result = mat3A.multiplyDiagonalPre(new Vector3(-2, -4, -6), null); 499 assertEquals(new Matrix3( // 500 -2 * Math.cos(a), -2 * 0, -2 * Math.sin(a), // 501 -4 * 0, -4 * 1, -4 * 0, // 502 -6 * -Math.sin(a), -6 * 0, -6 * Math.cos(a)), result); 503 } 504 505 @Test 506 public void testMultiply() { 507 final Matrix3 mat3A = new Matrix3( // 508 0.01, 0.1, 0.2, // 509 1.0, 1.1, 1.2, // 510 2.0, 2.1, 2.2); 511 mat3A.multiplyLocal(2); 512 assertEquals(new Matrix3( // 513 0.02, 0.2, 0.4, // 514 2.0, 2.2, 2.4, // 515 4.0, 4.2, 4.4), mat3A); 516 517 final Matrix3 mat3B = new Matrix3( // 518 0.5, 1, 2, // 519 4, 5, 6, // 520 8, 9, 10); 521 final Matrix3 result = mat3A.multiply(mat3B, null); 522 assertTrue(0.02 * 0.5 + 0.2 * 4 + 0.4 * 8 == result.getM00()); 523 assertTrue(0.02 * 1 + 0.2 * 5 + 0.4 * 9 == result.getM01()); 524 assertTrue(0.02 * 2 + 0.2 * 6 + 0.4 * 10 == result.getM02()); 525 assertTrue(2.0 * 0.5 + 2.2 * 4 + 2.4 * 8 == result.getM10()); 526 assertTrue(2.0 * 1 + 2.2 * 5 + 2.4 * 9 == result.getM11()); 527 assertTrue(2.0 * 2 + 2.2 * 6 + 2.4 * 10 == result.getM12()); 528 assertTrue(4.0 * 0.5 + 4.2 * 4 + 4.4 * 8 == result.getM20()); 529 assertTrue(4.0 * 1 + 4.2 * 5 + 4.4 * 9 == result.getM21()); 530 assertTrue(4.0 * 2 + 4.2 * 6 + 4.4 * 10 == result.getM22()); 531 mat3A.multiplyLocal(mat3B); 532 assertTrue(0.02 * 0.5 + 0.2 * 4 + 0.4 * 8 == mat3A.getM00()); 533 assertTrue(0.02 * 1 + 0.2 * 5 + 0.4 * 9 == mat3A.getM01()); 534 assertTrue(0.02 * 2 + 0.2 * 6 + 0.4 * 10 == mat3A.getM02()); 535 assertTrue(2.0 * 0.5 + 2.2 * 4 + 2.4 * 8 == mat3A.getM10()); 536 assertTrue(2.0 * 1 + 2.2 * 5 + 2.4 * 9 == mat3A.getM11()); 537 assertTrue(2.0 * 2 + 2.2 * 6 + 2.4 * 10 == mat3A.getM12()); 538 assertTrue(4.0 * 0.5 + 4.2 * 4 + 4.4 * 8 == mat3A.getM20()); 539 assertTrue(4.0 * 1 + 4.2 * 5 + 4.4 * 9 == mat3A.getM21()); 540 assertTrue(4.0 * 2 + 4.2 * 6 + 4.4 * 10 == mat3A.getM22()); 541 } 542 543 @Test 544 public void testAddSubtract() { 545 final Matrix3 mat3A = new Matrix3( // 546 0.0, 0.1, 0.2, // 547 1.0, 1.1, 1.2, // 548 2.0, 2.1, 2.2); 549 550 final Matrix3 result1 = mat3A.add(new Matrix3(// 551 1, 2, 3,// 552 5, 6, 7, // 553 9, 10, 11), null); 554 assertEquals(new Matrix3( // 555 1.0, 2.1, 3.2, // 556 6.0, 7.1, 8.2, // 557 11.0, 12.1, 13.2), result1); 558 559 final Matrix3 result2 = result1.subtract(new Matrix3(// 560 1, 2, 3, // 561 5, 6, 7, // 562 9, 10, 11), null); 563 assertEquals(mat3A, result2); 564 result2.addLocal(Matrix3.IDENTITY); 565 assertEquals(new Matrix3( // 566 1.0, 0.1, 0.2, // 567 1.0, 2.1, 1.2, // 568 2.0, 2.1, 3.2), result2); 569 570 result1.subtractLocal(Matrix3.IDENTITY); 571 assertEquals(new Matrix3( // 572 0.0, 2.1, 3.2, // 573 6.0, 6.1, 8.2, // 574 11.0, 12.1, 12.2), result1); 575 } 576 577 @Test 578 public void testScale() { 579 final Matrix3 mat3A = new Matrix3( // 580 0.01, 0.1, 0.2, // 581 1.0, 1.1, 1.2, // 582 2.0, 2.1, 2.2); 583 final Matrix3 result = mat3A.scale(new Vector3(-1, 2, 3), null); 584 assertEquals(new Matrix3( // 585 0.01 * -1, 0.1 * 2, 0.2 * 3, // 586 1.0 * -1, 1.1 * 2, 1.2 * 3, // 587 2.0 * -1, 2.1 * 2, 2.2 * 3), result); 588 589 result.scaleLocal(new Vector3(-1, 0.5, 1 / 3.)); 590 assertEquals(mat3A, result); 591 } 592 593 @Test 594 public void testTranspose() { 595 final Matrix3 mat3A = new Matrix3( // 596 0.01, 0.1, 0.2, // 597 1.0, 1.1, 1.2, // 598 2.0, 2.1, 2.2); 599 final Matrix3 result = mat3A.transpose(null); 600 assertEquals(new Matrix3( // 601 0.01, 1.0, 2.0, // 602 0.1, 1.1, 2.1, // 603 0.2, 1.2, 2.2), result); 604 assertEquals(new Matrix3( // 605 0.01, 0.1, 0.2, // 606 1.0, 1.1, 1.2, // 607 2.0, 2.1, 2.2), result.transposeLocal()); 608 // coverage 609 final Matrix3 result2 = result.transposeLocal().transpose(new Matrix3()); 610 assertEquals(mat3A, result2); 611 } 612 613 @Test 614 public void testInvert() { 615 final Matrix3 mat3A = new Matrix3().applyRotationX(MathUtils.QUARTER_PI); 616 final Matrix3 inverted = mat3A.invert(null); 617 assertEquals(Matrix3.IDENTITY, mat3A.multiply(inverted, null)); 618 assertEquals(mat3A, inverted.invertLocal()); 619 } 620 621 @Test(expected = ArithmeticException.class) 622 public void testBadInvert() { 623 final Matrix3 mat3A = new Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0); 624 mat3A.invertLocal(); 625 } 626 627 @Test 628 public void testAdjugate() { 629 final double // 630 a = -3, b = 2, c = -5, // 631 d = -1, e = 0, f = -2, // 632 g = 3, h = -4, i = 1; 633 634 final Matrix3 mat3A = new Matrix3( // 635 a, b, c, // 636 d, e, f, // 637 g, h, i); 638 639 final Matrix3 testValue = new Matrix3( // 640 e * i - h * f, -(b * i - h * c), b * f - e * c, // 641 -(d * i - g * f), a * i - g * c, -(a * f - d * c),// 642 d * h - g * e, -(a * h - g * b), a * e - d * b); 643 644 assertEquals(testValue, mat3A.adjugate(null)); 645 assertEquals(testValue, mat3A.adjugateLocal()); 646 } 647 648 @Test 649 public void testDeterminant() { 650 { 651 final double // 652 a = -3, b = 2, c = -5, // 653 d = -1, e = 0, f = -2, // 654 g = 3, h = -4, i = 1; 655 656 final Matrix3 mat3A = new Matrix3( // 657 a, b, c, // 658 d, e, f, // 659 g, h, i); 660 final double determinant = a * e * i + b * f * g + c * d * h - c * e * g - b * d * i - a * f * h; 661 assertTrue(determinant == mat3A.determinant()); 662 } 663 664 { 665 final double // 666 a = -1, b = 2, c = -3, // 667 d = 4, e = -5, f = 6, // 668 g = -7, h = 8, i = -9; 669 670 final Matrix3 mat3A = new Matrix3( // 671 a, b, c, // 672 d, e, f, // 673 g, h, i); 674 final double determinant = a * e * i + b * f * g + c * d * h - c * e * g - b * d * i - a * f * h; 675 assertTrue(determinant == mat3A.determinant()); 676 } 677 } 678 679 @Test 680 public void testClone() { 681 final Matrix3 mat1 = new Matrix3(); 682 final Matrix3 mat2 = mat1.clone(); 683 assertEquals(mat1, mat2); 684 assertNotSame(mat1, mat2); 685 } 686 687 @Test 688 public void testValid() { 689 final Matrix3 mat3 = new Matrix3(); 690 assertTrue(Matrix3.isValid(mat3)); 691 for (int i = 0; i < 9; i++) { 692 mat3.setIdentity(); 693 mat3.setValue(i / 3, i % 3, Double.NaN); 694 assertFalse(Matrix3.isValid(mat3)); 695 mat3.setIdentity(); 696 mat3.setValue(i / 3, i % 3, Double.POSITIVE_INFINITY); 697 assertFalse(Matrix3.isValid(mat3)); 698 } 699 700 mat3.setIdentity(); 701 assertTrue(Matrix3.isValid(mat3)); 702 703 assertFalse(Matrix3.isValid(null)); 704 705 // couple of equals validity tests 706 assertEquals(mat3, mat3); 707 assertTrue(mat3.strictEquals(mat3)); 708 assertFalse(mat3.equals(null)); 709 assertFalse(mat3.strictEquals(null)); 710 assertFalse(mat3.equals(new Vector2())); 711 assertFalse(mat3.strictEquals(new Vector2())); 712 713 // throw in a couple pool accesses for coverage 714 final Matrix3 matTemp = Matrix3.fetchTempInstance(); 715 matTemp.set(mat3); 716 assertEquals(mat3, matTemp); 717 assertNotSame(mat3, matTemp); 718 Matrix3.releaseTempInstance(matTemp); 719 720 // cover more of equals 721 mat3.set(0, 1, 2, 3, 4, 5, 6, 7, 8); 722 final Matrix3 comp = new Matrix3(-1, -1, -1, -1, -1, -1, -1, -1, -1); 723 assertFalse(mat3.equals(comp)); 724 assertFalse(mat3.strictEquals(comp)); 725 for (int i = 0; i < 8; i++) { 726 comp.setValue(i / 3, i % 3, i); 727 assertFalse(mat3.equals(comp)); 728 assertFalse(mat3.strictEquals(comp)); 729 } 730 } 731 732 @Test 733 public void testSimpleHash() { 734 // Just a simple sanity check. 735 final Matrix3 mat1 = new Matrix3(1, 2, 3, 4, 5, 6, 7, 8, 9); 736 final Matrix3 mat2 = new Matrix3(1, 2, 3, 4, 5, 6, 7, 8, 9); 737 final Matrix3 mat3 = new Matrix3(1, 2, 3, 4, 5, 6, 7, 8, 0); 738 739 assertTrue(mat1.hashCode() == mat2.hashCode()); 740 assertTrue(mat1.hashCode() != mat3.hashCode()); 741 } 742 743 @Test 744 public void testOrthonormal() { 745 final Matrix3 mat3 = new Matrix3(); 746 assertTrue(mat3.isOrthonormal()); 747 // just rotation 748 mat3.applyRotationX(MathUtils.QUARTER_PI); 749 assertTrue(mat3.isOrthonormal()); 750 // non-uniform scale 751 mat3.setIdentity(); 752 mat3.scaleLocal(new Vector3(1, 2, 3)); 753 assertFalse(mat3.isOrthonormal()); 754 // non-uniform scale + rotation 755 mat3.setIdentity(); 756 mat3.scaleLocal(new Vector3(1, 2, 3)); 757 mat3.applyRotationX(MathUtils.QUARTER_PI); 758 assertFalse(mat3.isOrthonormal()); 759 } 760 761 @Test 762 public void testApplyVector3() { 763 final Matrix3 mat3 = new Matrix3().applyRotationX(MathUtils.HALF_PI); 764 final Vector3 vec3 = new Vector3(0, 1, 0); 765 final Vector3 result = mat3.applyPost(vec3, null); 766 assertTrue(Math.abs(new Vector3(0, 0, 1).distance(result)) <= MathUtils.EPSILON); 767 vec3.set(0, 1, 1); 768 mat3.applyPost(vec3, result); 769 assertTrue(Math.abs(new Vector3(0, -1, 1).distance(result)) <= MathUtils.EPSILON); 770 771 vec3.set(0, 1, 1); 772 mat3.applyPre(vec3, result); 773 assertTrue(Math.abs(new Vector3(0, 1, -1).distance(result)) <= MathUtils.EPSILON); 774 775 vec3.set(1, 1, 1); 776 assertTrue(Math.abs(new Vector3(1, 1, -1).distance(mat3.applyPre(vec3, null))) <= MathUtils.EPSILON); 777 } 778 779 @Test 780 public void testStartEnd() { 781 final Matrix3 mat3 = new Matrix3(); 782 mat3.fromStartEndLocal(Vector3.UNIT_X, Vector3.UNIT_Y); // should be a 90 degree turn around Z 783 assertEquals(new Vector3(-1, 1, 1), mat3.applyPost(new Vector3(1, 1, 1), null)); 784 785 // coverage 786 mat3.fromStartEndLocal(new Vector3(1, 0, 0), new Vector3(1 + Double.MIN_VALUE, 0, 0)); 787 assertTrue(mat3.applyPost(Vector3.ONE, null).distance(Vector3.ONE) < MathUtils.ZERO_TOLERANCE); 788 mat3.fromStartEndLocal(new Vector3(0, 1, 0), new Vector3(0, 1 + Double.MIN_VALUE, 0)); 789 assertTrue(mat3.applyPost(Vector3.ONE, null).distance(Vector3.ONE) < MathUtils.ZERO_TOLERANCE); 790 mat3.fromStartEndLocal(new Vector3(0, 0, 1), new Vector3(0, 0, 1 + Double.MIN_VALUE)); 791 assertTrue(mat3.applyPost(Vector3.ONE, null).distance(Vector3.ONE) < MathUtils.ZERO_TOLERANCE); 792 } 793 794 @Test 795 public void testLookAt() { 796 final Vector3 direction = new Vector3(-1, 0, 0); 797 final Matrix3 mat3 = new Matrix3().lookAt(direction, Vector3.UNIT_Y); 798 assertEquals(direction, mat3.applyPost(Vector3.UNIT_Z, null)); 799 800 direction.set(1, 1, 1).normalizeLocal(); 801 mat3.lookAt(direction, Vector3.UNIT_Y); 802 assertEquals(direction, mat3.applyPost(Vector3.UNIT_Z, null)); 803 804 direction.set(-1, 2, -1).normalizeLocal(); 805 mat3.lookAt(direction, Vector3.UNIT_Y); 806 assertEquals(direction, mat3.applyPost(Vector3.UNIT_Z, new Vector3())); 807 } 808}