Jump to content
  • Advertisement
Sign in to follow this  
Dirk Gregorius

Quaternions, Angular Velocity and Scaling

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

(1) Given a unit quaternion q representing a rotation and a time interval dt. I seek the corresponding angular velocity w that rotates a rigid body the rotation described by the quaternion during the interval dt. What I am looking for is the angular operation corresponding to the following linear operation: vec3f delta_x = ( ... ); vec3f delta_v = delta_x / dt; I can't simply scale the whole quaternion. What I am thinking of is to scale the associated angle within the quaternion. float angle = QuatGetAngle( q ); quatf axis = QuatGetAxis( q ); float w = angle / dt QuatSetAxisAngle( q, axis, w ); Actually I am solving a planar problem described in the plane described by the rotation axis. Would this be correct? (2) Given a vector a and b. Finding the difference (offset) is simply a vector subtraction: delta = a - b; How would I do this with quaternions? What I seek is the quaternion that rotates b into a. I would setup the following: delta * b = a In words this would read - Rotation b followed by delta equals a. Solving for delta I get: delta = a * b_conjugate. Is this correct? Any other way to find the relative offset rotation? Regards, -Dirk

Share this post


Link to post
Share on other sites
Advertisement
'Scaling' a quaternion in terms of its rotation angle corresponds to taking the quaternion to a power. In practice, it comes out pretty much like your example, although there are a few shortcuts you can take.

You are also correct about finding the 'difference' between two quaternions. The only variable is the order - a*conj(b) or conj(b)*a - which depends on whether you're using 'standard' or 'reverse' quaternion multiplication.

Share this post


Link to post
Share on other sites
Quote:

'Scaling' a quaternion in terms of its rotation angle corresponds to taking the quaternion to a power


I need to extend my mathlib to do this. Are there any reference implementations? IIRC GPG1 deals with this topic. Also I will look into WildMagic3.5. Any more?

Quote:

The only variable is the order - a*conj(b) or conj(b)*a - which depends on whether you're using 'standard' or 'reverse' quaternion multiplication.


I use 'standard', not 'inverse' multiplication like e.g. DirectX does, if I understand you correctly. Is the order than ok?

Share this post


Link to post
Share on other sites
Here's an implementation I had lying around:
template <class T> Quaternion<T> Quaternion<T>::Pow(const Quaternion<T>& q, T t, T epsilon) {
T l = Math<T>::SqrtSafe((T)1.0 - q.m_[W] * q.m_[W]);
if (l < epsilon)
return IDENTITY;

T angle = t * Math<T>::ATan2(l, q.m_[W]);
T s = Math<T>::Sin(angle) / l;
q.Set(s * q.m_[X], s * q.m_[Y], s * q.m_[Z], Math<T>::Cos(angle));
}
I'm in the process of re-writing all this stuff, though; this is older code, and I don't know that it's been tested. So no guarantee of correctness, or of it being an optimal implementation.

For quaternion difference using standard multiplication, I'd think you'd want:

da = b
d = b*conj(a)

d is then the quaternion that rotates a to b. But I may be missing something there...

[Edited by - jyk on September 24, 2005 11:44:28 PM]

Share this post


Link to post
Share on other sites
Thanks for the code!

Quote:

da = b
d = b*conj(a)

d is then the quaternion that rotates a to b. But I may be missing something there...


I took vectors as example:

d = a - b

d is the vector that moves b into a. Since I describe all linear velocities w.r.t. b I thought that I need to be consistent here and asked for the rotation that rotates rot_b into rot_a, like for the vectors, therefore I wrote:

d * rot_b = rot_a // In words: rot_b followed by d equals rot_a (standard mult)
d = rot_a * conj( rot_b );

Would you agree here?

-Dirk

Share this post


Link to post
Share on other sites
Be very careful here!

For orientation, this stuff works well, but angular velocity can very easily become greater than 1 revolution per time unit, which really hoses the math (your sin's and cos's either cycle around, yielding a velocity discontinuity, or else you escape into the land of non-unit quaternions).

So you might want to reconsider your approach here. What problem are dealing with that you're using angular velocity?

Share this post


Link to post
Share on other sites
To anyone using the quaternion power code that I posted, note that I changed the sqrt call to a 'safe sqrt' that operates on the absolute value of the argument. This is to prevent failure resulting from a w value slightly greater than 1.

Also, my post only addressed the issue of how to scale the rotation angle of a quaternion. As ajas suggests, there may be other issues to consider.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!