34 #include <Base/Common/CompareFloatingPoint.hh>
35 #include <Base/Geometry/Quaternion.hh>
36 #include <Base/Math/Random.hh>
44 double maxerror = -1.0;
46 const double EPS = 5e-10;
56 void TestConversionQuaternionMatrix();
64 int main(
int argc,
char *argv[])
66 TestConversionQuaternionMatrix();
74 return GenerateRandomQuaternion(angle);
80 Q[3] = cos(0.5*angle);
81 Q[0] = Q[1] = Q[2] = sin(0.5*angle);
89 for (
int j = 0; j < 3; j++) Q[j] *= axis[j];
108 for (
int j = 0; j < 3; j++){
109 if (fabs(fabs(Q[j])-Qid[j]) > maxerror)
110 maxerror = fabs(fabs(Q[j])-Qid[j]);
111 if (!
Equal(fabs(Q[j]), Qid[j], EPS))
115 BIASERR(
"Inconsistent conversion quaternion -> rotation matrix -> "
116 "quaternion:\n- srcQ*dstQ.Inverse() = " <<Q/Q.
NormL2()
117 <<
"\n- srcQ = "<<Q1<<
"\n- dstQ = "<<Q2<<
"\n max. error = "
126 return GenerateRandomRMatrix(angle);
153 for (
int j = 0; j < 3; j++){
154 for (
int k = 0; k < 3; k++){
155 if (fabs(R[j][k]-I[j][k]) > maxerror)
156 maxerror = fabs(R[j][k]-I[j][k]);
157 if (!
Equal(R[j][k], I[j][k], EPS))
163 BIASERR(
"Inconsistent conversion rotation matrix -> quaternion -> "
164 "rotation matrix:\n- srcR*dstR.Inverse() = " <<R
165 <<
"\n- srcR = "<<R1<<
"\n- dstR = "<<R2<<
"\n max. error = "
171 void TestConversionQuaternionMatrix()
175 const int num = 10000;
177 cout <<
"\ntest rotation conversion for " << num <<
" random rotations"
178 <<
"\n------------------------------------------------------\n"
179 <<
"- test quaternion -> rotation matrix -> quaternion : ";
183 for (
int n = 0; n < num; n++)
185 srcQ = GenerateRandomQuaternion();
188 if (!CompareQuaternions(srcQ, dstQ)){
189 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
190 cerr <<
"[!] Error for sample id " << n
191 <<
" : source quaternion " << srcQ/srcQ.
NormL2()
192 <<
", resulting quaternion " << dstQ/dstQ.
NormL2() << endl;
196 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
198 cout <<
"- test rotation matrix -> quaternion -> rotation matrix : ";
202 for (
int n = 0; n < num; n++)
204 srcR = GenerateRandomRMatrix();
207 if (!CompareRMatrices(srcR, dstR)) {
208 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
209 cerr <<
"[!] Error for sample id " << n
210 <<
", source rotation matrix " << srcR
211 <<
", resulting rotation matrix " << dstR << endl;
215 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
220 const int num = 1000;
221 const double angleStep = 0.5*M_PI;
222 for (
int k = -4; k <= 4; k++)
224 const double angle = k*angleStep;
225 cout <<
"\ntest rotation conversion for " << num <<
" rotations "
226 <<
"with rotation angle " << angle*180.0/M_PI <<
" degree"
227 <<
"\n------------------------------------------------------\n"
228 <<
"- test quaternion -> rotation matrix -> quaternion : ";
232 for (
int n = 0; n < num; n++)
234 srcQ = GenerateRandomQuaternion(angle);
237 if (!CompareQuaternions(srcQ, dstQ)) {
238 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
239 cerr <<
"[!] Error for sample id " << n <<
" with "
240 << angle*180.0/M_PI <<
" degree, "
241 <<
"source quaternion " << srcQ/srcQ.
NormL2()
242 <<
", resulting quaternion " << dstQ/dstQ.
NormL2() << endl;
246 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
248 cout <<
"- test rotation matrix -> quaternion -> rotation matrix : ";
252 for (
int n = 0; n < num; n++)
254 srcR = GenerateRandomRMatrix(angle);
257 if (!CompareRMatrices(srcR, dstR)) {
258 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
259 cerr <<
"[!] Error for sample id " << n <<
" with "
260 << angle*180.0/M_PI <<
" degree, "
261 <<
"source rotation matrix " << srcR
262 <<
", resulting rotation matrix " << dstR << endl;
266 cout <<
"max. error = " << setprecision(30) << maxerror << endl;
272 cout <<
"\nevaluate special test case which is known for problems"
273 <<
"\n------------------------------------------------------\n";
276 Rsrc[0][0] = Rsrc[2][2] = 0.0;
277 Rsrc[1][1] = Rsrc[0][2] = Rsrc[2][0] = -1.0;
280 double diff = (Rsrc-Rdst).NormL2();
283 <<
"\n- rotation matrix " << Rsrc
284 <<
"\n-> to quaternion " << q
285 <<
"\n-> to rotation matrix " << Rdst
286 <<
"\ndifference = " << setprecision(30) << diff << endl;
287 const double eps = 5e-10;
289 if (!
Equal(diff, 0.0, eps)) {
290 BIASERR(
"[!] Inconsistent conversion rotation matrix -> quaternion -> "
291 "rotation matrix for special test case, difference is "
292 << setprecision(30) << diff);
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this->data_
BIAS::Vector3< ROTATION_MATRIX_TYPE > GetRotationAxis() const
Interface for axis component of GetRotationAxisAngle()
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
double NormL2() const
Return the L2 norm: sqrt(a^2 + b^2 + c^2 + d^2)
int GetQuaternion(Quaternion< ROTATION_MATRIX_TYPE > &quat) const
Calculates quaternion representation for this rotation matrix.
void Normalize()
Scales quaternion to unit length, i.e.
void Set(const Vector3< ROTATION_MATRIX_TYPE > &w, const ROTATION_MATRIX_TYPE phi)
Set from rotation axis w and angle phi (in rad)
Quaternion< QUAT_TYPE > Inverse() const
returns the Inverse rotation Quaternion
void Mult(const Quaternion< QUAT_TYPE > &quat)
quaternion multiplication: this= this * quat
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Implements a 3D rotation matrix.
ROTATION_MATRIX_TYPE GetRotationAngle() const
Interface for angle component of GetRotationAxisAngle()
Vector3< T > & Normalize()
normalize this vector to length 1
class for producing random numbers from different distributions
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)