Jump to content
  • Advertisement
Sign in to follow this  
sybixsus

Rotate a Vector By a Quaternion

This topic is 4216 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

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by sybixsus
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.


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 this post


Link to post
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.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!