| Index: tests/MatrixTest.cpp
|
| diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
|
| index 2f16d656619bf0c881ad9a85f71285cb30196996..16801d1a76c5caf4d2670a4e738fd7c16187c476 100644
|
| --- a/tests/MatrixTest.cpp
|
| +++ b/tests/MatrixTest.cpp
|
| @@ -592,6 +592,141 @@ static void test_matrix_decomposition(skiatest::Reporter* reporter) {
|
| REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &scaleY, &rotation1));
|
| }
|
|
|
| +// For test_matrix_homogeneous, below.
|
| +static bool scalar_array_nearly_equal_relative(const SkScalar a[], const SkScalar b[], int count) {
|
| + for (int i = 0; i < count; ++i) {
|
| + if (!scalar_nearly_equal_relative(a[i], b[i])) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// For test_matrix_homogeneous, below.
|
| +// Maps a single triple in src using m and compares results to those in dst
|
| +static bool naive_homogeneous_mapping(const SkMatrix& m, const SkScalar src[3],
|
| + const SkScalar dst[3]) {
|
| + SkScalar res[3];
|
| + res[0] = src[0] * m[0] + src[1] * m[1] + src[2] * m[2];
|
| + res[1] = src[0] * m[3] + src[1] * m[4] + src[2] * m[5];
|
| + res[2] = src[0] * m[6] + src[1] * m[7] + src[2] * m[8];
|
| + return scalar_array_nearly_equal_relative(res, dst, 3);
|
| +}
|
| +
|
| +static void test_matrix_homogeneous(skiatest::Reporter* reporter) {
|
| + SkMatrix mat;
|
| +
|
| + const float kRotation0 = 15.5f;
|
| + const float kRotation1 = -50.f;
|
| + const float kScale0 = 5000.f;
|
| +
|
| + const int kTripleCount = 1000;
|
| + const int kMatrixCount = 1000;
|
| + SkRandom rand;
|
| +
|
| + SkScalar randTriples[3*kTripleCount];
|
| + for (int i = 0; i < 3*kTripleCount; ++i) {
|
| + randTriples[i] = rand.nextRangeF(-3000.f, 3000.f);
|
| + }
|
| +
|
| + SkMatrix mats[kMatrixCount];
|
| + for (int i = 0; i < kMatrixCount; ++i) {
|
| + for (int j = 0; j < 9; ++j) {
|
| + mats[i].set(j, rand.nextRangeF(-3000.f, 3000.f));
|
| + }
|
| + }
|
| +
|
| + // identity
|
| + {
|
| + mat.reset();
|
| + SkScalar dst[3*kTripleCount];
|
| + mat.mapHomogeneousPoints(dst, randTriples, kTripleCount);
|
| + REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(randTriples, dst, kTripleCount*3));
|
| + }
|
| +
|
| + // zero matrix
|
| + {
|
| + mat.setAll(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
|
| + SkScalar dst[3*kTripleCount];
|
| + mat.mapHomogeneousPoints(dst, randTriples, kTripleCount);
|
| + SkScalar zeros[3] = {0.f, 0.f, 0.f};
|
| + for (int i = 0; i < kTripleCount; ++i) {
|
| + REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(&dst[i*3], zeros, 3));
|
| + }
|
| + }
|
| +
|
| + // zero point
|
| + {
|
| + SkScalar zeros[3] = {0.f, 0.f, 0.f};
|
| + for (int i = 0; i < kMatrixCount; ++i) {
|
| + SkScalar dst[3];
|
| + mats[i].mapHomogeneousPoints(dst, zeros, 1);
|
| + REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(dst, zeros, 3));
|
| + }
|
| + }
|
| +
|
| + // doesn't crash with null dst, src, count == 0
|
| + {
|
| + mats[0].mapHomogeneousPoints(NULL, NULL, 0);
|
| + }
|
| +
|
| + // uniform scale of point
|
| + {
|
| + mat.setScale(kScale0, kScale0);
|
| + SkScalar dst[3];
|
| + SkScalar src[3] = {randTriples[0], randTriples[1], 1.f};
|
| + SkPoint pnt;
|
| + pnt.set(src[0], src[1]);
|
| + mat.mapHomogeneousPoints(dst, src, 1);
|
| + mat.mapPoints(&pnt, &pnt, 1);
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1));
|
| + }
|
| +
|
| + // rotation of point
|
| + {
|
| + mat.setRotate(kRotation0);
|
| + SkScalar dst[3];
|
| + SkScalar src[3] = {randTriples[0], randTriples[1], 1.f};
|
| + SkPoint pnt;
|
| + pnt.set(src[0], src[1]);
|
| + mat.mapHomogeneousPoints(dst, src, 1);
|
| + mat.mapPoints(&pnt, &pnt, 1);
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1));
|
| + }
|
| +
|
| + // rotation, scale, rotation of point
|
| + {
|
| + mat.setRotate(kRotation1);
|
| + mat.postScale(kScale0, kScale0);
|
| + mat.postRotate(kRotation0);
|
| + SkScalar dst[3];
|
| + SkScalar src[3] = {randTriples[0], randTriples[1], 1.f};
|
| + SkPoint pnt;
|
| + pnt.set(src[0], src[1]);
|
| + mat.mapHomogeneousPoints(dst, src, 1);
|
| + mat.mapPoints(&pnt, &pnt, 1);
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY));
|
| + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1));
|
| + }
|
| +
|
| + // compare with naive approach
|
| + {
|
| + for (int i = 0; i < kMatrixCount; ++i) {
|
| + for (int j = 0; j < kTripleCount; ++j) {
|
| + SkScalar dst[3];
|
| + mats[i].mapHomogeneousPoints(dst, &randTriples[j*3], 1);
|
| + REPORTER_ASSERT(reporter, naive_homogeneous_mapping(mats[i], &randTriples[j*3], dst));
|
| + }
|
| + }
|
| + }
|
| +
|
| +}
|
| +
|
| static void TestMatrix(skiatest::Reporter* reporter) {
|
| SkMatrix mat, inverse, iden1, iden2;
|
|
|
| @@ -713,6 +848,7 @@ static void TestMatrix(skiatest::Reporter* reporter) {
|
| test_matrix_is_similarity(reporter);
|
| test_matrix_recttorect(reporter);
|
| test_matrix_decomposition(reporter);
|
| + test_matrix_homogeneous(reporter);
|
| }
|
|
|
| #include "TestClassDef.h"
|
|
|