Archived

This topic is now archived and is closed to further replies.

Matrix to quaternion

This topic is 6108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I''ve been trying to learn how to use quaternions for a while now, and I got a question: When creating a quaternion from a matrix, most of the examples I''ve seen are pretty long. However, I''ve seen this(or similiar) in a few places:
public final void set(Matrix4f m1)
{
w = Math.sqrt(1.0 + m1.m00 + m1.m11 + m1.m22) / 2.0;
double w4 = (4.0 * w);
x = (m1.m12 - m1.m21) / w4 ;
y = (m1.m20 - m1.m02) / w4 ;
z = (m1.m01 - m1.m10) / w4 ;
} 
I wonder if this works too? Probably not, why would not more people use it that''s the case? Thanks...

Share on other sites
This will work for some (but not all) matrices...

A safer version might be:

const float d = (1.0f + m1.m00 + m1.m11 + m1.m22);if (d > 0.0f){    w = 0.5f * sqrtf(d);    const float temp = 0.25f / w;    x = (m1.m12 - m1.m21) * temp;    y = (m1.m20 - m1.m02) * temp;    z = (m1.m01 - m1.m10) * temp;}else{    // fall back to long code...}

As a general rule, you should always check that values you pass to square-root functions are >= 0, plus you don''t want a divide by zero.

Share on other sites
Damn, I was hoping to get away with the short one.
I guess I''ll have to learn the hard way to do it.
Thanks

Share on other sites
I don''t know if this works (I haven''t seriously tested it, in other words) but this is what I wrote a while back for my engine. The lower case ''s'' is what I use where most people use ''w''. ''v'' is a local vector. Val.v is a 16 element 1D array of floats.
void rQuat::operator = (const rMatrix4x4 &Val) {	float T, S;	T = Val.v[0] + Val.v[5] + Val.v[10] + 1.0f;	if(T > 0.0f) {		S = 0.5f / (float) rInternalSqrt(T);		s = 0.25f / S;		v.v[0] = S * (Val.v[9] - Val.v[6]);		v.v[1] = S * (Val.v[2] - Val.v[8]);		v.v[2] = S * (Val.v[4] - Val.v[1]);	} else {		if(Val.v[0] > Val.v[5]) {			if(Val.v[0] > Val.v[10]) { // Column 1				S = 0.5f / (float)rInternalSqrt(1.0f + Val.v[0] - Val.v[5] - Val.v[10]);				s = S * (Val.v[6] + Val.v[9]);				v.v[0] = S * 0.5f;				v.v[1] = S * (Val.v[1] + Val.v[4]);				v.v[2] = S * (Val.v[2] + Val.v[8]);			} else goto HandleCol3;		} else {			if(Val.v[5] > Val.v[10]) { // Column 2				S = 0.5f / (float)rInternalSqrt(1.0f + Val.v[5] - Val.v[0] - Val.v[10]);				s = S * (Val.v[2] + Val.v[8]);				v.v[0] = S * (Val.v[1] + Val.v[4]);				v.v[1] = S * 0.5f;				v.v[2] = S * (Val.v[2] + Val.v[8]);			} else goto HandleCol3;		}		return;		HandleCol3:		{ // Column 3			S = 0.5f / (float)rInternalSqrt(1.0f + Val.v[10] - Val.v[0] - Val.v[5]);			s = S * (Val.v[1] + Val.v[4]);			v.v[0] = S * (Val.v[2] + Val.v[8]);			v.v[1] = S * (Val.v[6] + Val.v[9]);			v.v[2] = S * 0.5f;		}	}}

[Resist Windows XP''s Invasive Production Activation Technology!]

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
17
5. 5

• 14
• 29
• 11
• 11
• 9
• Forum Statistics

• Total Topics
631773
• Total Posts
3002265
×