You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3dpcp/.svn/pristine/67/67dde7bb46c00cac257bcc8da58...

122 lines
3.9 KiB
Plaintext

/**
* @file
* @brief Inline helper functions for show program
* @author Kai Lingemann. Institute of Computer Science, University of Osnabrueck, Germany.
* @author Andreas Nuechter. Institute of Computer Science, University of Osnabrueck, Germany.
*/
#include "slam6d/globals.icc"
/**
* converts a quaterion to a 4x4 matrix
* in OpenGL style
*/
template <class T>
inline void QuaternionToMatrix4(const double *quat, T *mat)
{
double xy = quat[0] * quat[1] * -1.0;
double xz = quat[0] * quat[2];
double yz = quat[1] * quat[2] * -1.0;
double wx = quat[3] * quat[0];
double wy = quat[3] * quat[1] * -1.0;
double wz = quat[3] * quat[2];
double x2 = sqr(quat[0]);
double y2 = sqr(quat[1]);
double z2 = sqr(quat[2]);
mat[0] = 1.0 - 2.0 * (y2 + z2);
mat[4] = 2.0 * (xy - wz);
mat[8] = 2.0 * (xz + wy);
mat[1] = 2.0 * (xy + wz);
mat[5] = 1.0 - 2.0 * (x2 + z2);
mat[9] = 2.0 * (yz - wx);
mat[2] = 2.0 * (xz - wy);
mat[6] = 2.0 * (yz + wx);
mat[10] = 1.0 - 2.0 * (x2 + y2);
mat[11] = mat[7] = mat[3] = mat[12] = mat[13] = mat[14] = 0.0;
mat[15] = 1.0;
}
/**
* converts a 4x4 matrix to a quaternion
*/
template <class T>
inline void Matrix4ToQuaternion(const T *mat, double *quat)
{
double S;
double Trace = 1 + mat[0] + mat[5] + mat[10];
if ( Trace > COMPARE_EPSILON ) {
S = sqrt(Trace) * 2;
quat[0] = -1.0 * ( mat[9] - mat[6] ) / S; // q_x
quat[1] = -1.0 * ( mat[2] - mat[8] ) / S; // q_y
quat[2] = -1.0 * ( mat[4] - mat[1] ) / S; // q_z
quat[3] = 0.25 * S; // q_0
} else if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
quat[0] = -1.0 * 0.25 * S;
quat[1] = -1.0 * (mat[4] + mat[1] ) / S;
quat[2] = -1.0 * (mat[2] + mat[8] ) / S;
quat[3] = (mat[9] - mat[6] ) / S;
} else if ( mat[5] > mat[10] ) { // Column 1:
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
quat[0] = -1.0 * (mat[4] + mat[1] ) / S;
quat[1] = -1.0 * 0.25 * S;
quat[2] = -1.0 * (mat[9] + mat[6] ) / S;
quat[3] = (mat[2] - mat[8] ) / S;
} else { // Column 2:
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
quat[0] = -1.0 * (mat[2] + mat[8] ) / S;
quat[1] = -1.0 * (mat[9] + mat[6] ) / S;
quat[2] = -1.0 * 0.25 * S;
quat[3] = (mat[4] - mat[1] ) / S;
}
}
/**
* normalizes a quaternion to gain a unit quaternion
*/
template <class T>
inline void QuatNormalize(T *q)
{
T norm = sqrt(sqr(q[0]) + sqr(q[1]) + sqr(q[2]) + sqr(q[3]));
q[3] = q[3] / norm;
q[2] = q[2] / norm;
q[1] = q[1] / norm;
q[0] = q[0] / norm;
}
/**
* multiplication of quaternions
*/
template <class T>
inline void QuatMult(const T *q, const T *q_new, T *qtemp)
{
qtemp[3] = q_new[3] * q[3] - q_new[0] * q[0] - q_new[1] * q[1] - q_new[2] * q[2];
qtemp[0] = q_new[3] * q[0] + q_new[0] * q[3] + q_new[1] * q[2] - q_new[2] * q[1];
qtemp[1] = q_new[3] * q[1] + q_new[1] * q[3] + q_new[2] * q[0] - q_new[0] * q[2];
qtemp[2] = q_new[3] * q[2] + q_new[2] * q[3] + q_new[0] * q[1] - q_new[1] * q[0];
}
/**
* converts a quaternion to an axis angle
*/
inline void QuaternionToAxisAngle(const double *quat, double *axis, double &angle)
{
double quaternion_norm = sqrt( sqr(quat[0]) + sqr(quat[1]) + sqr(quat[2]) + sqr(quat[3]) );
double normalized_quat[4];
normalized_quat[0] = quat[0] / quaternion_norm;
normalized_quat[1] = quat[1] / quaternion_norm;
normalized_quat[2] = quat[2] / quaternion_norm;
normalized_quat[3] = quat[3] / quaternion_norm;
double cos_a = normalized_quat[3];
angle = deg(acos( cos_a )) * 2.0;
double sin_a = sqrt( 1.0 - cos_a * cos_a );
if ( fabs( sin_a ) < DIV_EPSILON ) sin_a = 1;
axis[0] = normalized_quat[0] / sin_a;
axis[1] = normalized_quat[1] / sin_a;
axis[2] = -1.0 * normalized_quat[2] / sin_a;
}