~lib2geom-hackers/lib2geom/trunk

« back to all changes in this revision

Viewing changes to matrix-test.cpp

  • Committer: njh
  • Date: 2006-05-22 11:50:24 UTC
  • Revision ID: svn-v4:4601daaa-0314-0410-9a8b-c964a3c23b6b:trunk/lib2geom:1
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <utest/utest.h>
 
2
#include <libnr/matrix.h>
 
3
#include <libnr/matrix-fns.h>
 
4
#include <libnr/matrix-ops.h>
 
5
#include <libnr/matrix-rotate-ops.h>
 
6
#include <libnr/matrix-scale-ops.h>
 
7
#include <libnr/point-matrix-ops.h>
 
8
#include <libnr/rotate.h>
 
9
#include <libnr/rotate-ops.h>
 
10
#include <libnr/scale-ops.h>
 
11
#include <libnr/scale-translate-ops.h>
 
12
#include <libnr/translate.h>
 
13
#include <libnr/translate-ops.h>
 
14
#include <libnr/translate-scale-ops.h>
 
15
using Geom::Matrix;
 
16
using Geom::X;
 
17
using Geom::Y;
 
18
 
 
19
inline bool point_equalp(Geom::Point const &a, Geom::Point const &b)
 
20
{
 
21
    return ( Geom_DF_TEST_CLOSE(a[X], b[X], 1e-5) &&
 
22
             Geom_DF_TEST_CLOSE(a[Y], b[Y], 1e-5)   );
 
23
}
 
24
 
 
25
int main(int argc, char *argv[])
 
