Sign in to follow this  
polar01

Quaternion to rotation matrix problem...

Recommended Posts

Hi, I contact you because in my software I use quaternion to do so rotation and in a specific context I need to convert my quaternion to a rotation matrix. In fact, my software use a formula for this and it works fine for the work I have do until now. Last week I have added some code of someone else, he is also doing so rotation with quaternion but with another formula. What I have discover is that my formula and his formula are rotating in the inverse direction !!! And I don't know why because both should have the same rotation result. This stuff is driving me nuts... so if someone understand what is happening ? [u]Here is the pseudo-code of my formula :[/u] Matrix3 rotation = Matrix3.Identity; float length = (x * x) + (y * y) + (z * z) + (w * w); float s = (length > 0f) ? 2f / length : 0f; float xx = x * x; float yy = y * y; float zz = z * z; float xw = x * w; float yw = y * w; float zw = z * w; float xz = x * z; float xy = x * y; float yz = y * z; rotation.M00 = 1f - (s * yy + s * zz); rotation.M10 = s * xy - s * zw; rotation.M20 = s * xz + s * yw; rotation.M01 = s * xy + s * zw; rotation.M11 = 1f - (s * xx + s * zz); rotation.M21 = s * yz - s * xw; rotation.M02 = s * xz - s * yw; rotation.M12 = s * yz + s * xw; rotation.M22 = 1f - (s * xx + s * yy); [u]The pseudo code of his formula[/u] Matrix4 mat = Matrix4.Identity; float ww = w * w; float xx = x * x; float yy = y * y; float zz = z * z; // Diagonal elements mat.M00 = ww + xx - yy - zz; mat.M11 = ww - xx + yy - zz; mat.M22 = ww - xx - yy + zz; // 0,1 and 1,0 elements float q03 =w * z; float q12 =x * y; mat.M01 = 2.0f * (q12 - q03); mat.M10 = 2.0f * (q03 + q12); // 0,2 and 2,0 elements float q02 = w * y; float q13 = x * z; mat.M02 = 2.0f * (q02 + q13); mat.M20 = 2.0f * (q13 - q02); // 1,2 and 2,1 elements float q01 = w * x; float q23 = y * z; mat.M12 = 2.0f * (q23 - q01); mat.M21 = 2.0f * (q01 + q23);

Share this post


Link to post
Share on other sites
Here's what I've coded:


void to_rotation_matrix( Quaternion const & src, Matrix3 & dest )

{

Real wx = src.get_w() * src.get_x();

Real wy = src.get_w() * src.get_y();

Real wz = src.get_w() * src.get_z();



Real xx = src.get_x() * src.get_x();

Real xy = src.get_x() * src.get_y();

Real xz = src.get_x() * src.get_z();



Real yy = src.get_y() * src.get_y();

Real yz = src.get_y() * src.get_z();

Real zz = src.get_z() * src.get_z();



dest.set_00( (Real)1.0 - (Real)2.0 * ( yy + zz ) );

dest.set_01( (Real)2.0 * ( xy - wz ) );

dest.set_02( (Real)2.0 * ( xz + wy ) );

dest.set_10( (Real)2.0 * ( xy + wz ) );

dest.set_11( (Real)1.0 - (Real)2.0 * ( xx + zz ) );

dest.set_12( (Real)2.0 * ( yz - wx ) );

dest.set_20( (Real)2.0 * ( xz - wy ) );

dest.set_21( (Real)2.0 * ( yz + wx ) );

dest.set_22( (Real)1.0 - (Real)2.0 * ( xx + yy ) );

}






[Edited by - johnstanp on April 29, 2010 7:07:09 AM]

Share this post


Link to post
Share on other sites
If the rotations appear to be in opposite directions, it is most likely because one version is intended for use with row vectors, and the other is intended for use with column vectors. Another possibility is that it's a problem with matrix layout conventions (i.e. 'majorness'), which can also have the end effect of matrices appearing to be transposes of one another.

Assuming it's the former (which I'm guessing it is, from what you've posted), then you can simply use the version that produces the correct results in the context in which it's being used. For what it's worth, it looks to me like your version is set up for row vectors and his is set up for column vectors, so you should use whichever version matches the vector notation convention that you're using.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this