Jump to content
  • Advertisement
Sign in to follow this  
prototypev

Quaternions, Axis-Angles, Slerp

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

Hi all, I have a question to ask regarding quaternions, axis-angles and slerp interpolation. First off, I have a couple of data in axis-angle format (x, y, z) to represent the rotation. What I need to do is to extract these axis-angles and convert them to quaternions. After which use slerp to interpolate the in-between frames so as to achieve smooth transition. Once I get the interpolated quaternions, I need to convert all these quaternions back into axis-angle format. So here's where my problem lies: from what I have gathered (please correct me if I am wrong), in order to perform axis-angle to quaternion conversion, the axis-angle has to be normalized. The magnitude of the rotation corresponds to the length of the rotation vector (x, y, z) (again correct me if I am wrong). And in order to perform slerp, the keyframe quaternions have to be normalized as well. So the issue here is, after all these normalization, when I convert them back to the axis-angle format, wouldn't the magnitude of rotation be distorted since everything has been normalized?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by prototypev
Hi all, I have a question to ask regarding quaternions, axis-angles and slerp interpolation.

First off, I have a couple of data in axis-angle format (x, y, z) to represent the rotation. What I need to do is to extract these axis-angles and convert them to quaternions. After which use slerp to interpolate the in-between frames so as to achieve smooth transition. Once I get the interpolated quaternions, I need to convert all these quaternions back into axis-angle format.

So here's where my problem lies: from what I have gathered (please correct me if I am wrong), in order to perform axis-angle to quaternion conversion, the axis-angle has to be normalized. The magnitude of the rotation corresponds to the length of the rotation vector (x, y, z) (again correct me if I am wrong). And in order to perform slerp, the keyframe quaternions have to be normalized as well.

So the issue here is, after all these normalization, when I convert them back to the axis-angle format, wouldn't the magnitude of rotation be distorted since everything has been normalized?
If your data is really in axis-angle format then it would be pointless to use quaternions at all. That would just add a whole lot of extra complexity doing conversions. You do not need to do any conversions, you can operate directly with axis-angle data. In this case it would be more efficient too.
Do we really need quaternions?
Note, that I assume you do NOT mean that you have Euler angles.

If you are worried about the length of the output axis, then simply remember the original length, and set it to that length afterwards.

Share this post


Link to post
Share on other sites
Quote:
Original post by prototypev
Hi all, I have a question to ask regarding quaternions, axis-angles and slerp interpolation.

So the issue here is, after all these normalization, when I convert them back to the axis-angle format, wouldn't the magnitude of rotation be distorted since everything has been normalized?


You can convert back to axis angle from a normalized quaternion without issue:


/*
Vec3 axis;
flt angle;
Quat4 q(~Vec3(1,2,3),rDegToRad(.1f)); // ~ = normalze.
q.getAxisAngle(axis,angle);
angle = rRadToDeg(angle);
*/

inline bool Quat4::getAxisAngle(Vec3 & axis,flt & angle) const {
const Vec3 & n = (Vec3 &)*this;
flt lenSqr = n.lengthSqr();
if (lenSqr > 0.f) {
axis = n*sqrtInverse(lenSqr); // The sine is encoded in the axis direction.
angle = rAcos(rSqr(w)-lenSqr); // Get the angle: from test code above, this version: .0989 vs .0969 (2*acos(w)).
// angle = 2.f*rAcos(w);
// The combined angle and axis direction negate the need for atan2() to get 2pi range rotation.
return true;
} else {
axis = Vec3(0,0,1);
angle = 0.f;
return false;
} // if
} // getAxisAngle




In my experience, the fastest and easiest way to interpolate smoothly between arbitrary rotations (with constant velocity) is with quaternions. You can use lerp() (small angles), slerp() (linear) or squad() (cubic). If interpolating between axis angle:

newAxis = normalize(lerp(alpha,axisA,axisB))
newAngle = lerp(alpha,thetaA,thetaB)

provides sufficient quality for your application, it will be faster than using quaternions (again you can lerp quaternions when the angle is small (see the links below). In the past, I found that interpolating two vectors from a matrix can work fine (then reconstructing and orthonormalizing the 3 vectors to make an orthogonal matrix).

More info on interpolating rotations:

Hacking Quaternions
Slerp Info

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
If your data is really in axis-angle format then it would be pointless to use quaternions at all. That would just add a whole lot of extra complexity doing conversions. You do not need to do any conversions, you can operate directly with axis-angle data. In this case it would be more efficient too.
Do we really need quaternions?
Note, that I assume you do NOT mean that you have Euler angles.

If you are worried about the length of the output axis, then simply remember the original length, and set it to that length afterwards.


I need to use quaternions. And further more remembering the original length works... but only for the original keyframes, not for interpolated quaternions that I need to determine using slerp.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!