OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "SkMath.h" | 9 #include "SkMath.h" |
10 #include "SkMatrix.h" | 10 #include "SkMatrix.h" |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); | 338 mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); |
339 REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 339 REPORTER_ASSERT(reporter, !mat.isSimilarity()); |
340 | 340 |
341 // scales zero, only skews | 341 // scales zero, only skews |
342 mat.setAll(0, SK_Scalar1, 0, | 342 mat.setAll(0, SK_Scalar1, 0, |
343 SK_Scalar1, 0, 0, | 343 SK_Scalar1, 0, 0, |
344 0, 0, SkMatrix::I()[8]); | 344 0, 0, SkMatrix::I()[8]); |
345 REPORTER_ASSERT(reporter, mat.isSimilarity()); | 345 REPORTER_ASSERT(reporter, mat.isSimilarity()); |
346 } | 346 } |
347 | 347 |
| 348 static void test_matrix_decomposition(skiatest::Reporter* reporter) { |
| 349 SkMatrix mat;//, rotate0, rotate1, uniformScale, anisoScale; |
| 350 SkScalar rotation0, scaleX, scaleY, rotation1; |
| 351 |
| 352 const float kRotation0 = 15.5f; |
| 353 const float kRotation1 = -50.f; |
| 354 const float kScale0 = 2000.f; |
| 355 const float kScale1 = 0.001f; |
| 356 |
| 357 // identity |
| 358 mat.reset(); |
| 359 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 360 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); |
| 361 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1)); |
| 362 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1)); |
| 363 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 364 // make sure it doesn't crash if we pass in NULLs |
| 365 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(NULL, NULL, NULL, NULL)); |
| 366 |
| 367 // rotation only |
| 368 mat.setRotate(kRotation0); |
| 369 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 370 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians(
kRotation0))); |
| 371 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1)); |
| 372 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1)); |
| 373 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 374 |
| 375 // uniform scale only |
| 376 mat.setScale(kScale0, kScale0); |
| 377 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 378 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); |
| 379 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 380 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0)); |
| 381 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 382 |
| 383 // anisotropic scale only |
| 384 mat.setScale(kScale0, kScale1); |
| 385 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 386 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); |
| 387 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 388 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale1)); |
| 389 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 390 |
| 391 // rotation then uniform scale |
| 392 mat.setRotate(kRotation1); |
| 393 mat.postScale(kScale0, kScale0); |
| 394 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 395 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians(
kRotation1))); |
| 396 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 397 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0)); |
| 398 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 399 |
| 400 // uniform scale then rotation |
| 401 mat.setScale(kScale0, kScale0); |
| 402 mat.postRotate(kRotation1); |
| 403 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 404 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians(
kRotation1))); |
| 405 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 406 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0)); |
| 407 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 408 |
| 409 // rotation then uniform scale+reflection |
| 410 mat.setRotate(kRotation0); |
| 411 mat.postScale(kScale1, -kScale1); |
| 412 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 413 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians(
kRotation0))); |
| 414 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1)); |
| 415 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale1)); |
| 416 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 417 |
| 418 // uniform scale+reflection, then rotate |
| 419 mat.setScale(kScale0, -kScale0); |
| 420 mat.postRotate(kRotation1); |
| 421 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 422 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians(
-kRotation1))); |
| 423 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 424 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale0)); |
| 425 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 426 |
| 427 // rotation then anisotropic scale |
| 428 mat.setRotate(kRotation1); |
| 429 mat.postScale(kScale1, kScale0); |
| 430 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 431 // because of the shear/skew we won't get the same results, so we need to mu
ltiply it out |
| 432 SkMatrix mat2; |
| 433 mat2.setRotate(rotation0*(180.f/SK_ScalarPI)); |
| 434 mat2.postScale(scaleX, scaleY); |
| 435 mat2.postRotate(rotation1*(180.f/SK_ScalarPI)); |
| 436 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX], |
| 437 mat2[SkMatrix::kMScaleX])); |
| 438 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX], |
| 439 mat2[SkMatrix::kMSkewX])); |
| 440 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY], |
| 441 mat2[SkMatrix::kMSkewY])); |
| 442 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY], |
| 443 mat2[SkMatrix::kMScaleY])); |
| 444 |
| 445 // anisotropic scale then rotation |
| 446 mat.setScale(kScale0, kScale1); |
| 447 mat.postRotate(kRotation0); |
| 448 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 449 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); |
| 450 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 451 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale1)); |
| 452 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation1, SkDegreesToRadians(
kRotation0))); |
| 453 |
| 454 // rotation, uniform scale, then different rotation |
| 455 mat.setRotate(kRotation1); |
| 456 mat.postScale(kScale0, kScale0); |
| 457 mat.postRotate(kRotation0); |
| 458 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 459 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, |
| 460 SkDegreesToRadians(kRotation0
+ kRotation1))); |
| 461 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0)); |
| 462 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0)); |
| 463 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1)); |
| 464 |
| 465 // rotation, anisotropic scale, then different rotation |
| 466 mat.setRotate(kRotation0); |
| 467 mat.postScale(kScale1, kScale0); |
| 468 mat.postRotate(kRotation1); |
| 469 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 470 // because of the shear/skew we won't get the same results, so we need to mu
ltiply it out |
| 471 mat2.setRotate(rotation0*(180.f/SK_ScalarPI)); |
| 472 mat2.postScale(scaleX, scaleY); |
| 473 mat2.postRotate(rotation1*(180.f/SK_ScalarPI)); |
| 474 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX], |
| 475 mat2[SkMatrix::kMScaleX])); |
| 476 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX], |
| 477 mat2[SkMatrix::kMSkewX])); |
| 478 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY], |
| 479 mat2[SkMatrix::kMSkewY])); |
| 480 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY], |
| 481 mat2[SkMatrix::kMScaleY])); |
| 482 |
| 483 // translation shouldn't affect this |
| 484 mat.postTranslate(-1000.f, 1000.f); |
| 485 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 486 // because of the shear/skew we won't get the same results, so we need to mu
ltiply it out |
| 487 mat2.setRotate(rotation0*(180.f/SK_ScalarPI)); |
| 488 mat2.postScale(scaleX, scaleY); |
| 489 mat2.postRotate(rotation1*(180.f/SK_ScalarPI)); |
| 490 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX], |
| 491 mat2[SkMatrix::kMScaleX])); |
| 492 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX], |
| 493 mat2[SkMatrix::kMSkewX])); |
| 494 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY], |
| 495 mat2[SkMatrix::kMSkewY])); |
| 496 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY], |
| 497 mat2[SkMatrix::kMScaleY])); |
| 498 |
| 499 // perspective shouldn't affect this |
| 500 mat[SkMatrix::kMPersp0] = 12.0; |
| 501 mat[SkMatrix::kMPersp1] = 4.0; |
| 502 mat[SkMatrix::kMPersp2] = 1872.0; |
| 503 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY
, &rotation1)); |
| 504 // because of the shear/skew we won't get the same results, so we need to mu
ltiply it out |
| 505 mat2.setRotate(rotation0*(180.f/SK_ScalarPI)); |
| 506 mat2.postScale(scaleX, scaleY); |
| 507 mat2.postRotate(rotation1*(180.f/SK_ScalarPI)); |
| 508 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX], |
| 509 mat2[SkMatrix::kMScaleX])); |
| 510 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX], |
| 511 mat2[SkMatrix::kMSkewX])); |
| 512 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY], |
| 513 mat2[SkMatrix::kMSkewY])); |
| 514 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY], |
| 515 mat2[SkMatrix::kMScaleY])); |
| 516 |
| 517 // degenerate matrices |
| 518 mat.reset(); |
| 519 mat[SkMatrix::kMScaleX] = 0.f; |
| 520 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale
Y, &rotation1)); |
| 521 mat.reset(); |
| 522 mat[SkMatrix::kMScaleY] = 0.f; |
| 523 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale
Y, &rotation1)); |
| 524 mat.reset(); |
| 525 mat[SkMatrix::kMScaleX] = 1.f; |
| 526 mat[SkMatrix::kMSkewX] = 2.f; |
| 527 mat[SkMatrix::kMSkewY] = 4.f; |
| 528 mat[SkMatrix::kMScaleY] = 8.f; // who do we appreciate? |
| 529 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale
Y, &rotation1)); |
| 530 } |
| 531 |
348 static void TestMatrix(skiatest::Reporter* reporter) { | 532 static void TestMatrix(skiatest::Reporter* reporter) { |
349 SkMatrix mat, inverse, iden1, iden2; | 533 SkMatrix mat, inverse, iden1, iden2; |
350 | 534 |
351 mat.reset(); | 535 mat.reset(); |
352 mat.setTranslate(SK_Scalar1, SK_Scalar1); | 536 mat.setTranslate(SK_Scalar1, SK_Scalar1); |
353 REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 537 REPORTER_ASSERT(reporter, mat.invert(&inverse)); |
354 iden1.setConcat(mat, inverse); | 538 iden1.setConcat(mat, inverse); |
355 REPORTER_ASSERT(reporter, is_identity(iden1)); | 539 REPORTER_ASSERT(reporter, is_identity(iden1)); |
356 | 540 |
357 mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); | 541 mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 // fixed pt doesn't have the property that NaN does not equal itself. | 642 // fixed pt doesn't have the property that NaN does not equal itself. |
459 #ifdef SK_SCALAR_IS_FIXED | 643 #ifdef SK_SCALAR_IS_FIXED |
460 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); | 644 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); |
461 #else | 645 #else |
462 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); | 646 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); |
463 #endif | 647 #endif |
464 | 648 |
465 test_matrix_max_stretch(reporter); | 649 test_matrix_max_stretch(reporter); |
466 test_matrix_is_similarity(reporter); | 650 test_matrix_is_similarity(reporter); |
467 test_matrix_recttorect(reporter); | 651 test_matrix_recttorect(reporter); |
| 652 test_matrix_decomposition(reporter); |
468 } | 653 } |
469 | 654 |
470 #include "TestClassDef.h" | 655 #include "TestClassDef.h" |
471 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) | 656 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) |
OLD | NEW |