26
{
 
27
    int rc = EXIT_SUCCESS;
 
28
 
 
29
    Matrix const m_id(Geom::identity());
 
30
    Geom::rotate const r_id(Geom::Point(1, 0));
 
31
    Geom::translate const t_id(0, 0);
 
32
 
 
33
    utest_start("Matrix");
 
34
 
 
35
    Matrix const c16(1.0, 2.0,
 
36
                     3.0, 4.0,
 
37
                     5.0, 6.0);
 
38
    UTEST_TEST("basic constructors, operator=") {
 
39
        Matrix const c16_copy(c16);
 
40
        Matrix c16_eq(m_id);
 
41
        c16_eq = c16;
 
42
        for(unsigned i = 0; i < 6; ++i) {
 
43
            UTEST_ASSERT( c16[i] == 1.0 + i );
 
44
            UTEST_ASSERT( c16[i] == c16_copy[i] );
 
45
            UTEST_ASSERT( c16[i] == c16_eq[i] );
 
46
            UTEST_ASSERT( m_id[i] == double( i == 0 || i == 3 ) );
 
47
        }
 
48
    }
 
49
 
 
50
    UTEST_TEST("scale constructor") {
 
51
        Geom::scale const s(2.0, 3.0);
 
52
        Geom::Matrix const ms(s);
 
53
        Geom::Point const p(5.0, 7.0);
 
54
        UTEST_ASSERT( p * s == Geom::Point(10.0, 21.0) );
 
55
        UTEST_ASSERT( p * ms == Geom::Point(10.0, 21.0) );
 
56
    }
 
57
 
 
58
    Geom::rotate const r86(Geom::Point(.8, .6));
 
59
    Geom::Matrix const mr86(r86);
 
60
    UTEST_TEST("rotate constructor") {
 
61
        Geom::Point const p0(1.0, 0.0);
 
62
        Geom::Point const p90(0.0, 1.0);
 
63
        UTEST_ASSERT( p0 * r86 == Geom::Point(.8, .6) );
 
64
        UTEST_ASSERT( p0 * mr86 == Geom::Point(.8, .6) );
 
65
        UTEST_ASSERT( p90 * r86 == Geom::Point(-.6, .8) );
 
66
        UTEST_ASSERT( p90 * mr86 == Geom::Point(-.6, .8) );
 
67
        UTEST_ASSERT(matrix_equalp(Matrix( r86 * r86 ),
 
68
                                   mr86 * mr86,
 
69
                                   1e-14));
 
70
    }
 
71
 
 
72
    Geom::translate const t23(2.0, 3.0);
 
73
    UTEST_TEST("translate constructor") {
 
74
        Geom::Matrix const mt23(t23);
 
75
        Geom::Point const b(-2.0, 3.0);
 
76
        UTEST_ASSERT( b * t23 == b * mt23 );
 
77
    }
 
78
 
 
79
    Geom::scale const s_id(1.0, 1.0);
 
80
    UTEST_TEST("test_identity") {
 
81
        UTEST_ASSERT(m_id.test_identity());
 
82
        UTEST_ASSERT(Matrix(t_id).test_identity());
 
83
        UTEST_ASSERT(!(Matrix(Geom::translate(-2, 3)).test_identity()));
 
84
        UTEST_ASSERT(Matrix(r_id).test_identity());
 
85
        Geom::rotate const rot180(Geom::Point(-1, 0));
 
86
        UTEST_ASSERT(!(Matrix(rot180).test_identity()));
 
87
        UTEST_ASSERT(Matrix(s_id).test_identity());
 
88
        UTEST_ASSERT(!(Matrix(Geom::scale(1.0, 0.0)).test_identity()));
 
89
        UTEST_ASSERT(!(Matrix(Geom::scale(0.0, 1.0)).test_identity()));
 
90
        UTEST_ASSERT(!(Matrix(Geom::scale(1.0, -1.0)).test_identity()));
 
91
        UTEST_ASSERT(!(Matrix(Geom::scale(-1.0, -1.0)).test_identity()));
 
92
    }
 
93
 
 
94
    UTEST_TEST("inverse") {
 
95
        UTEST_ASSERT( m_id.inverse() == m_id );
 
96
        UTEST_ASSERT( Matrix(t23).inverse() == Matrix(Geom::translate(-2.0, -3.0)) );
 
97
        Geom::scale const s2(-4.0, 2.0);
 
98
        Geom::scale const sp5(-.25, .5);
 
99
        UTEST_ASSERT( Matrix(s2).inverse() == Matrix(sp5) );
 
100
    }
 
101
 
 
102
    UTEST_TEST("nr_matrix_invert") {
 
103
        NRMatrix const nr_m_id(m_id);
 
104
        Matrix const m_s2(Geom::scale(-4.0, 2.0));
 
105
        NRMatrix const nr_s2(m_s2);
 
106
        Matrix const m_sp5(Geom::scale(-.25, .5));
 
107
        NRMatrix const nr_sp5(m_sp5);
 
108
        Matrix const m_t23(t23);
 
109
        NRMatrix const nr_t23(m_t23);
 
110
        NRMatrix inv;
 
111
        nr_matrix_invert(&inv, &nr_m_id);
 
112
        UTEST_ASSERT( Matrix(inv) == m_id );
 
113
        nr_matrix_invert(&inv, &nr_t23);
 
114
        UTEST_ASSERT( Matrix(inv) == Matrix(Geom::translate(-2.0, -3.0)) );
 
115
        nr_matrix_invert(&inv, &nr_s2);
 
116
        UTEST_ASSERT( Matrix(inv) == Matrix(nr_sp5) );
 
117
        nr_matrix_invert(&inv, &nr_sp5);
 
118
        UTEST_ASSERT( Matrix(inv) == Matrix(nr_s2) );
 
119
 
 
120
        /* Test that nr_matrix_invert handles src == dest. */
 
121
        inv = nr_s2;
 
122
        nr_matrix_invert(&inv, &inv);
 
123
        UTEST_ASSERT( Matrix(inv) == Matrix(nr_sp5) );
 
124
        inv = nr_t23;
 
125
        nr_matrix_invert(&inv, &inv);
 
126
        UTEST_ASSERT( Matrix(inv) == Matrix(Geom::translate(-2.0, -3.0)) );
 
127
    }
 
128
 
 
129
    UTEST_TEST("elliptic quadratic form") {
 
130
        Geom::Matrix const aff(1.0, 1.0,
 
131
                             0.0, 1.0,
 
132
                             5.0, 6.0);
 
133
        Geom::Matrix const invaff = aff.inverse();
 
134
        UTEST_ASSERT( invaff[1] == -1.0 );
 
135
                
 
136
        Geom::Matrix const ef(elliptic_quadratic_form(invaff));
 
137
        Geom::Matrix const exp_ef(2, -1,
 
138
                                -1, 1,
 
139
                                0, 0);
 
140
        UTEST_ASSERT( ef == exp_ef );
 
141
    }
 
142
 
 
143
    UTEST_TEST("Matrix * rotate") {
 
144
        Geom::Matrix const ma(2.0, -1.0,
 
145
                            4.0, 4.0,
 
146
                            -0.5, 2.0);
 
147
        Geom::Matrix const a_r86( ma * r86 );
 
148
        Geom::Matrix const ma1( a_r86 * r86.inverse() );
 
149
        UTEST_ASSERT(matrix_equalp(ma1, ma, 1e-12));
 
150
        Geom::Matrix const exp_a_r86( 2*.8 + -1*-.6,  2*.6 + -1*.8,
 
151
                                    4*.8 + 4*-.6,   4*.6 + 4*.8,
 
152
                                    -.5*.8 + 2*-.6, -.5*.6 + 2*.8 );
 
153
        UTEST_ASSERT(matrix_equalp(a_r86, exp_a_r86, 1e-12));
 
154
    }
 
155
 
 
156
    UTEST_TEST("translate*scale, scale*translate") {
 
157
        Geom::translate const t2n4(2, -4);
 
158
        Geom::scale const sn2_8(-2, 8);
 
159
        Geom::Matrix const exp_ts(-2, 0,
 
160
                                0,  8,
 
161
                                -4, -32);
 
162
        Geom::Matrix const exp_st(-2, 0,
 
163
                                0,  8,
 
164
                                2, -4);
 
165
        UTEST_ASSERT( exp_ts == t2n4 * sn2_8 );
 
166
        UTEST_ASSERT( exp_st == sn2_8 * t2n4 );
 
167
    }
 
168
 
 
169
    UTEST_TEST("Matrix * scale") {
 
170
        Geom::Matrix const ma(2.0, -1.0,
 
171
                            4.0, 4.0,
 
172
                            -0.5, 2.0);
 
173
        Geom::scale const sn2_8(-2, 8);
 
174
        Geom::Matrix const exp_as(-4, -8,
 
175
                                -8, 32,
 
176
                                1,  16);
 
177
        UTEST_ASSERT( ma * sn2_8 == exp_as );
 
178
    }
 
179
 
 
180
    if (!utest_end()) {
 
181
        rc = EXIT_FAILURE;
 
182
    }
 
183
 
 
184
    return rc;
 
185
}
 
186
 
 
187
 
 
188
/*
 
189
  Local Variables:
 
190
  mode:c++
 
191
  c-file-style:"stroustrup"
 
192
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
193
  indent-tabs-mode:nil
 
194
  fill-column:99
 
195
  End:
 
196
*/
 
197
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :