Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(571)

Unified Diff: tests/Matrix44Test.cpp

Issue 508303005: SkMatrix44::preserves2dAxisAlignment() (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix perspective check, add tolerance Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/utils/SkMatrix44.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/Matrix44Test.cpp
diff --git a/tests/Matrix44Test.cpp b/tests/Matrix44Test.cpp
index 443086dbef5a298c394e5aa230586231b2fb5bff..3bb4c5591e3cc9c18b5d4c794f01bfcd22f9b9ab 100644
--- a/tests/Matrix44Test.cpp
+++ b/tests/Matrix44Test.cpp
@@ -521,6 +521,226 @@ static void test_3x3_conversion(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transformed2[3]));
}
+static bool is_rectilinear (SkVector4& p1, SkVector4& p2, SkVector4& p3, SkVector4& p4) {
+ return (p1.fData[0] == p2.fData[0] && p2.fData[1] == p3.fData[1] &&
danakj 2014/09/03 19:59:22 The gfx unit test uses within-std::epsilon<float>
+ p3.fData[0] == p4.fData[0] && p4.fData[1] == p1.fData[1]) ||
+ (p1.fData[1] == p2.fData[1] && p2.fData[0] == p3.fData[0] &&
+ p3.fData[1] == p4.fData[1] && p4.fData[0] == p1.fData[0]);
+}
+
+static bool empirically_preserves_2d_axis_alignment(skiatest::Reporter* reporter,
+ const SkMatrix44& transform) {
+ SkVector4 p1(5.0f, 5.0f, 0.0f);
+ SkVector4 p2(10.0f, 5.0f, 0.0f);
+ SkVector4 p3(10.0f, 20.0f, 0.0f);
+ SkVector4 p4(5.0f, 20.0f, 0.0f);
+
+ REPORTER_ASSERT(reporter, is_rectilinear(p1, p2, p3, p4));
+
+ p1 = transform * p1;
danakj 2014/09/03 19:59:22 The gfx TransformPoint() method does something mor
Ian Vollick 2014/09/05 15:05:27 I wonder if dividing through by w to get the persp
+ p2 = transform * p2;
+ p3 = transform * p3;
+ p4 = transform * p4;
+
+SkDebugf("p1 %f %f %f %f\n", p1.fData[0], p1.fData[1], p1.fData[2], p1.fData[3]);
+SkDebugf("p2 %f %f %f %f\n", p2.fData[0], p2.fData[1], p2.fData[2], p2.fData[3]);
+SkDebugf("p3 %f %f %f %f\n", p3.fData[0], p3.fData[1], p3.fData[2], p3.fData[3]);
+SkDebugf("p4 %f %f %f %f\n", p4.fData[0], p4.fData[1], p4.fData[2], p4.fData[3]);
+
+ return is_rectilinear(p1, p2, p3, p4);
+}
+
+static void test_preserves_2d_axis_alignment(skiatest::Reporter* reporter) {
+ SkMatrix44 transform(SkMatrix44::kUninitialized_Constructor);
+ SkMatrix44 transform2(SkMatrix44::kUninitialized_Constructor);
+
+/*
+ static const struct TestCase {
+ SkMScalar a; // row 1, column 1
+ SkMScalar b; // row 1, column 2
+ SkMScalar c; // row 2, column 1
+ SkMScalar d; // row 2, column 2
+ bool expected;
+ } test_cases[] = {
+ { 3.f, 0.f,
+ 0.f, 4.f, true }, // basic case
+ { 0.f, 4.f,
+ 3.f, 0.f, true }, // rotate by 90
+ { 0.f, 0.f,
+ 0.f, 4.f, true }, // degenerate x
+ { 3.f, 0.f,
+ 0.f, 0.f, true }, // degenerate y
+ { 0.f, 0.f,
+ 3.f, 0.f, true }, // degenerate x + rotate by 90
+ { 0.f, 4.f,
+ 0.f, 0.f, true }, // degenerate y + rotate by 90
+ { 3.f, 4.f,
+ 0.f, 0.f, false },
+ { 0.f, 0.f,
+ 3.f, 4.f, false },
+ { 0.f, 3.f,
+ 0.f, 4.f, false },
+ { 3.f, 0.f,
+ 4.f, 0.f, false },
+ { 3.f, 4.f,
+ 5.f, 0.f, false },
+ { 3.f, 4.f,
+ 0.f, 5.f, false },
+ { 3.f, 0.f,
+ 4.f, 5.f, false },
+ { 0.f, 3.f,
+ 4.f, 5.f, false },
+ { 2.f, 3.f,
+ 4.f, 5.f, false },
+ };
+
+ for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
+ const TestCase& value = test_cases[i];
+ transform.setIdentity();
+ transform.set(0, 0, value.a);
+ transform.set(0, 1, value.b);
+ transform.set(1, 0, value.c);
+ transform.set(1, 1, value.d);
+
+ if (value.expected) {
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+ } else {
+ REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
+ }
+ }
+
+ // Try the same test cases again, but this time make sure that other matrix
+ // elements (except perspective) have entries, to test that they are ignored.
+ for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
+ const TestCase& value = test_cases[i];
+ transform.setIdentity();
+ transform.set(0, 0, value.a);
+ transform.set(0, 1, value.b);
+ transform.set(1, 0, value.c);
+ transform.set(1, 1, value.d);
+
+ transform.set(0, 2, 1.f);
+ transform.set(0, 3, 2.f);
+ transform.set(1, 2, 3.f);
+ transform.set(1, 3, 4.f);
+ transform.set(2, 0, 5.f);
+ transform.set(2, 1, 6.f);
+ transform.set(2, 2, 7.f);
+ transform.set(2, 3, 8.f);
+
+ if (value.expected) {
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+ } else {
+ REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
+ }
+ }
+
+ // Try the same test cases again, but this time add perspective which is
+ // always assumed to not-preserve axis alignment.
+ for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
+ const TestCase& value = test_cases[i];
+ transform.setIdentity();
+ transform.set(0, 0, value.a);
+ transform.set(0, 1, value.b);
+ transform.set(1, 0, value.c);
+ transform.set(1, 1, value.d);
+
+ transform.set(0, 2, 1.f);
+ transform.set(0, 3, 2.f);
+ transform.set(1, 2, 3.f);
+ transform.set(1, 3, 4.f);
+ transform.set(2, 0, 5.f);
+ transform.set(2, 1, 6.f);
+ transform.set(2, 2, 7.f);
+ transform.set(2, 3, 8.f);
+ transform.set(3, 0, 9.f);
+ transform.set(3, 1, 10.f);
+ transform.set(3, 2, 11.f);
+ transform.set(3, 3, 12.f);
+
+ REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
+ }
+
+ // Try a few more practical situations to check precision
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 180.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 270.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(1.0, 0.0, 0.0, 90.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
+ transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0);
+ transform.postConcat(transform2);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
+ transform2.setRotateDegreesAbout(1.0, 0.0, 0.0, 90.0);
+ transform.postConcat(transform2);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0);
+ transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
+ transform.postConcat(transform2);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 45.0);
+ REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
+
+ // 3-d case; In 2d after an orthographic projection, this case does
+ // preserve 2d axis alignment. But in 3d, it does not preserve axis
+ // alignment.
+ transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+
+ transform.setRotateDegreesAbout(1.0, 0.0, 0.0, 45.0);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+*/
+
+ // Perspective cases.
+ transform.setIdentity();
+ transform.set(3, 2, -0.1);
+ transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0);
+ transform.preConcat(transform2);
+
+transform.dump();
+
+ REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
+
+ transform.setIdentity();
+ transform.set(3, 2, -0.1);
+ transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
+ transform.preConcat(transform2);
+ REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
+ REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
+}
+
+
DEF_TEST(Matrix44, reporter) {
SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
@@ -626,4 +846,5 @@ DEF_TEST(Matrix44, reporter) {
test_scale(reporter);
test_map2(reporter);
test_3x3_conversion(reporter);
+ test_preserves_2d_axis_alignment(reporter);
}
« no previous file with comments | « src/utils/SkMatrix44.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698