/*
* rot_checker.cpp
*
* Authors: [email]dungeoneer@freenet.de[/email] (dun)
* Copyright: GPL
*
* Compares two fixed sets of rotations arond the cordinate axes
* using quaternions:
*
* v' = qx * (qy * (qz * v * _qz) * _qy) * _qx
* = (qx * qy * qz) * v * (_qz * _qy * _qx)
*
* Rotation precedence is Z->Y->X
*
* Compilation:
* g++ rot_checker.cpp -o rot_checker
*
* PLEASE NOTE:
* Neither accuracy nor fitness for any particular purpose
* is expresed nor implied.
*
* Version 1.0: May 29th 2010 (dun)
*
* TODO: Make the datasets a runtime parameter
*/
#include <iostream> // for std::cout, std::endl
#include <boost/math/quaternion.hpp>
#include <cmath> // for sin(x), cos(x)
typedef float RealType;
const RealType DEG2RAD = M_PI/180.0;
///////////////////////////////////////////////////////////
// Data Sets
const RealType Collada_set[3] = {-90.0001, -89.029, -180.0};
const RealType ThreeDS_set[3] = { 90.0, -90.971, 0.0};
///////////////////////////////////////////////////////////
typedef boost::math::quaternion<RealType> QuatType;
typedef float AngleType;
enum AxisType {
X = 0,
Y = 1,
Z = 2
};
QuatType make_quat(const AxisType& axis, const AngleType& angle) {
QuatType q(cos(angle * DEG2RAD / 2.0), 0.0, 0.0, 0.0);
RealType* p = reinterpret_cast<RealType*>(&q);
p[(int)axis + 1] = sin(angle * DEG2RAD / 2.0);
return q;
}
int main() {
QuatType qCollada(1.0, 0.0, 0.0, 0.0), qThreeDS(1.0, 0.0, 0.0, 0.0);
/*
* Testing the conjugates is redundant due to quaternionic algebra,
* but added for the sake of instructiveness
*/
QuatType _qCollada(1.0, 0.0, 0.0, 0.0), _qThreeDS(1.0, 0.0, 0.0, 0.0);
for (int i = 0; i <= 2; ++i) {
qThreeDS *= make_quat((AxisType)i, ThreeDS_set[i]);
qCollada *= make_quat((AxisType)i, Collada_set[i]);
}
std::cout << "Combined lhs Quaternion for COLLADA rotations: "
<< qCollada << std::endl;
std::cout << "Combined lhs Quaternion for 3DS rotations: "
<< qThreeDS << std::endl;
for (int i = 2; i >= 0; --i) {
_qThreeDS *= boost::math::conj(make_quat((AxisType)i, ThreeDS_set[i]));
_qCollada *= boost::math::conj(make_quat((AxisType)i, Collada_set[i]));
}
std::cout << "Combined rhs Quaternion for COLLADA rotations: "
<< _qCollada << std::endl;
std::cout << "Combined rhs Quaternion for 3DS rotations: "
<< _qThreeDS << std::endl;
return 0;
}