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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc
aleY, &rotation1)); | 585 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc
aleY, &rotation1)); |
586 mat.reset(); | 586 mat.reset(); |
587 // linearly dependent entries | 587 // linearly dependent entries |
588 mat[SkMatrix::kMScaleX] = 1.f; | 588 mat[SkMatrix::kMScaleX] = 1.f; |
589 mat[SkMatrix::kMSkewX] = 2.f; | 589 mat[SkMatrix::kMSkewX] = 2.f; |
590 mat[SkMatrix::kMSkewY] = 4.f; | 590 mat[SkMatrix::kMSkewY] = 4.f; |
591 mat[SkMatrix::kMScaleY] = 8.f; | 591 mat[SkMatrix::kMScaleY] = 8.f; |
592 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc
aleY, &rotation1)); | 592 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc
aleY, &rotation1)); |
593 } | 593 } |
594 | 594 |
| 595 // For test_matrix_homogeneous, below. |
| 596 static bool scalar_array_nearly_equal_relative(const SkScalar a[], const SkScala
r b[], int count) { |
| 597 for (int i = 0; i < count; ++i) { |
| 598 if (!scalar_nearly_equal_relative(a[i], b[i])) { |
| 599 return false; |
| 600 } |
| 601 } |
| 602 return true; |
| 603 } |
| 604 |
| 605 // For test_matrix_homogeneous, below. |
| 606 // Maps a single triple in src using m and compares results to those in dst |
| 607 static bool naive_homogeneous_mapping(const SkMatrix& m, const SkScalar src[3], |
| 608 const SkScalar dst[3]) { |
| 609 SkScalar res[3]; |
| 610 res[0] = src[0] * m[0] + src[1] * m[1] + src[2] * m[2]; |
| 611 res[1] = src[0] * m[3] + src[1] * m[4] + src[2] * m[5]; |
| 612 res[2] = src[0] * m[6] + src[1] * m[7] + src[2] * m[8]; |
| 613 return scalar_array_nearly_equal_relative(res, dst, 3); |
| 614 } |
| 615 |
| 616 static void test_matrix_homogeneous(skiatest::Reporter* reporter) { |
| 617 SkMatrix mat; |
| 618 |
| 619 const float kRotation0 = 15.5f; |
| 620 const float kRotation1 = -50.f; |
| 621 const float kScale0 = 5000.f; |
| 622 |
| 623 const int kTripleCount = 1000; |
| 624 const int kMatrixCount = 1000; |
| 625 SkRandom rand; |
| 626 |
| 627 SkScalar randTriples[3*kTripleCount]; |
| 628 for (int i = 0; i < 3*kTripleCount; ++i) { |
| 629 randTriples[i] = rand.nextRangeF(-3000.f, 3000.f); |
| 630 } |
| 631 |
| 632 SkMatrix mats[kMatrixCount]; |
| 633 for (int i = 0; i < kMatrixCount; ++i) { |
| 634 for (int j = 0; j < 9; ++j) { |
| 635 mats[i].set(j, rand.nextRangeF(-3000.f, 3000.f)); |
| 636 } |
| 637 } |
| 638 |
| 639 // identity |
| 640 { |
| 641 mat.reset(); |
| 642 SkScalar dst[3*kTripleCount]; |
| 643 mat.mapHomogeneousPoints(dst, randTriples, kTripleCount); |
| 644 REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(randTriples, ds
t, kTripleCount*3)); |
| 645 } |
| 646 |
| 647 // zero matrix |
| 648 { |
| 649 mat.setAll(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f); |
| 650 SkScalar dst[3*kTripleCount]; |
| 651 mat.mapHomogeneousPoints(dst, randTriples, kTripleCount); |
| 652 SkScalar zeros[3] = {0.f, 0.f, 0.f}; |
| 653 for (int i = 0; i < kTripleCount; ++i) { |
| 654 REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(&dst[i*3],
zeros, 3)); |
| 655 } |
| 656 } |
| 657 |
| 658 // zero point |
| 659 { |
| 660 SkScalar zeros[3] = {0.f, 0.f, 0.f}; |
| 661 for (int i = 0; i < kMatrixCount; ++i) { |
| 662 SkScalar dst[3]; |
| 663 mats[i].mapHomogeneousPoints(dst, zeros, 1); |
| 664 REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(dst, zeros,
3)); |
| 665 } |
| 666 } |
| 667 |
| 668 // doesn't crash with null dst, src, count == 0 |
| 669 { |
| 670 mats[0].mapHomogeneousPoints(NULL, NULL, 0); |
| 671 } |
| 672 |
| 673 // uniform scale of point |
| 674 { |
| 675 mat.setScale(kScale0, kScale0); |
| 676 SkScalar dst[3]; |
| 677 SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; |
| 678 SkPoint pnt; |
| 679 pnt.set(src[0], src[1]); |
| 680 mat.mapHomogeneousPoints(dst, src, 1); |
| 681 mat.mapPoints(&pnt, &pnt, 1); |
| 682 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); |
| 683 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); |
| 684 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); |
| 685 } |
| 686 |
| 687 // rotation of point |
| 688 { |
| 689 mat.setRotate(kRotation0); |
| 690 SkScalar dst[3]; |
| 691 SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; |
| 692 SkPoint pnt; |
| 693 pnt.set(src[0], src[1]); |
| 694 mat.mapHomogeneousPoints(dst, src, 1); |
| 695 mat.mapPoints(&pnt, &pnt, 1); |
| 696 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); |
| 697 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); |
| 698 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); |
| 699 } |
| 700 |
| 701 // rotation, scale, rotation of point |
| 702 { |
| 703 mat.setRotate(kRotation1); |
| 704 mat.postScale(kScale0, kScale0); |
| 705 mat.postRotate(kRotation0); |
| 706 SkScalar dst[3]; |
| 707 SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; |
| 708 SkPoint pnt; |
| 709 pnt.set(src[0], src[1]); |
| 710 mat.mapHomogeneousPoints(dst, src, 1); |
| 711 mat.mapPoints(&pnt, &pnt, 1); |
| 712 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); |
| 713 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); |
| 714 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); |
| 715 } |
| 716 |
| 717 // compare with naive approach |
| 718 { |
| 719 for (int i = 0; i < kMatrixCount; ++i) { |
| 720 for (int j = 0; j < kTripleCount; ++j) { |
| 721 SkScalar dst[3]; |
| 722 mats[i].mapHomogeneousPoints(dst, &randTriples[j*3], 1); |
| 723 REPORTER_ASSERT(reporter, naive_homogeneous_mapping(mats[i], &randTr
iples[j*3], dst)); |
| 724 } |
| 725 } |
| 726 } |
| 727 |
| 728 } |
| 729 |
595 static void TestMatrix(skiatest::Reporter* reporter) { | 730 static void TestMatrix(skiatest::Reporter* reporter) { |
596 SkMatrix mat, inverse, iden1, iden2; | 731 SkMatrix mat, inverse, iden1, iden2; |
597 | 732 |
598 mat.reset(); | 733 mat.reset(); |
599 mat.setTranslate(SK_Scalar1, SK_Scalar1); | 734 mat.setTranslate(SK_Scalar1, SK_Scalar1); |
600 REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 735 REPORTER_ASSERT(reporter, mat.invert(&inverse)); |
601 iden1.setConcat(mat, inverse); | 736 iden1.setConcat(mat, inverse); |
602 REPORTER_ASSERT(reporter, is_identity(iden1)); | 737 REPORTER_ASSERT(reporter, is_identity(iden1)); |
603 | 738 |
604 mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); | 739 mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 #ifdef SK_SCALAR_IS_FIXED | 841 #ifdef SK_SCALAR_IS_FIXED |
707 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); | 842 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); |
708 #else | 843 #else |
709 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); | 844 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); |
710 #endif | 845 #endif |
711 | 846 |
712 test_matrix_max_stretch(reporter); | 847 test_matrix_max_stretch(reporter); |
713 test_matrix_is_similarity(reporter); | 848 test_matrix_is_similarity(reporter); |
714 test_matrix_recttorect(reporter); | 849 test_matrix_recttorect(reporter); |
715 test_matrix_decomposition(reporter); | 850 test_matrix_decomposition(reporter); |
| 851 test_matrix_homogeneous(reporter); |
716 } | 852 } |
717 | 853 |
718 #include "TestClassDef.h" | 854 #include "TestClassDef.h" |
719 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) | 855 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) |
OLD | NEW |