~ubuntu-branches/ubuntu/saucy/openexr/saucy

« back to all changes in this revision

Viewing changes to ImathTest/testExtractEuler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adeodato Simó
  • Date: 2008-03-24 23:00:21 UTC
  • mfrom: (3.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080324230021-gnofz9mnvcj1xlv3
Tags: 1.6.1-3
Disable (hopefully temporarily) the test suite on arm and ia64.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
///////////////////////////////////////////////////////////////////////////
2
 
//
3
 
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4
 
// Digital Ltd. LLC
5
 
// 
6
 
// All rights reserved.
7
 
// 
8
 
// Redistribution and use in source and binary forms, with or without
9
 
// modification, are permitted provided that the following conditions are
10
 
// met:
11
 
// *       Redistributions of source code must retain the above copyright
12
 
// notice, this list of conditions and the following disclaimer.
13
 
// *       Redistributions in binary form must reproduce the above
14
 
// copyright notice, this list of conditions and the following disclaimer
15
 
// in the documentation and/or other materials provided with the
16
 
// distribution.
17
 
// *       Neither the name of Industrial Light & Magic nor the names of
18
 
// its contributors may be used to endorse or promote products derived
19
 
// from this software without specific prior written permission. 
20
 
// 
21
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 
//
33
 
///////////////////////////////////////////////////////////////////////////
34
 
 
35
 
 
36
 
#include <testExtractEuler.h>
37
 
#include <ImathMatrixAlgo.h>
38
 
#include <ImathEuler.h>
39
 
#include <ImathRandom.h>
40
 
#include <ImathFun.h>
41
 
#include <iostream>
42
 
#include <assert.h>
43
 
 
44
 
 
45
 
using namespace std;
46
 
using namespace Imath;
47
 
 
48
 
namespace {
49
 
 
50
 
float rad (float deg) {return deg * (M_PI / 180);}
51
 
float deg (float rad) {return rad * (180 / M_PI);}
52
 
 
53
 
 
54
 
M44f
55
 
matrixEulerMatrix_1 (const M44f &M, Eulerf::Order order)
56
 
{
57
 
    V3f f;
58
 
 
59
 
    if (order == Eulerf::XYZ)
60
 
        extractEulerXYZ (M, f);
61
 
    else
62
 
        extractEulerZYX (M, f);
63
 
 
64
 
    return Eulerf(f, order).toMatrix44();
65
 
}
66
 
 
67
 
 
68
 
M44f
69
 
matrixEulerMatrix_2 (const M44f &M, Eulerf::Order order)
70
 
{
71
 
    Eulerf f (order);
72
 
    f.extract (M);
73
 
    return f.toMatrix44();
74
 
}
75
 
 
76
 
 
77
 
void
78
 
testMatrix (const M44f M,
79
 
            M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
80
 
            Eulerf::Order order)
81
 
{
82
 
    //
83
 
    // Extract Euler angles from M, and convert the
84
 
    // Euler angles back to a matrix, N.
85
 
    //
86
 
 
87
 
    M44f N = matrixEulerMatrix (M, order);
88
 
 
89
 
    //
90
 
    // Verify that the entries in M and N do not
91
 
    // differ too much.
92
 
    //
93
 
 
94
 
    M44f D (M - N);
95
 
 
96
 
    for (int j = 0; j < 3; ++j)
97
 
    {
98
 
        for (int k = 0; k < 3; ++k)
99
 
        {
100
 
            if (abs (D[j][k]) > 0.000002)
101
 
            {
102
 
                cout << "unexpectedly large matrix to "
103
 
                        "euler angles conversion error: " <<
104
 
                        D[j][k] << endl;
105
 
 
106
 
                cout << j << " " << k << endl;
107
 
 
108
 
                cout << "M\n" << M << endl;
109
 
                cout << "N\n" << N << endl;
110
 
                cout << "D\n" << D << endl;
111
 
 
112
 
                assert (false);
113
 
            }
114
 
        }
115
 
    }
116
 
}
117
 
 
118
 
 
119
 
void
120
 
testRandomAngles (M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
121
 
                  Eulerf::Order order)
122
 
{
123
 
    Rand48 r(0);
124
 
 
125
 
    for (int i = 0; i < 100000; ++i)
126
 
    {
127
 
        //
128
 
        // Create a rotation matrix, M
129
 
        //
130
 
 
131
 
        Eulerf e (rad (r.nextf (-180, 180)),
132
 
                  rad (r.nextf (-180, 180)),
133
 
                  rad (r.nextf (-180, 180)),
134
 
                  Eulerf::XYZ);
135
 
 
136
 
        M44f M (e.toMatrix44());
137
 
 
138
 
        //
139
 
        // Add a small random error to the elements of M
140
 
        //
141
 
 
142
 
        for (int j = 0; j < 3; ++j)
143
 
            for (int k = 0; k < 3; ++k)
144
 
                M[j][k] += r.nextf (-1e-7, 1e-7);
145
 
 
146
 
        //
147
 
        // Extract Euler angles from M, convert the Euler angles
148
 
        // back to a matrix, N, and verify that the entries in M
149
 
        // and N do not differ too much.
150
 
        //
151
 
 
152
 
        testMatrix (M, matrixEulerMatrix, order);
153
 
    }
154
 
}
155
 
 
156
 
 
157
 
void
158
 
testAngles (V3f angles,
159
 
            M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
160
 
            Eulerf::Order order)
161
 
{
162
 
    Eulerf e (rad (angles.x),
163
 
              rad (angles.y),
164
 
              rad (angles.z),
165
 
              order);
166
 
 
167
 
    M44f M (e.toMatrix44());
168
 
 
169
 
    //
170
 
    // With rounding errors from e.toMatrix.
171
 
    //
172
 
 
173
 
    testMatrix (M, matrixEulerMatrix, order);
174
 
 
175
 
    //
176
 
    // Without rounding errors (assuming that
177
 
    // all angles are multiples of 90 degrees).
178
 
    //
179
 
 
180
 
    for (int i = 0; i < 3; ++i)
181
 
        for (int j = 0; j < 3; ++j)
182
 
            if (M[i][j] < -0.5)
183
 
                M[i][j] = -1;
184
 
            else if (M[i][j] > 0.5)
185
 
                M[i][j] = 1;
186
 
            else
187
 
                M[i][j] = 0;
188
 
 
189
 
    testMatrix (M, matrixEulerMatrix, order);
190
 
}
191
 
 
192
 
 
193
 
void
194
 
test (M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
195
 
      Eulerf::Order order)
196
 
{
197
 
    cout << "order = " << setbase (16) << int (order) << setbase (10) << endl;
198
 
 
199
 
    // cout << "random angles" << endl;
200
 
 
201
 
    testRandomAngles (matrixEulerMatrix, order);
202
 
 
203
 
    // cout << "special angles" << endl;
204
 
 
205
 
    for (int i = 0; i < 360; i += 90)
206
 
        for (int j = 0; j < 360; j += 90)
207
 
            for (int k = 0; k < 360; k += 90)
208
 
                testAngles (V3f (i, j, k), matrixEulerMatrix, order);
209
 
}
210
 
 
211
 
 
212
 
void
213
 
testRandomAngles33 ()
214
 
{
215
 
    Rand48 r(0);
216
 
 
217
 
    float eps = 8.0 * limits<float>::epsilon();
218
 
 
219
 
    for (int i = 0; i < 100000; ++i)
220
 
    {
221
 
        float angle = rad (r.nextf (-180, 180));
222
 
 
223
 
        M33f M;
224
 
        M.setRotation (angle);
225
 
 
226
 
        float angleEx;
227
 
        extractEuler (M, angleEx);
228
 
 
229
 
        assert (Imath::equal (angle, angleEx, eps));
230
 
    }
231
 
}
232
 
 
233
 
 
234
 
} // namespace
235
 
 
236
 
 
237
 
void
238
 
testExtractEuler ()
239
 
{
240
 
#if defined PLATFORM_WINDOWS && _MSC_VER >= 1300
241
 
    cout << "testExtractEuler disabled on this compiler due to bugs" << endl;
242
 
#else
243
 
    cout << "Testing extraction of rotation angle from 3x3 matrices" << endl;
244
 
    testRandomAngles33 ();
245
 
    
246
 
    cout << "Testing extraction of Euler angles from matrices" << endl;
247
 
 
248
 
    cout << "extractEulerXYZ()" << endl;
249
 
    test (matrixEulerMatrix_1, Eulerf::XYZ);
250
 
 
251
 
    cout << "extractEulerZYX()" << endl;
252
 
    test (matrixEulerMatrix_1, Eulerf::ZYX);
253
 
 
254
 
    cout << "Eulerf::extract()" << endl;
255
 
    test (matrixEulerMatrix_2, Eulerf::XYZ);
256
 
    test (matrixEulerMatrix_2, Eulerf::XZY);
257
 
    test (matrixEulerMatrix_2, Eulerf::YZX);
258
 
    test (matrixEulerMatrix_2, Eulerf::YXZ);
259
 
    test (matrixEulerMatrix_2, Eulerf::ZXY);
260
 
    test (matrixEulerMatrix_2, Eulerf::ZYX);
261
 
    
262
 
    test (matrixEulerMatrix_2, Eulerf::XZX);
263
 
    test (matrixEulerMatrix_2, Eulerf::XYX);
264
 
    test (matrixEulerMatrix_2, Eulerf::YXY);
265
 
    test (matrixEulerMatrix_2, Eulerf::YZY);
266
 
    test (matrixEulerMatrix_2, Eulerf::ZYZ);
267
 
    test (matrixEulerMatrix_2, Eulerf::ZXZ);
268
 
 
269
 
    test (matrixEulerMatrix_2, Eulerf::XYZr);
270
 
    test (matrixEulerMatrix_2, Eulerf::XZYr);
271
 
    test (matrixEulerMatrix_2, Eulerf::YZXr);
272
 
    test (matrixEulerMatrix_2, Eulerf::YXZr);
273
 
    test (matrixEulerMatrix_2, Eulerf::ZXYr);
274
 
    test (matrixEulerMatrix_2, Eulerf::ZYXr);
275
 
    
276
 
    test (matrixEulerMatrix_2, Eulerf::XZXr);
277
 
    test (matrixEulerMatrix_2, Eulerf::XYXr);
278
 
    test (matrixEulerMatrix_2, Eulerf::YXYr);
279
 
    test (matrixEulerMatrix_2, Eulerf::YZYr);
280
 
    test (matrixEulerMatrix_2, Eulerf::ZYZr);
281
 
    test (matrixEulerMatrix_2, Eulerf::ZXZr);
282
 
 
283
 
    cout << "ok\n" << endl;
284
 
#endif
285
 
}