iDevGames Forums
matrix normalization?? - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: matrix normalization?? (/thread-7243.html)



matrix normalization?? - <seb> - Mar 8, 2003 09:52 AM

hi!

once again a matrix problem Smile

i am multiplying lots of rotation matrices, and after a
while my rotations dont look as i think they should!

i once read somewhere, matrices should be normalized every
once in a while when multiplying them with each other ...
is that true? and could that be the reason for my problems?

and, if i have to do that, does anyone have a link
on HOW to normalize a 4x4 matrix??

Smile
sebastian


matrix normalization?? - Mark Levin - Mar 8, 2003 11:05 AM

Floating point numbers are not 100% accurate (more like 99.99999999%); your matrix is indeed slowly diverging from the correct value. "Normalizing the matrix" means clearing it to the identity matrix and setting it explicitly to the rotation you want, instead of multiplying a rotation matrix with very small numbers a hundred thousand times.


matrix normalization?? - codemattic - Mar 8, 2003 07:56 PM

What Mark says is true. If for instance you have an tumbling asteroid - you dont want to keep a matrix for the asteroid and just keep multiplying that matrix by some rotation matrix every frame to let all the rotations accumulate - because the asteroids matrix will start to skew due to floating point roundoff. You want to build the rotation matrix fresh each frame.

However I dont believe...
Quote:Originally posted by Mark Levin
"Normalizing the matrix" means clearing it to the identity matrix and setting it explicitly to the rotation you want, instead of multiplying a rotation matrix with very small numbers a hundred thousand times.
is completely accurate. If you need to have a matrix which will accumulate errors you *can* orthonormalize it. Its slow - but again as you posted - you dont need to do it every frame because it takes some time for a matrix to become undone.

I use the math library called FreeMagic - which you can get at <http://www.magic-software.com> and it has this method for dealing with 3x3 matricies (and you really only need to apply this to the 'rotational' 3x3 section of OpenGL's 4x4 matrix)

[SOURCECODE]void Matrix3::Orthonormalize ()
{
// Algorithm uses Gram-Schmidt orthogonalization. If 'this' matrix is
// M = [m0|m1|m2], then orthonormal output matrix is Q = [q0|q1|q2],
//
// q0 = m0/|m0|
// q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0|
// q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1|
//
// where |V| indicates length of vector V and A*B indicates dot
// product of vectors A and B.

// compute q0
Real fInvLength = Math::InvSqrt(m_aafEntry[0][0]*m_aafEntry[0][0]
+ m_aafEntry[1][0]*m_aafEntry[1][0] +
m_aafEntry[2][0]*m_aafEntry[2][0]);

m_aafEntry[0][0] *= fInvLength;
m_aafEntry[1][0] *= fInvLength;
m_aafEntry[2][0] *= fInvLength;

// compute q1
Real fDot0 =
m_aafEntry[0][0]*m_aafEntry[0][1] +
m_aafEntry[1][0]*m_aafEntry[1][1] +
m_aafEntry[2][0]*m_aafEntry[2][1];

m_aafEntry[0][1] -= fDot0*m_aafEntry[0][0];
m_aafEntry[1][1] -= fDot0*m_aafEntry[1][0];
m_aafEntry[2][1] -= fDot0*m_aafEntry[2][0];

fInvLength = Math::InvSqrt(m_aafEntry[0][1]*m_aafEntry[0][1] +
m_aafEntry[1][1]*m_aafEntry[1][1] +
m_aafEntry[2][1]*m_aafEntry[2][1]);

m_aafEntry[0][1] *= fInvLength;
m_aafEntry[1][1] *= fInvLength;
m_aafEntry[2][1] *= fInvLength;

// compute q2
Real fDot1 =
m_aafEntry[0][1]*m_aafEntry[0][2] +
m_aafEntry[1][1]*m_aafEntry[1][2] +
m_aafEntry[2][1]*m_aafEntry[2][2];

fDot0 =
m_aafEntry[0][0]*m_aafEntry[0][2] +
m_aafEntry[1][0]*m_aafEntry[1][2] +
m_aafEntry[2][0]*m_aafEntry[2][2];

m_aafEntry[0][2] -= fDot0*m_aafEntry[0][0] + fDot1*m_aafEntry[0][1];
m_aafEntry[1][2] -= fDot0*m_aafEntry[1][0] + fDot1*m_aafEntry[1][1];
m_aafEntry[2][2] -= fDot0*m_aafEntry[2][0] + fDot1*m_aafEntry[2][1];

fInvLength = Math::InvSqrt(m_aafEntry[0][2]*m_aafEntry[0][2] +
m_aafEntry[1][2]*m_aafEntry[1][2] +
m_aafEntry[2][2]*m_aafEntry[2][2]);

m_aafEntry[0][2] *= fInvLength;
m_aafEntry[1][2] *= fInvLength;
m_aafEntry[2][2] *= fInvLength;
}
[/SOURCECODE]

hth,
Codemattic