1 /* 2 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package test.com.sun.javafx.test; 27 28 import javafx.scene.transform.Transform; 29 import static org.junit.Assert.assertEquals; 30 import static org.junit.Assert.assertTrue; 31 import com.sun.javafx.geom.transform.Affine3D; 32 import com.sun.javafx.geom.transform.BaseTransform; 33 import com.sun.javafx.geom.transform.GeneralTransform3D; 34 import com.sun.javafx.scene.transform.TransformUtils; 35 import javafx.geometry.Point3D; 36 import javafx.scene.transform.Affine; 37 import javafx.scene.transform.NonInvertibleTransformException; 38 import javafx.scene.transform.Rotate; 39 import javafx.scene.transform.Scale; 40 import javafx.scene.transform.Shear; 41 import javafx.scene.transform.Translate; 42 43 /** 44 * Helper class for transform tests. 45 */ 46 public final class TransformHelper { 47 48 /** 49 * Asserts the {@code matrix} equals to the specified expected values 50 */ 51 public static void assertMatrix(Transform matrix, 52 double mxx, double mxy, double mxz, double tx, 53 double myx, double myy, double myz, double ty, 54 double mzx, double mzy, double mzz, double tz) { 55 assertEquals(mxx, matrix.getMxx(), 0.00001); 56 assertEquals(mxy, matrix.getMxy(), 0.00001); 57 assertEquals(mxz, matrix.getMxz(), 0.00001); 58 assertEquals(tx, matrix.getTx(), 0.00001); 59 assertEquals(myx, matrix.getMyx(), 0.00001); 60 assertEquals(myy, matrix.getMyy(), 0.00001); 61 assertEquals(myz, matrix.getMyz(), 0.00001); 62 assertEquals(ty, matrix.getTy(), 0.00001); 63 assertEquals(mzx, matrix.getMzx(), 0.00001); 64 assertEquals(mzy, matrix.getMzy(), 0.00001); 65 assertEquals(mzz, matrix.getMzz(), 0.00001); 66 assertEquals(tz, matrix.getTz(), 0.00001); 67 } 68 69 /** 70 * Asserts the {@code matrix} equals to the specified expected values 71 */ 72 public static void assertMatrix(BaseTransform matrix, 73 double mxx, double mxy, double mxz, double tx, 74 double myx, double myy, double myz, double ty, 75 double mzx, double mzy, double mzz, double tz) { 76 assertEquals(mxx, matrix.getMxx(), 0.00001); 77 assertEquals(mxy, matrix.getMxy(), 0.00001); 78 assertEquals(mxz, matrix.getMxz(), 0.00001); 79 assertEquals(tx, matrix.getMxt(), 0.00001); 80 assertEquals(myx, matrix.getMyx(), 0.00001); 81 assertEquals(myy, matrix.getMyy(), 0.00001); 82 assertEquals(myz, matrix.getMyz(), 0.00001); 83 assertEquals(ty, matrix.getMyt(), 0.00001); 84 assertEquals(mzx, matrix.getMzx(), 0.00001); 85 assertEquals(mzy, matrix.getMzy(), 0.00001); 86 assertEquals(mzz, matrix.getMzz(), 0.00001); 87 assertEquals(tz, matrix.getMzt(), 0.00001); 88 } 89 90 /** 91 * Asserts the {@code matrix} elements equal to the expected values 92 * specified by {@code reference} 93 */ 94 public static void assertMatrix(Transform matrix, 95 Transform reference) { 96 assertEquals(reference.getMxx(), matrix.getMxx(), 0.00001); 97 assertEquals(reference.getMxy(), matrix.getMxy(), 0.00001); 98 assertEquals(reference.getMxz(), matrix.getMxz(), 0.00001); 99 assertEquals(reference.getTx(), matrix.getTx(), 0.00001); 100 assertEquals(reference.getMyx(), matrix.getMyx(), 0.00001); 101 assertEquals(reference.getMyy(), matrix.getMyy(), 0.00001); 102 assertEquals(reference.getMyz(), matrix.getMyz(), 0.00001); 103 assertEquals(reference.getTy(), matrix.getTy(), 0.00001); 104 assertEquals(reference.getMzx(), matrix.getMzx(), 0.00001); 105 assertEquals(reference.getMzy(), matrix.getMzy(), 0.00001); 106 assertEquals(reference.getMzz(), matrix.getMzz(), 0.00001); 107 assertEquals(reference.getTz(), matrix.getTz(), 0.00001); 108 } 109 110 /** 111 * Asserts the {@code matrix} elements equal to the expected values 112 * specified by {@code reference} 113 */ 114 public static void assertMatrix(Affine3D matrix, 115 BaseTransform reference) { 116 assertEquals(reference.getMxx(), matrix.getMxx(), 0.00001); 117 assertEquals(reference.getMxy(), matrix.getMxy(), 0.00001); 118 assertEquals(reference.getMxz(), matrix.getMxz(), 0.00001); 119 assertEquals(reference.getMxt(), matrix.getMxt(), 0.00001); 120 assertEquals(reference.getMyx(), matrix.getMyx(), 0.00001); 121 assertEquals(reference.getMyy(), matrix.getMyy(), 0.00001); 122 assertEquals(reference.getMyz(), matrix.getMyz(), 0.00001); 123 assertEquals(reference.getMyt(), matrix.getMyt(), 0.00001); 124 assertEquals(reference.getMzx(), matrix.getMzx(), 0.00001); 125 assertEquals(reference.getMzy(), matrix.getMzy(), 0.00001); 126 assertEquals(reference.getMzz(), matrix.getMzz(), 0.00001); 127 assertEquals(reference.getMzt(), matrix.getMzt(), 0.00001); 128 } 129 130 /** 131 * Asserts the {@code matrix} elements equal to the expected values 132 * specified by {@code reference} 133 */ 134 public static void assertMatrix(String message, Transform matrix, 135 Transform reference) { 136 assertEquals(message, reference.getMxx(), matrix.getMxx(), 0.00001); 137 assertEquals(message, reference.getMxy(), matrix.getMxy(), 0.00001); 138 assertEquals(message, reference.getMxz(), matrix.getMxz(), 0.00001); 139 assertEquals(message, reference.getTx(), matrix.getTx(), 0.00001); 140 assertEquals(message, reference.getMyx(), matrix.getMyx(), 0.00001); 141 assertEquals(message, reference.getMyy(), matrix.getMyy(), 0.00001); 142 assertEquals(message, reference.getMyz(), matrix.getMyz(), 0.00001); 143 assertEquals(message, reference.getTy(), matrix.getTy(), 0.00001); 144 assertEquals(message, reference.getMzx(), matrix.getMzx(), 0.00001); 145 assertEquals(message, reference.getMzy(), matrix.getMzy(), 0.00001); 146 assertEquals(message, reference.getMzz(), matrix.getMzz(), 0.00001); 147 assertEquals(message, reference.getTz(), matrix.getTz(), 0.00001); 148 } 149 150 /** 151 * Asserts the {@code matrix} elements equal to the expected values 152 * specified by {@code reference} 153 */ 154 public static void assertMatrix(GeneralTransform3D matrix, 155 GeneralTransform3D reference) { 156 for (int i = 0; i < 16; i++) { 157 assertEquals(reference.get(i), matrix.get(i), 0.00001); 158 } 159 } 160 161 /** 162 * Asserts the {@code matrix} is NOT equal to the specified values 163 */ 164 public static void assertMatrixDiffers(Transform matrix, 165 double mxx, double mxy, double mxz, double tx, 166 double myx, double myy, double myz, double ty, 167 double mzx, double mzy, double mzz, double tz) { 168 assertTrue( 169 mxx != matrix.getMxx() || 170 mxy != matrix.getMxy() || 171 mxz != matrix.getMxz() || 172 tx != matrix.getTx() || 173 myx != matrix.getMyx() || 174 myy != matrix.getMyy() || 175 myz != matrix.getMyz() || 176 ty != matrix.getTy() || 177 mzx != matrix.getMzx() || 178 mzy != matrix.getMzy() || 179 mzz != matrix.getMzz() || 180 tz != matrix.getTz()); 181 } 182 183 /** 184 * Inverts the given transform. 185 * @throws NonInvertibleTransformException 186 */ 187 public static Transform invert(Transform t) 188 throws NonInvertibleTransformException { 189 190 final double det = determinant(t); 191 if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { 192 throw new NonInvertibleTransformException("Det is 0"); 193 } 194 195 final double cxx = minor(t, 0, 0); 196 final double cyx = - minor(t, 0, 1); 197 final double czx = minor(t, 0, 2); 198 final double cxy = - minor(t, 1, 0); 199 final double cyy = minor(t, 1, 1); 200 final double czy = - minor(t, 1, 2); 201 final double cxz = minor(t, 2, 0); 202 final double cyz = - minor(t, 2, 1); 203 final double czz = minor(t, 2, 2); 204 final double cxt = - minor(t, 3, 0); 205 final double cyt = minor(t, 3, 1); 206 final double czt = - minor(t, 3, 2); 207 208 return TransformUtils.immutableTransform( 209 cxx / det, cxy / det, cxz / det, cxt / det, 210 cyx / det, cyy / det, cyz / det, cyt / det, 211 czx / det, czy / det, czz / det, czt / det); 212 } 213 214 /** 215 * Concatenates the two transforms. 216 */ 217 public static Transform concatenate(Transform t1, Transform t2) { 218 219 final double txx = t2.getMxx(); 220 final double txy = t2.getMxy(); 221 final double txz = t2.getMxz(); 222 final double ttx = t2.getTx(); 223 final double tyx = t2.getMyx(); 224 final double tyy = t2.getMyy(); 225 final double tyz = t2.getMyz(); 226 final double tty = t2.getTy(); 227 final double tzx = t2.getMzx(); 228 final double tzy = t2.getMzy(); 229 final double tzz = t2.getMzz(); 230 final double ttz = t2.getTz(); 231 final double rxx = (t1.getMxx() * txx + t1.getMxy() * tyx + t1.getMxz() * tzx /* + getMxt * 0.0 */); 232 final double rxy = (t1.getMxx() * txy + t1.getMxy() * tyy + t1.getMxz() * tzy /* + getMxt * 0.0 */); 233 final double rxz = (t1.getMxx() * txz + t1.getMxy() * tyz + t1.getMxz() * tzz /* + getMxt * 0.0 */); 234 final double rxt = (t1.getMxx() * ttx + t1.getMxy() * tty + t1.getMxz() * ttz + t1.getTx() /* * 1.0 */); 235 final double ryx = (t1.getMyx() * txx + t1.getMyy() * tyx + t1.getMyz() * tzx /* + getMyt * 0.0 */); 236 final double ryy = (t1.getMyx() * txy + t1.getMyy() * tyy + t1.getMyz() * tzy /* + getMyt * 0.0 */); 237 final double ryz = (t1.getMyx() * txz + t1.getMyy() * tyz + t1.getMyz() * tzz /* + getMyt * 0.0 */); 238 final double ryt = (t1.getMyx() * ttx + t1.getMyy() * tty + t1.getMyz() * ttz + t1.getTy() /* * 1.0 */); 239 final double rzx = (t1.getMzx() * txx + t1.getMzy() * tyx + t1.getMzz() * tzx /* + getMzt * 0.0 */); 240 final double rzy = (t1.getMzx() * txy + t1.getMzy() * tyy + t1.getMzz() * tzy /* + getMzt * 0.0 */); 241 final double rzz = (t1.getMzx() * txz + t1.getMzy() * tyz + t1.getMzz() * tzz /* + getMzt * 0.0 */); 242 final double rzt = (t1.getMzx() * ttx + t1.getMzy() * tty + t1.getMzz() * ttz + t1.getTz() /* * 1.0 */); 243 244 return TransformUtils.immutableTransform( 245 rxx, rxy, rxz, rxt, 246 ryx, ryy, ryz, ryt, 247 rzx, rzy, rzz, rzt); 248 } 249 250 /** 251 * Concatenates the two transforms. 252 */ 253 public static Transform concatenate(BaseTransform t1, Transform t2) { 254 255 final double txx = t2.getMxx(); 256 final double txy = t2.getMxy(); 257 final double txz = t2.getMxz(); 258 final double ttx = t2.getTx(); 259 final double tyx = t2.getMyx(); 260 final double tyy = t2.getMyy(); 261 final double tyz = t2.getMyz(); 262 final double tty = t2.getTy(); 263 final double tzx = t2.getMzx(); 264 final double tzy = t2.getMzy(); 265 final double tzz = t2.getMzz(); 266 final double ttz = t2.getTz(); 267 final double rxx = (t1.getMxx() * txx + t1.getMxy() * tyx + t1.getMxz() * tzx /* + getMxt * 0.0 */); 268 final double rxy = (t1.getMxx() * txy + t1.getMxy() * tyy + t1.getMxz() * tzy /* + getMxt * 0.0 */); 269 final double rxz = (t1.getMxx() * txz + t1.getMxy() * tyz + t1.getMxz() * tzz /* + getMxt * 0.0 */); 270 final double rxt = (t1.getMxx() * ttx + t1.getMxy() * tty + t1.getMxz() * ttz + t1.getMxt() /* * 1.0 */); 271 final double ryx = (t1.getMyx() * txx + t1.getMyy() * tyx + t1.getMyz() * tzx /* + getMyt * 0.0 */); 272 final double ryy = (t1.getMyx() * txy + t1.getMyy() * tyy + t1.getMyz() * tzy /* + getMyt * 0.0 */); 273 final double ryz = (t1.getMyx() * txz + t1.getMyy() * tyz + t1.getMyz() * tzz /* + getMyt * 0.0 */); 274 final double ryt = (t1.getMyx() * ttx + t1.getMyy() * tty + t1.getMyz() * ttz + t1.getMyt() /* * 1.0 */); 275 final double rzx = (t1.getMzx() * txx + t1.getMzy() * tyx + t1.getMzz() * tzx /* + getMzt * 0.0 */); 276 final double rzy = (t1.getMzx() * txy + t1.getMzy() * tyy + t1.getMzz() * tzy /* + getMzt * 0.0 */); 277 final double rzz = (t1.getMzx() * txz + t1.getMzy() * tyz + t1.getMzz() * tzz /* + getMzt * 0.0 */); 278 final double rzt = (t1.getMzx() * ttx + t1.getMzy() * tty + t1.getMzz() * ttz + t1.getMzt() /* * 1.0 */); 279 280 return TransformUtils.immutableTransform( 281 rxx, rxy, rxz, rxt, 282 ryx, ryy, ryz, ryt, 283 rzx, rzy, rzz, rzt); 284 } 285 286 /** 287 * Computes determinant of the specified transform. 288 */ 289 public static double determinant(Transform t) { 290 return 291 t.getMxx() * (t.getMyy() * t.getMzz() - t.getMzy() * t.getMyz()) + 292 t.getMxy() * (t.getMyz() * t.getMzx() - t.getMzz() * t.getMyx()) + 293 t.getMxz() * (t.getMyx() * t.getMzy() - t.getMzx() * t.getMyy()); 294 } 295 296 /** 297 * Needed for inversion. 298 */ 299 private static double minor(Transform t, int row, int col) { 300 double m00 = t.getMxx(), m01 = t.getMxy(), m02 = t.getMxz(); 301 double m10 = t.getMyx(), m11 = t.getMyy(), m12 = t.getMyz(); 302 double m20 = t.getMzx(), m21 = t.getMzy(), m22 = t.getMzz(); 303 switch (col) { 304 case 0: 305 m00 = m01; 306 m10 = m11; 307 m20 = m21; 308 case 1: 309 m01 = m02; 310 m11 = m12; 311 m21 = m22; 312 case 2: 313 m02 = t.getTx(); 314 m12 = t.getTy(); 315 m22 = t.getTz(); 316 } 317 switch (row) { 318 case 0: 319 m00 = m10; 320 m01 = m11; 321 // m02 = m12; 322 case 1: 323 m10 = m20; 324 m11 = m21; 325 // m12 = m22; 326 case 2: 327 // m20 = 0.0; 328 // m21 = 0.0; 329 // m22 = 1.0; 330 break; 331 case 3: 332 // This is the only row that requires a full 3x3 determinant 333 return (m00 * (m11 * m22 - m21 * m12) + 334 m01 * (m12 * m20 - m22 * m10) + 335 m02 * (m10 * m21 - m20 * m11)); 336 } 337 // return (m00 * (m11 * 1.0 - 0.0 * m12) + 338 // m01 * (m12 * 0.0 - 1.0 * m10) + 339 // m02 * (m10 * 0.0 - 0.0 * m11)); 340 return (m00 * m11 - m01 * m10); 341 } 342 343 /** 344 * Modifies the given transform, if possible. 345 * @param t Transform to modify 346 * @param value Value to set to one of transform's properties 347 * @return true if the transform was modified 348 */ 349 public static boolean modify(Transform t, double value) { 350 if (t instanceof Translate) { 351 ((Translate) t).setY(value); 352 } else if (t instanceof Scale) { 353 ((Scale) t).setY(value); 354 } else if (t instanceof Shear) { 355 ((Shear) t).setY(value); 356 } else if (t instanceof Rotate) { 357 Rotate r = (Rotate) t; 358 if (r.getAxis().equals(new Point3D(0, 0, 0))) { 359 r.setAxis(Rotate.Z_AXIS); 360 } 361 if ((r.getAxis().getX() != 0 || r.getAxis().getY() != 0) && r.getAngle() == 0) { 362 r.setAxis(Rotate.Z_AXIS); 363 } 364 r.setAngle(value); 365 } else if (t instanceof Affine) { 366 ((Affine) t).setMyx(value); 367 } else { 368 return false; 369 } 370 371 return true; 372 } 373 374 /** 375 * Makes a small modification to the transform, if possible. 376 * @param t Transform to modify 377 * @return true if the transform was modified 378 */ 379 public static boolean tinyModify(Transform t) { 380 if (t instanceof Translate) { 381 Translate tr = (Translate) t; 382 tr.setY(tr.getY() + 1); 383 if (tr.getZ() != 0) { 384 tr.setZ(tr.getZ() + 3); 385 } 386 } else if (t instanceof Scale) { 387 Scale sc = (Scale) t; 388 sc.setY(sc.getY() + 0.01); 389 if (sc.getZ() != 1) { 390 sc.setZ(sc.getZ() + 0.01); 391 } 392 } else if (t instanceof Shear) { 393 ((Shear) t).setY(((Shear) t).getY() + 0.01); 394 } else if (t instanceof Rotate) { 395 Rotate r = (Rotate) t; 396 if (r.getAxis().getX() == 0 && 397 r.getAxis().getY() == 0 && 398 r.getAxis().getZ() == 0) { 399 return false; 400 } 401 if ((r.getAxis().getX() != 0 || r.getAxis().getY() != 0) && r.getAngle() == 0) { 402 return false; 403 } 404 r.setAngle(r.getAngle() + 0.2); 405 } else if (t instanceof Affine) { 406 Affine a = (Affine) t; 407 a.setTy(a.getTy() + 1); 408 if (!a.isType2D()) { 409 a.setMzz(a.getMzz() + 2); 410 } 411 } else { 412 return false; 413 } 414 415 return true; 416 } 417 418 /** 419 * Makes a small modification to one of the 3D (Z-axis-effective) properties 420 * of the transform, if possible. 421 * @param t Transform to modify 422 * @return true if the transform was modified 423 */ 424 public static boolean tinyModify3D(Transform t) { 425 if (t instanceof Translate) { 426 ((Translate) t).setZ(((Translate) t).getZ() + 1); 427 } else if (t instanceof Scale) { 428 ((Scale) t).setZ(((Scale) t).getZ() + 0.01); 429 } else if (t instanceof Shear) { 430 return false; 431 } else if (t instanceof Rotate) { 432 Rotate r = (Rotate) t; 433 if (r.getAxis().getX() == 0 && 434 r.getAxis().getY() == 0 && 435 r.getAxis().getZ() == 0) { 436 return false; 437 } 438 r.setAngle(r.getAngle() + 0.2); 439 } else if (t instanceof Affine) { 440 ((Affine) t).setTy(((Affine) t).getTy() + 1); 441 } else { 442 return false; 443 } 444 445 return true; 446 } 447 448 /** 449 * Makes the transform 3D, if possible. 450 * @param t Transform to modify 451 * @return true if the transform was modified to a 3D state 452 */ 453 public static boolean make3D(Transform t) { 454 if (t instanceof Translate) { 455 ((Translate) t).setZ(42); 456 } else if (t instanceof Scale) { 457 ((Scale) t).setZ(42); 458 } else if (t instanceof Shear) { 459 return false; 460 } else if (t instanceof Rotate) { 461 Rotate r = (Rotate) t; 462 if (r.getAxis().getX() == 0 && r.getAxis().getY() == 0) { 463 r.setAxis(Rotate.Y_AXIS); 464 } 465 if (r.getAngle() == 0) { 466 r.setAngle(23); 467 } 468 } else if (t instanceof Affine) { 469 ((Affine) t).setMyz(42); 470 } else { 471 return false; 472 } 473 474 return true; 475 } 476 477 /** 478 * Makes the transform 2D, if possible. 479 * @param t Transform to modify 480 * @return true if the transform was modified to a 2D state 481 */ 482 public static boolean make2D(Transform t) { 483 if (t instanceof Translate) { 484 ((Translate) t).setZ(0); 485 } else if (t instanceof Scale) { 486 ((Scale) t).setZ(1); 487 } else if (t instanceof Shear) { 488 return true; 489 } else if (t instanceof Rotate) { 490 ((Rotate) t).setAxis(Rotate.Z_AXIS); 491 } else if (t instanceof Affine) { 492 ((Affine) t).setToIdentity(); 493 } else { 494 return false; 495 } 496 497 return true; 498 } 499 500 /** 501 * Makes the transform identity, if possible. 502 * @param t Transform to modify 503 * @return true if the transform was modified to an identity state 504 */ 505 public static boolean makeIdentity(Transform t) { 506 if (t instanceof Translate) { 507 ((Translate) t).setX(0); 508 ((Translate) t).setY(0); 509 ((Translate) t).setZ(0); 510 } else if (t instanceof Scale) { 511 ((Scale) t).setX(1); 512 ((Scale) t).setY(1); 513 ((Scale) t).setZ(1); 514 } else if (t instanceof Shear) { 515 ((Shear) t).setX(0); 516 ((Shear) t).setY(0); 517 } else if (t instanceof Rotate) { 518 ((Rotate) t).setAngle(0); 519 } else if (t instanceof Affine) { 520 ((Affine) t).setToIdentity(); 521 } else { 522 return false; 523 } 524 525 return true; 526 } 527 528 private static enum State2D { 529 IDENTITY(0), 530 TRANSLATE(1), 531 SCALE(2), 532 SC_TR(3), 533 SHEAR(4), 534 SH_TR(5), 535 SH_SC(6), 536 SH_SC_TR(7); 537 538 private int value; 539 540 private State2D(int value) { 541 this.value = value; 542 } 543 544 public int getValue() { 545 return value; 546 } 547 } 548 549 private static enum State3D { 550 NON_3D(0), 551 TRANSLATE(1), 552 SCALE(2), 553 SC_TR(3), 554 COMPLEX(4); 555 556 private int value; 557 558 private State3D(int value) { 559 this.value = value; 560 } 561 562 public int getValue() { 563 return value; 564 } 565 } 566 567 private static State2D getExpectedState2D(Transform t) { 568 if (t.getMxy() == 0.0 && t.getMyx() == 0.0) { 569 if (t.getMxx() == 1.0 && t.getMyy() == 1.0) { 570 if (t.getTx() == 0.0 && t.getTy() == 0.0) { 571 return State2D.IDENTITY; 572 } else { 573 return State2D.TRANSLATE; 574 } 575 } else { 576 if (t.getTx() == 0.0 && t.getTy() == 0.0) { 577 return State2D.SCALE; 578 } else { 579 return State2D.SC_TR; 580 } 581 } 582 } else { 583 if (t.getMxx() == 0.0 && t.getMyy() == 0.0) { 584 if (t.getTx() == 0.0 && t.getTy() == 0.0) { 585 return State2D.SHEAR; 586 } else { 587 return State2D.SH_TR; 588 } 589 } else { 590 if (t.getTx() == 0.0 && t.getTy() == 0.0) { 591 return State2D.SH_SC; 592 } else { 593 return State2D.SH_SC_TR; 594 } 595 } 596 } 597 } 598 599 private static State3D getExpectedState3D(Transform t) { 600 if (t.getMxz() == 0.0 && t.getMyz() == 0.0 && 601 t.getMzx() == 0.0 && t.getMzy() == 0.0 && 602 t.getMzz() == 1.0 && t.getTz() == 0.0) { 603 return State3D.NON_3D; 604 } 605 606 if (t.getMxy() != 0.0 || t.getMxz() != 0.0 || 607 t.getMyx() != 0.0 || t.getMyz() != 0.0 || 608 t.getMzx() != 0.0 || t.getMzy() != 0.0) { 609 return State3D.COMPLEX; 610 } 611 612 if ((t.getMxx() != 1.0 || t.getMyy() != 1.0 || t.getMzz() != 1.0) && 613 (t.getTx() != 0.0 || t.getTy() != 0.0 || t.getTz() != 0.0)) { 614 return State3D.SC_TR; 615 } 616 617 if (t.getMxx() != 1.0 || t.getMyy() != 1.0 || t.getMzz() != 1.0) { 618 return State3D.SCALE; 619 } 620 if (t.getTx() != 0.0 || t.getTy() != 0.0 || t.getTz() != 0.0) { 621 return State3D.TRANSLATE; 622 } 623 return null; 624 } 625 626 public static void assertStateOk(Transform t, int state3d, int state2d) { 627 TransformHelper.State3D expectedState3D = TransformHelper.getExpectedState3D(t); 628 assertEquals(expectedState3D.getValue(), state3d); 629 if (expectedState3D == TransformHelper.State3D.NON_3D) { 630 assertEquals(TransformHelper.getExpectedState2D(t).getValue(), state2d); 631 } 632 } 633 634 public static void assertStateOk(String message, Transform t, int state3d, int state2d) { 635 TransformHelper.State3D expectedState3D = TransformHelper.getExpectedState3D(t); 636 assertEquals(message, expectedState3D.getValue(), state3d); 637 if (expectedState3D == TransformHelper.State3D.NON_3D) { 638 assertEquals(message, TransformHelper.getExpectedState2D(t).getValue(), state2d); 639 } 640 } 641 642 /** 643 * Convenient factory for 2D immutable transforms. 644 */ 645 public static Transform immutableTransform( 646 double mxx, double mxy, double tx, 647 double myx, double myy, double ty) { 648 return TransformUtils.immutableTransform( 649 mxx, mxy, 0.0, tx, 650 myx, myy, 0.0, ty, 651 0.0, 0.0, 1.0, 0.0); 652 } 653 654 /** 655 * Creates a raw transformation to test the Transform class. 656 */ 657 public static Transform rawTransform( 658 double mxx, double mxy, double mxz, double tx, 659 double myx, double myy, double myz, double ty, 660 double mzx, double mzy, double mzz, double tz) { 661 return new RawTransform( 662 mxx, mxy, mxz, tx, 663 myx, myy, myz, ty, 664 mzx, mzy, mzz, tz); 665 } 666 667 private static class RawTransform extends Transform { 668 private final double mxx, mxy, mxz, tx; 669 private final double myx, myy, myz, ty; 670 private final double mzx, mzy, mzz, tz; 671 672 public RawTransform( 673 double mxx, double mxy, double mxz, double tx, 674 double myx, double myy, double myz, double ty, 675 double mzx, double mzy, double mzz, double tz) { 676 this.mxx = mxx; 677 this.mxy = mxy; 678 this.mxz = mxz; 679 this.tx = tx; 680 this.myx = myx; 681 this.myy = myy; 682 this.myz = myz; 683 this.ty = ty; 684 this.mzx = mzx; 685 this.mzy = mzy; 686 this.mzz = mzz; 687 this.tz = tz; 688 } 689 690 @Override 691 public double getMxx() { 692 return mxx; 693 } 694 695 @Override 696 public double getMxy() { 697 return mxy; 698 } 699 700 @Override 701 public double getMxz() { 702 return mxz; 703 } 704 705 @Override 706 public double getTx() { 707 return tx; 708 } 709 710 @Override 711 public double getMyx() { 712 return myx; 713 } 714 715 @Override 716 public double getMyy() { 717 return myy; 718 } 719 720 @Override 721 public double getMyz() { 722 return myz; 723 } 724 725 @Override 726 public double getTy() { 727 return ty; 728 } 729 730 @Override 731 public double getMzx() { 732 return mzx; 733 } 734 735 @Override 736 public double getMzy() { 737 return mzy; 738 } 739 740 @Override 741 public double getMzz() { 742 return mzz; 743 } 744 745 @Override 746 public double getTz() { 747 return tz; 748 } 749 750 @Override 751 public void impl_apply(Affine3D t) { 752 t.concatenate( 753 getMxx(), getMxy(), getMxz(), getTx(), 754 getMyx(), getMyy(), getMyz(), getTy(), 755 getMzx(), getMzy(), getMzz(), getTz()); 756 } 757 758 @Override 759 public BaseTransform impl_derive(BaseTransform t) { 760 return t.deriveWithConcatenation( 761 getMxx(), getMxy(), getMxz(), getTx(), 762 getMyx(), getMyy(), getMyz(), getTy(), 763 getMzx(), getMzy(), getMzz(), getTz()); 764 } 765 } 766 }