aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/MatrixTest.cpp
diff options
context:
space:
mode:
authorGravatar egdaniel@google.com <egdaniel@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-15 21:12:11 +0000
committerGravatar egdaniel@google.com <egdaniel@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-15 21:12:11 +0000
commit259fbaf7a464827bc560517988daeb5836e11e98 (patch)
treedffe383235dc80f54a2e3080ed2d20d15b18f3d5 /tests/MatrixTest.cpp
parent0038c12f337b7037ef698e2723099c7e3b19c4ca (diff)
Add homogeneous point mapping to Matrix
Adds mapping of homogeneous points (points with three scalar components, where the last component is not 1). Includes fix for tests when running on 32 bit debug builds BUG= R=bsalomon@google.com Review URL: https://codereview.chromium.org/22816005 git-svn-id: http://skia.googlecode.com/svn/trunk@10755 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests/MatrixTest.cpp')
-rw-r--r--tests/MatrixTest.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
index 2f16d65661..8785730322 100644
--- a/tests/MatrixTest.cpp
+++ b/tests/MatrixTest.cpp
@@ -592,6 +592,144 @@ 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];
+ SkScalar ms[9] = {m[0], m[1], m[2],
+ m[3], m[4], m[5],
+ m[6], m[7], m[8]};
+ res[0] = src[0] * ms[0] + src[1] * ms[1] + src[2] * ms[2];
+ res[1] = src[0] * ms[3] + src[1] * ms[4] + src[2] * ms[5];
+ res[2] = src[0] * ms[6] + src[1] * ms[7] + src[2] * ms[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 +851,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"