Sign in to follow this  

Multiplying quaternions

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

What is the effect of multiplying quaternions? I thought maybe it'd multiply their effects like matrices but it doesn't seem to do that. I know you can use it to reverse a rotation, but other than that what would you use it for? Thanks in advance.

Share this post


Link to post
Share on other sites
It is similar to multiplying matrices. The rotation R3 which is represented by the result Q3 of multiplying quaternions Q1 and Q2, is the same as the rotation which is represented by the result M3 of multiplying rotation matrices M1 and M2.

Share this post


Link to post
Share on other sites
So would Q(60, 1.0, 1.0, 0.0) be the same as Q1(60, 1.0, 0.0, 0.0) * Q2(60, 0.0, 1.0, 0.0)?

Share this post


Link to post
Share on other sites
None of those are valid quaternions. Did you mean the quaternions which correspond to rotations expressed in axis-angle form? If so, no, that's not what it comes out to. That's not how quaternions OR matrices work, because it's not how rotations work.

Share this post


Link to post
Share on other sites
Why aren't they valide quaternions? I mean them to be about an arbitrary axis. At least the first one should be, but I can kinda see how multiplying the 2 wouldn't work out that way.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ganoosh_
Why aren't they valide quaternions? I mean them to be about an arbitrary axis. At least the first one should be, but I can kinda see how multiplying the 2 wouldn't work out that way.
I'm not sure, but it looks like you might be thinking that rotation quaternions are of the form:
[angle in degrees, axis.x, axis.y, axis.z]
Actually, the representation is:
[cos(angle/2), sin(angle/2)*axis.x, sin(angle/2)*axis.y, sin(angle/2)*axis.z]
(With c++ trig functions, the angle must be in radians.) Quaternion multiplication also has a more complex form than you may be assuming.

Check out a good game math book for details, or google for info on the net. (Just watch out for misinformation, as there's about as much incorrect info online about quats as there is correct info. Well, that's probably an exaggeration, but just be sure to compare multiple sources and not believe everything you read.) Also, in general I'd recommend not messing with quats at all until/unless you have a solid handle on rotations in general (i.e. understanding axis-angle, Euler angle, and matrix rotations).

Share this post


Link to post
Share on other sites
Quaternions only represent orientations/rotation when they are unit quaternions. A unit quaternion {w,x,y,z} has w2+x2+y2+z2=1. Otherwise, I suppose, they produce distortions such as scaling or skewing.

The product of three unit quaternions (q2*q1)*v has the effect of rotation q2 following rotation q1, on the quaternion v. v is essentially a 4-vector with w-component==0, and {x,y,z} components equal to the components of the 3-vector you wish to tranform. The fact that the order in which rotations are performed affects the final result, should give you a hint that quaternion multiplication is not commutative.

If you want to rotate by angle w (in radians) around an axis v, you should produce the quaternion {cos(w/2),sin(w/2)*axis.x, sin(w/2)*axis.y, sin(w/2)*axis.z}. I don't remember the multiplication formula by heart. You shouldn't have trouble finding it

Share this post


Link to post
Share on other sites
Quote:
Original post by someusername
The product of three unit quaternions (q2*q1)*v has the effect of rotation q2 following rotation q1, on the quaternion v. v is essentially a 4-vector with w-component==0, and {x,y,z} components equal to the components of the 3-vector you wish to tranform.
I think you may have the quaternion rotation formula wrong (or perhaps I'm misunderstanding your post)...

Share this post


Link to post
Share on other sites
I've seen this being mentioned -in articles about quaternions- quite often. To be honest, I've never tried it directly. You may be right

Share this post


Link to post
Share on other sites
Let me just blatantly advertise this book, since it's so relevant. [smile]

This book is a great resource for learning quaternions (and rotations in general in 2- and 3-dimensional Euclidean spaces). I honestly couldn't recommend it more.

Share this post


Link to post
Share on other sites
I understand the rotation formula and I'm using unit quaternions. A rotation say 45 degrees around (1, 1, 0) would be (45, 1, 1, 0) for example. It works, but what if I had 2 rotations:
(45, 1, 0, 0) and (45, 0, 1, 0). Those are 2 euler angles I believe? If I multiplied those 2 quaternions, what would it do to the rotation? It doesn't come out to (45, 1, 1, 0) as I've observed. Does it keep it as a X rotation of 45 and then a Y rotation of 45? Or something else?
I do know that after multiplying if I don't normalize it, the object doesn't show because it's too big or far off screen or something I'm not sure but I have to normalize it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ganoosh_
A rotation say 45 degrees around (1, 1, 0) would be (45, 1, 1, 0) for example.
I may have misunderstood you before, so just to be sure... In the above statement are you saying that to create a quaternion representing a 45-degree rotation about (1, 1, 0) you actually set the quaternion components to w = 45, x = 1, y = 1, z = 0? Or are you just using (45, 1, 1, 0) as a shorthand for the encoded quaternion equivalent?

(If the question isn't clear, you might just post a bit of your code...)

Share this post


Link to post
Share on other sites
As a shorthand for the quaternion equivalent, before the rotation formulas.
For example my function rotate takes the w, x, y, z. It applies the formulas and sets the actual w, x, y, z in the quaternion to w = cos(w/2), x = x * sin(w/2) etc.

q.rotate(45, 1.0f, 1.0f, 0.0f);
q.matrix(m);

void Quaternion::rotate(float w, float x, float y, float z) {
if ((x + y + z) != 1.0f) {
float length = (float)sqrt(x*x + y*y + z*z);
x /= length;
y /= length;
z /= length;
}
w = DEGTORAD(w);
float sine = (float)sin(w / 2.0f);
this->x = x * sine;
this->y = y * sine;
this->z = z * sine;
this->w = (float)cos(w / 2.0f);
}



So when I say (45, 1, 0, 0) * (45, 0, 1, 0) I don't actually mean 45, 1, 0, 0 * 45, 0, 1, 0 but the quaternions that represent 45, 1, 0, 0 and etc. Which would actually be about(0.99, 0.00685, 0, 0) * (0.99, 0, 0.00685, 0). Get what I'm saying?

Share this post


Link to post
Share on other sites
Quote:
Original post by Ganoosh_
So when I say (45, 1, 0, 0) * (45, 0, 1, 0) I don't actually mean 45, 1, 0, 0 * 45, 0, 1, 0 but the quaternions that represent 45, 1, 0, 0 and etc. Which would actually be about(0.99, 0.00685, 0, 0) * (0.99, 0, 0.00685, 0). Get what I'm saying?
Indeed I do :-) However, those values don't look correct for 45-degree rotations, and I'm thinking it may be because of the normalization step in your quaternion function. First of all, I think you may mean:
if ((x*x + y*y + z*z) != 1.0f)
Rather than:
if ((x + y + z) != 1.0f)
Even then, doing an exact float comparison there renders the test almost useless; even if your axis is non-unit-length, it will almost never be normalized by the function (and the resulting quaternion will be wrong). You could introduce a tolerance, but it might be better to just a) restrict the input to unit-length axes, or b) include a boolean 'normalize the axis' argument.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Indeed I do :-) However, those values don't look correct for 45-degree rotations, and I'm thinking it may be because of the normalization step in your quaternion function.

Lol whoops. I just did that with the calculator I didn't get those values from the function, I forgot to normalize it. But I should probably fix what you said in the function.
Ok, the values from the function are (0.923, 0.382, 0.0, 0.0) and (0.923, 0.0, 0.382, 0.0).

Share this post


Link to post
Share on other sites
Sign in to follow this