# Rotate a Vector By a Quaternion

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

## Recommended Posts

Could someone give me ( or link me to ) a simple explanation on how to rotate a vector by a quaternion? Preferably without any/much mathematical notation. The more english, the better. The only one I've found so far is this one :
Vector QuaternionMultiplyVector(Quaternion * quat, Vector * vector) {
Quaternion vectorQuat, inverseQuat, resultQuat;
Vector resultVector;

vectorQuat.x = vector->x;
vectorQuat.y = vector->y;
vectorQuat.z = vector->z;
vectorQuat.w = 0.0f;

inverseQuat = *quat;
QuaternionInvert(&inverseQuat);
resultQuat = QuaternionMultiply(&vectorQuat, &inverseQuat);
resultQuat = QuaternionMultiply(quat, &resultQuat);

resultVector.x = resultQuat.x;
resultVector.y = resultQuat.y;
resultVector.z = resultQuat.z;

return resultVector;
}

But I'm finding this impossible to test or debug because the quaternion values it creates are invalid so I have no idea what the values should be at each stage. I have no idea if the tutorial expects me to normalize them at every stage to make them valid or not. So if someone could let me have a working explanation which isn't so ambiguous as that, that would be great.

##### Share on other sites
That looks like right method. As long as you supply a unit quaternion and the inverse and multiply functions work as expected it should work. Things to check for include that inverseQuat and quat are the same except the x, y, z parts are negated and the resultvector has the same length as the input vector.

##### Share on other sites
Thanks for your quick response. Well if the method sounds good, I'll stick with this and try to make it work.

Here's a snippet from my debug log. Perhaps you can see where my error is so that I can at least focus on which part to fix?

