Google Answers Logo
View Question
 
Q: Quaternion 3D Rotations (Multiplying) ( No Answer,   3 Comments )
Question  
Subject: Quaternion 3D Rotations (Multiplying)
Category: Science > Math
Asked by: asdf123-ga
List Price: $15.00
Posted: 21 Nov 2005 18:33 PST
Expires: 22 Nov 2005 12:24 PST
Question ID: 596035
I can provide more detail as necessary.
I have code but id prefer not to post it in here so email me for it.

Here is the question:
I have had good luck with 3D rotations using Quaternions.
This page has all the pertinent info:
http://www.cprogramming.com/tutorial/3d/quaternions.html

Now, multiplying two quaternions together 
should give you a rotation that is the equivalent of doing
the two respective rotations (in a certain order of course).
I am NOT having success with this and want to know what i am 
doing wrong.

It seems to work sometimes but sometimes it doesnt.

Ex. Say i have a 
Vector = (xyz) 1, 0, 0
rotate around X axis - 1, 0, 0

rotating that vector X degrees should ALWAYS give 1, 0, 0 as a 
result vector right?

however if i rotate it 90 and then 90 the answer is completely wrong.
90 and 0 works, 0 + 0 works, but many others (0-360) + (0-360) DONT.
shouldnt they?

is there a special case for rotating vectors around axes that are the same?

like i said i have code that would clarify 
but i cant post it here so let me know and i can provide it.

Here it is briefly:

Vector v1 = 1, 0, 0 (x axis)

Axis a1 = 0, 1, 0 (y axis)
Angle ang1 = 90 deg

Vector result1 = 0, 0, 1 (z axis)

Axis a2 = 1, 0, 0 (x axis)
Angle ang2 = 90 deg

Vector result2 = 0, 1, 0 (y axis)

-----------------------
Quaternions q1, q2 = 

	ang = Math.toRadians(ang);
	q.w = Math.cos(ang / 2.0);
	q.x = axis.x * Math.sin(ang / 2.0);
	q.y = axis.y * Math.sin(ang / 2.0);
	q.z = axis.z * Math.sin(ang / 2.0);

the quaternion matrices are made by:

	q.m[0] = 1 - 2 * (q.y * q.y - q.z * q.z);
	q.m[1] = 2 * (q.x * q.y - q.w * q.z);
	q.m[2] = 2 * (q.x * q.z + q.w * q.y);

	q.m[3] = 2 * (q.x * q.y + q.w * q.z);
	q.m[4] = 1 - 2 * (q.x * q.x - q.z * q.z);
	q.m[5] = 2 * (q.y * q.z - q.w * q.x);

	q.m[6] = 2 * (q.x * q.z - q.w * q.y);
	q.m[7] = 2 * (q.y * q.z + q.w * q.x);
	q.m[8] = 1 - 2 * (q.x * q.x - q.y * q.y);



and the product of 2 quats

Quaternion product = 
	product.w = (q2.w * q.w) - (q2.x * q.x) - (q2.y * q.y) - (q2.z * q.z);
	product.x = (q2.w * q.x) + (q2.x * q.w) + (q2.y * q.z) - (q2.z * q.y);
	product.y = (q2.w * q.y) - (q2.x * q.z) + (q2.y * q.w) + (q2.x * q.x);
	product.z = (q2.w * q.z) + (q2.x * q.y) - (q2.y * q.x) + (q2.z * q.w);

and then i form the Q Matrix as usual from w,x,y,z and mult it by the 
orig vector (1, 0, 0).
this works. 

but sometimes some rotations dont work.
So essential i want to know if i can rely on this mult. tech.
to always work.
Also why doesnt the 1,0,0 around 1,0,0 - first  90 deg and then 90 degrees 
doesnt work.

Thanks!

Clarification of Question by asdf123-ga on 21 Nov 2005 18:41 PST
Haha, im sorry about the scattered ranting. 
I began to talk about how rotating a vector around itself
works as individual rotations but fails as a combined rotation
obtained by multiplying the two individual rotations.

The long psuedo-coded example is an example that HAS worked
rotating the vector 1,0,0 90 degrees around 0,1,0 and then 1,0,0
should yield 0,1,0 and it does if you multiply the two individual
quaternion rotation matrices.

However, id like to know under what circumstances this fails or
if im doing something wrong.
i could have just made a mistake in my code or i could have possibly
misunderstood the intent / restrictions of multiplying two quaternions.

Does multiplying two rotation quaternions always yield a quaternion
that represents both rotations?

Also, everything ive read says that two unit quaternions multiplied
together should yield a unit length quaternion. 
Sometimes i am NOT getting this!

I desperately need this to work. Please help.

Clarification of Question by asdf123-ga on 22 Nov 2005 11:22 PST
I changed the list price from $30 to $15 seeing as how the commenter
pointed out the problem stemmed from a simple typo.

$15 dollars remains for a reassuring explanation of how reliable these
rotations are (they should be %100 reliable) and how possible 
errors might arrive (like the aforementioned rotating a vector around
itself).

Thankx
Answer  
There is no answer at this time.

Comments  
Subject: Re: Quaternion 3D Rotations (Multiplying)
From: mr_f-ga on 22 Nov 2005 00:25 PST
 
You have:

Quaternion product = 
	product.w = (q2.w * q.w) - (q2.x * q.x) - (q2.y * q.y) - (q2.z * q.z);
	product.x = (q2.w * q.x) + (q2.x * q.w) + (q2.y * q.z) - (q2.z * q.y);
	product.y = (q2.w * q.y) - (q2.x * q.z) + (q2.y * q.w) + (q2.x * q.x);
	product.z = (q2.w * q.z) + (q2.x * q.y) - (q2.y * q.x) + (q2.z * q.w);

The correct Method:

Quaternion product = 
	product.w = (q2.w * q.w) - (q2.x * q.x) - (q2.y * q.y) - (q2.z * q.z);
	product.x = (q2.w * q.x) + (q2.x * q.w) + (q2.y * q.z) - (q2.z * q.y);
	product.y = (q2.w * q.y) - (q2.x * q.z) + (q2.y * q.w) + (q2.z * q.x);
	product.z = (q2.w * q.z) + (q2.x * q.y) - (q2.y * q.x) + (q2.z * q.w);

Cant spot the difference? product.y, your last addition statement you
had q2.x * q.x.. Unless its a typo, (im assuming you copied and pasted
your code).

If this is a typo, I will reevaluate your code, but with an error like
this you could expect some of the results you were explaining.
Subject: Re: Quaternion 3D Rotations (Multiplying)
From: asdf123-ga on 22 Nov 2005 11:19 PST
 
Haha, even when looking for the typo i couldnt find it.
Wow. The products always come out unit length now.
However, i havent tested the 1,0,0 vector around 1,0,0 axis problem.
Hopefully this will fix it.
So this is totally reliable for all rotations right?
You deserve the $30.
If the answer people were quicker that would have been the 
easiest $30 they ever made, lol.
Thanks a lot!
Subject: Re: Quaternion 3D Rotations (Multiplying)
From: mr_f-ga on 22 Nov 2005 12:11 PST
 
The only reliability issues you may have is loss of precision due to
floating point operations, which would likely be caused by multiplying
the Quaterion product with another quaterion several times, so just
make sure you do you tolerence checks of the magnitude (make sure its
one) and this should be completely reliable as it is now _exactly_ how
you do quaternion product.

eg
if( Math.abs(product.w^2 + product.x^2 + product.y^2 + product.z^2 - 1
) > tolerance) then normalize

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy