Game Development Reference
In-Depth Information
The principle behind the AngleAxisToEuler function is to create a rotation
matrix, then use inverse trig functions to extract the Euler angles. Recall
that a rotation matrix formed from HPB rotations is defined as
cos( h )cos( b ) - sin( h )sin( p )sin( b )
cos( h )sin( b ) + sin( h )sin( p )cos( b )
sin( h )cos( p )
HPB =
-cos( p )sin( p )
cos( p )cos( b )
-sin( p )
-sin( h )cos( b ) - cos( h )sin( p )sin( b )
-sin( h )sin( b ) + cos( h )sin( p )cos( b )
cos( h )cos( p )
If each term of this is given a name based on the row and column, then
we get the matrix
m 00
m 10
m 20
m 01
m 11
m 21
m 02
m 12
m 22
Comparing terms, we can see that m 12 = -sin( p ). Hence, p = asin(- m 12).
From term m 10 we have m 10 = -cos( p )sin( p ). Therefore, m 10 =
m 12cos( p ). Hence, cos( p ) = m 10/ m 12.
We can use this to find the heading using term m 02:
m 02 = sin( h )cos( p ); therefore, m 02 = sin( h ) * ( m 10/ m 12)
sin( h )=( m 02 * m 12)/ m 10; hence, h = asin(( m 02 * m 12)/ m 10)
Using the same value for cos( p ) and term m 11, we can derive the b
value:
m 11 = cos( p )cos( b ); therefore, m 11 = cos( b ) * ( m 10/ m 12)
cos( b )=( m 11 * m 12)/ m 10; hence, b = acos(( m 11 * m 12)/ m 10)
The function uses this derivation to get the appropriate values for H , P
and B .
void C3DSAscii::AngleAxisToEuler(const VECTOR &rotaxis, const
double &rotangle, VECTOR &euler)
{
double c = cos(rotangle);
doubles = sin(rotangle);
double omc = 1.0 -c;
double m02, m10, m11, m12;
m11 = c + rotaxis.y*rotaxis.y*omc;