DebugLog:MULTIPLYING VECTOR (1.00000000,0.000000000,0.000000000) BY QUATERNION (-0.0876943693,-0.380955547,0.0363241844,-0.919708133)DebugLog:MAKE QUAT FROM VECTOR(1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:NORMALIZE QUAT(1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:INVERT QUAT(-1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:MULTIPLY MADE QUAT BY INVERSE QUAT(0.000000000,0.000000000,0.000000000,1.00000000)DebugLog:MULTIPLY ROTATION(INPUT)QUAT BY RESULTING QUAT(-0.0876943693,-0.380955547,0.0363241844,-0.919708133)DebugLog:ROTATED VECTOR IS THEREFORE(-0.0876943693,-0.380955547,0.0363241844)

The result certainly doesn't seem correct in the test scene. I'm just not sure at which stage the problems creeps in.

##### Share on other sites
DebugLog:MAKE QUAT FROM VECTOR(1.00000000,0.000000000,0.000000000,0.000000000)
DebugLog:INVERT QUAT(-1.00000000,0.000000000,0.000000000,0.000000000)

It looks like you are conjugating the vector rather than the quaternion here.

##### Share on other sites
The first step is to make a quaternion from the vector, with a w component of zero. So the quaternion is going to have the same values as the vector, isn't it? Am I wrong to do that by just negating the vector component of the quaternion. I'm pulling most of this from the book 3D Math Primer, and it says :

Quote:
 The conjugate of a quaternion, denoted q*, is obtained by negating the vector portion of the quaternion:w ( x y z ) = w ( -x -y -z )

Those debug logs, by the way, are all printed in x,y,z,w order, in case that wasn't apparent.

EDIT: Oh darnit, I see what you mean. I've misread it. I'm inverting the wrong quaternion. No wonder. Thanks for that.

##### Share on other sites
Ok, well now that Paradigm_Shifter spotted my reading mistake, I've got it looking a bit healthier, but the results are still wrong.

Precise same situation as above, and the debuglog reads :

DebugLog:MULTIPLYING VECTOR (1.00000000,0.000000000,0.000000000) BY QUATERNION (-0.0876943693,-0.380955547,0.0363241844,-0.919708133)DebugLog:MAKE QUAT FROM VECTOR(1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:INVERT SOURCE QUAT(0.0876943693,0.380955547,-0.0363241844,0.919708133)DebugLog:MULTIPLY MADE QUAT BY INVERSE QUAT(0.919708133,0.0363241844,0.380955547,-0.0876943693)DebugLog:MULTIPLY ROTATION(INPUT)QUAT BY RESULTING QUAT(-0.984619319,0.0668153092,-0.00637084246,0.161306456)

I'm not sure if I've got the multiplication order back to front or if it's something else, but it definitely seems better, but still not right.

##### Share on other sites
Can't answer your specific problem since it's been a couple years since I implemented my quaternion class. However, this article has a lot of the math and quite a bit of code that should help you out (you may have to create an account to access the article)

http://www.gamasutra.com/features/19980703/quaternions_01.htm

-me

##### Share on other sites
I see nothing wrong with your first function.

Rotating a vector by quaternion is actually just 3 quaternion multiplications:

Qr = Q * Qv * Qinv;

Qr and Qv are just vectors in un-normalized quaternion form. Do not normalize these quats!
Q and Qinv are your normalized and inverse quaterion.

Just make sure your order of multiplication is correct.

Of course, there are optimizations, since w is zero for Qv, so you can reduce the number
of multiplications.

##### Share on other sites
Quote:
 Original post by sybixsusOk, well now that Paradigm_Shifter spotted my reading mistake, I've got it looking a bit healthier, but the results are still wrong.Precise same situation as above, and the debuglog reads :DebugLog:MULTIPLYING VECTOR (1.00000000,0.000000000,0.000000000) BY QUATERNION (-0.0876943693,-0.380955547,0.0363241844,-0.919708133)DebugLog:MAKE QUAT FROM VECTOR(1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:INVERT SOURCE QUAT(0.0876943693,0.380955547,-0.0363241844,0.919708133)DebugLog:MULTIPLY MADE QUAT BY INVERSE QUAT(0.919708133,0.0363241844,0.380955547,-0.0876943693)DebugLog:MULTIPLY ROTATION(INPUT)QUAT BY RESULTING QUAT(-0.984619319,0.0668153092,-0.00637084246,0.161306456) I'm not sure if I've got the multiplication order back to front or if it's something else, but it definitely seems better, but still not right.

DebugLog:MULTIPLYING VECTOR (1.00000000,0.000000000,0.000000000) BY QUATERNION (-0.0876943693,-0.380955547,0.0363241844,-0.919708133)
DebugLog:INVERT SOURCE QUAT(0.0876943693,0.380955547,-0.0363241844,0.919708133)

This looks like you are negating ALL of the components of the quaternion rather than just the x,y,z terms.

##### Share on other sites
Oops, well spotted, and thanks. I've fixed the inverse method now. I've also changed to a standard quaternion value for testing to make things a little easier.

Here are the results :

MULTIPLYING VECTOR (1.00000000,0.000000000,0.000000000) BY QUATERNION (0.000000000,-0.707106769,0.000000000,0.707106769)DebugLog:MAKE QUAT FROM VECTOR(1.00000000,0.000000000,0.000000000,0.000000000)DebugLog:INVERT SOURCE QUAT(0.000000000,0.707106769,0.000000000,0.707106769)DebugLog:MULTIPLY MADE QUAT BY INVERSE QUAT(0.707106769,0.000000000,0.707106769,0.000000000)DebugLog:MULTIPLY ROTATION(INPUT)QUAT BY RESULTING QUAT(0.000000000,0.000000000,0.999999940,0.000000000)DebugLog:0.000000000,0.000000000,0.999999940

So I come out with ( basically ) 0,0,1 which I think is correct, isn't it? Or should it be 0,0,-1?

It doesn't seem to work for more complicated rotations, yet, but if someone can confirm or deny that this is correct, I can go into the more complex multi-axis rotations.