Matrix to Quaternion

How can I convert a rotation Matrix into a quaternion? This is my code:

void CQuaternion :: ConvertFromMatrix ( const CMatrix& m )
{
//NOTE: The matrix MUST BE homogeneus-orthonormalized
//Local variables
FLOATTYPE l_flFloat = m.GetElement(0,0)+m.GetElement(1,1)+m.GetElement(2,2);
unsigned int l_i, l_j, l_k, l_uiNxt[3]= {1,2,0};

if ( l_flFloat > static_cast<FLOATTYPE>(0.0) )
{
	l_flFloat = static_cast<FLOATTYPE>(sqrt(l_flFloat+1.0));
	m_flV[0] = (m.GetElement(2,1)-m.GetElement(1,2)) / (static_cast<FLOATTYPE>(2) * l_flFloat);
	m_flV[1] = (m.GetElement(0,2)-m.GetElement(2,0)) / (static_cast<FLOATTYPE>(2) * l_flFloat);
	m_flV[2] = (m.GetElement(1,0)-m.GetElement(0,1)) / (static_cast<FLOATTYPE>(2) * l_flFloat);
	m_flS    = static_cast<FLOATTYPE>(0.5) * l_flFloat;
}
else
{
	( m.GetElement(1,1) > m.GetElement(0,0) ) ? l_i = 1 : l_i = 0;
	if ( m.GetElement(2,2) > l_i ) l_i = 2;
    l_j = l_uiNxt[l_i];
	l_k = l_uiNxt[l_j];
    
    l_flFloat = static_cast<FLOATTYPE>( sqrt ( m.GetElement(l_i,l_i) - m.GetElement(l_j,l_j) - m.GetElement(l_k,l_k) + static_cast<FLOATTYPE>(1) ) );
  
	operator[](l_i) = l_flFloat * static_cast<FLOATTYPE>(0.5);

	l_flFloat = static_cast<FLOATTYPE>(4) * operator[](l_i);
        
	m_flS = ( m.GetElement(l_k,l_j) - m.GetElement(l_j,l_k) ) / l_flFloat;
	operator[](l_j) = ( m.GetElement(l_j,l_i) + m.GetElement(l_i,l_j) ) / l_flFloat;
	operator[](l_k) = ( m.GetElement(l_k,l_i) + m.GetElement(l_i,l_k) ) / l_flFloat;
}

but doesn’t work correctly for matrix trace <= 0.0f. Anybody could tell me why?

This is the header:

//UNIT quaternion class
class CQuaternion
{
protected:
IGE_FLOATTYPE m_flV[3], m_flS;

public:
	//Operators
	CQuaternion&		operator = ( const CQuaternion& q )				{ m_flV[0] = q.m_flV[0];
																				  m_flV[1] = q.m_flV[1];
																				  m_flV[2] = q.m_flV[2];
																				  m_flS    = q.m_flS;
																				  return *this; }

	IGE_FLOATTYPE&			operator [] (unsigned int i) const					{ return const_cast&lt;IGE_FLOATTYPE&&gt;((i&lt;3)?m_flV[i]:m_flS); }

	//Normalization methods
	CQuaternion&		Normalize ();

	//Conversion methods
	void					ConvertFromMatrix ( const CMatrix& );
	void					ConvertToMatrix ( CMatrix& );
	
	//Constuctor & initializers
	void					SetDefaults()										{ m_flV[0] = m_flV[1] = m_flV[2] = static_cast&lt;IGE_FLOATTYPE&gt;(0);
																				  m_flS = static_cast&lt;IGE_FLOATTYPE&gt;(0); }

							CQuaternion ()									{ SetDefaults(); }
							CQuaternion ( const CQuaternion& q )		{ *this=q; }
							CQuaternion ( const CMatrix& m )			{ ConvertFromMatrix ( m ); }

};

I don’t have a lot of experience with Matrix-Quaternion conversion but I’ll try to help.

Correct me if I’m wrong, but I dont think the matrix trace can be zero. You need to find the quaternion component with the greatest absolute value and then use that to find the other components, wether it’s w(the scalar part of the quaternion) or x, or y or z (the 3d vector part of the quaternion).

There should be two cases in the conversion. One where the Trace is greater than or equal to 1(use w and solve for the others) and the other case where the Trace is less than 1(find the largest value between x,y and z then use that).

You might know all that already, but it should work out that the trace is never zero if you’re at this point.

hope this helps

Funk.

Look in the “Interpolating Rotation keyframes” topic. I posted my entire (verified working) quat logic earlier today…

-Blake

First, thanks to all. But… is possible that quaternions, sometimes, doesn’t represent EXACTLY a rotation matrix. Could commit any high non-despreciable error? Suffers an strange Gimbal Lock?

Originally posted by bsenftner:
Look in the “Interpolating Rotation keyframes” topic. I posted my entire (verified working) quat logic earlier today…
-Blake

Since the search engine is SOOOOOOO SLOOOOOWWW!!! …
http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/002895.html