Matrix44Test.cpp revision 1cab2921ab279367f8206cdadc9259d12e603548
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "Test.h"
9#include "SkMatrix44.h"
10
11static bool nearly_equal_scalar(SkMScalar a, SkMScalar b) {
12    // Note that we get more compounded error for multiple operations when
13    // SK_SCALAR_IS_FIXED.
14#ifdef SK_SCALAR_IS_FLOAT
15    const SkScalar tolerance = SK_Scalar1 / 200000;
16#else
17    const SkScalar tolerance = SK_Scalar1 / 1024;
18#endif
19
20    return SkScalarAbs(a - b) <= tolerance;
21}
22
23template <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
24                                    T m0,  T m1,  T m2,  T m3,
25                                    T m4,  T m5,  T m6,  T m7,
26                                    T m8,  T m9,  T m10, T m11,
27                                    T m12, T m13, T m14, T m15) {
28    REPORTER_ASSERT(reporter, data[0] == m0);
29    REPORTER_ASSERT(reporter, data[1] == m1);
30    REPORTER_ASSERT(reporter, data[2] == m2);
31    REPORTER_ASSERT(reporter, data[3] == m3);
32
33    REPORTER_ASSERT(reporter, data[4] == m4);
34    REPORTER_ASSERT(reporter, data[5] == m5);
35    REPORTER_ASSERT(reporter, data[6] == m6);
36    REPORTER_ASSERT(reporter, data[7] == m7);
37
38    REPORTER_ASSERT(reporter, data[8] == m8);
39    REPORTER_ASSERT(reporter, data[9] == m9);
40    REPORTER_ASSERT(reporter, data[10] == m10);
41    REPORTER_ASSERT(reporter, data[11] == m11);
42
43    REPORTER_ASSERT(reporter, data[12] == m12);
44    REPORTER_ASSERT(reporter, data[13] == m13);
45    REPORTER_ASSERT(reporter, data[14] == m14);
46    REPORTER_ASSERT(reporter, data[15] == m15);
47}
48
49static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
50    for (int i = 0; i < 4; ++i) {
51        for (int j = 0; j < 4; ++j) {
52            if (!nearly_equal_scalar(a.get(i, j), b.get(i, j))) {
53                printf("not equal %g %g\n", a.get(i, j), b.get(i, j));
54                return false;
55            }
56        }
57    }
58    return true;
59}
60
61static bool is_identity(const SkMatrix44& m) {
62    SkMatrix44 identity;
63    identity.reset();
64    return nearly_equal(m, identity);
65}
66
67static void test_common_angles(skiatest::Reporter* reporter) {
68    SkMatrix44 rot;
69    // Test precision of rotation in common cases
70    int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
71    for (int i = 0; i < 9; ++i) {
72        rot.setRotateDegreesAbout(0, 0, -1, common_angles[i]);
73
74        SkMatrix rot3x3 = rot;
75        REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
76    }
77}
78
79void TestMatrix44(skiatest::Reporter* reporter) {
80#ifdef SK_SCALAR_IS_FLOAT
81    SkMatrix44 mat, inverse, iden1, iden2, rot;
82
83    mat.reset();
84    mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
85    mat.invert(&inverse);
86    iden1.setConcat(mat, inverse);
87    REPORTER_ASSERT(reporter, is_identity(iden1));
88
89    mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
90    mat.invert(&inverse);
91    iden1.setConcat(mat, inverse);
92    REPORTER_ASSERT(reporter, is_identity(iden1));
93
94    mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
95    mat.invert(&inverse);
96    iden1.setConcat(mat, inverse);
97    REPORTER_ASSERT(reporter, is_identity(iden1));
98
99    mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
100    rot.setRotateDegreesAbout(
101        SkIntToScalar(0),
102        SkIntToScalar(0),
103        SkIntToScalar(-1),
104        SkIntToScalar(90));
105    mat.postConcat(rot);
106    REPORTER_ASSERT(reporter, mat.invert(NULL));
107    mat.invert(&inverse);
108    iden1.setConcat(mat, inverse);
109    REPORTER_ASSERT(reporter, is_identity(iden1));
110    iden2.setConcat(inverse, mat);
111    REPORTER_ASSERT(reporter, is_identity(iden2));
112
113    // test rol/col Major getters
114    {
115        mat.setTranslate(2, 3, 4);
116        float dataf[16];
117        double datad[16];
118
119        mat.asColMajorf(dataf);
120        assert16<float>(reporter, dataf,
121                 1, 0, 0, 0,
122                 0, 1, 0, 0,
123                 0, 0, 1, 0,
124                 2, 3, 4, 1);
125        mat.asColMajord(datad);
126        assert16<double>(reporter, datad, 1, 0, 0, 0,
127                        0, 1, 0, 0,
128                        0, 0, 1, 0,
129                        2, 3, 4, 1);
130        mat.asRowMajorf(dataf);
131        assert16<float>(reporter, dataf, 1, 0, 0, 2,
132                        0, 1, 0, 3,
133                        0, 0, 1, 4,
134                        0, 0, 0, 1);
135        mat.asRowMajord(datad);
136        assert16<double>(reporter, datad, 1, 0, 0, 2,
137                        0, 1, 0, 3,
138                        0, 0, 1, 4,
139                        0, 0, 0, 1);
140    }
141
142#if 0   // working on making this pass
143    test_common_angles(reporter);
144#endif
145#endif
146}
147
148#include "TestClassDef.h"
149DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)
150