1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
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
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.
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.
33
///////////////////////////////////////////////////////////////////////////
36
#include <testExtractEuler.h>
37
#include <ImathMatrixAlgo.h>
38
#include <ImathEuler.h>
39
#include <ImathRandom.h>
46
using namespace Imath;
50
float rad (float deg) {return deg * (M_PI / 180);}
51
float deg (float rad) {return rad * (180 / M_PI);}
55
matrixEulerMatrix_1 (const M44f &M, Eulerf::Order order)
59
if (order == Eulerf::XYZ)
60
extractEulerXYZ (M, f);
62
extractEulerZYX (M, f);
64
return Eulerf(f, order).toMatrix44();
69
matrixEulerMatrix_2 (const M44f &M, Eulerf::Order order)
73
return f.toMatrix44();
78
testMatrix (const M44f M,
79
M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
83
// Extract Euler angles from M, and convert the
84
// Euler angles back to a matrix, N.
87
M44f N = matrixEulerMatrix (M, order);
90
// Verify that the entries in M and N do not
96
for (int j = 0; j < 3; ++j)
98
for (int k = 0; k < 3; ++k)
100
if (abs (D[j][k]) > 0.000002)
102
cout << "unexpectedly large matrix to "
103
"euler angles conversion error: " <<
106
cout << j << " " << k << endl;
108
cout << "M\n" << M << endl;
109
cout << "N\n" << N << endl;
110
cout << "D\n" << D << endl;
120
testRandomAngles (M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
125
for (int i = 0; i < 100000; ++i)
128
// Create a rotation matrix, M
131
Eulerf e (rad (r.nextf (-180, 180)),
132
rad (r.nextf (-180, 180)),
133
rad (r.nextf (-180, 180)),
136
M44f M (e.toMatrix44());
139
// Add a small random error to the elements of M
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);
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.
152
testMatrix (M, matrixEulerMatrix, order);
158
testAngles (V3f angles,
159
M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
162
Eulerf e (rad (angles.x),
167
M44f M (e.toMatrix44());
170
// With rounding errors from e.toMatrix.
173
testMatrix (M, matrixEulerMatrix, order);
176
// Without rounding errors (assuming that
177
// all angles are multiples of 90 degrees).
180
for (int i = 0; i < 3; ++i)
181
for (int j = 0; j < 3; ++j)
184
else if (M[i][j] > 0.5)
189
testMatrix (M, matrixEulerMatrix, order);
194
test (M44f (*matrixEulerMatrix)(const M44f &, Eulerf::Order),
197
cout << "order = " << setbase (16) << int (order) << setbase (10) << endl;
199
// cout << "random angles" << endl;
201
testRandomAngles (matrixEulerMatrix, order);
203
// cout << "special angles" << endl;
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);
213
testRandomAngles33 ()
217
float eps = 8.0 * limits<float>::epsilon();
219
for (int i = 0; i < 100000; ++i)
221
float angle = rad (r.nextf (-180, 180));
224
M.setRotation (angle);
227
extractEuler (M, angleEx);
229
assert (Imath::equal (angle, angleEx, eps));
240
#if defined PLATFORM_WINDOWS && _MSC_VER >= 1300
241
cout << "testExtractEuler disabled on this compiler due to bugs" << endl;
243
cout << "Testing extraction of rotation angle from 3x3 matrices" << endl;
244
testRandomAngles33 ();
246
cout << "Testing extraction of Euler angles from matrices" << endl;
248
cout << "extractEulerXYZ()" << endl;
249
test (matrixEulerMatrix_1, Eulerf::XYZ);
251
cout << "extractEulerZYX()" << endl;
252
test (matrixEulerMatrix_1, Eulerf::ZYX);
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);
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);
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);
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);
283
cout << "ok\n" << endl;