# 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.

## 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 on other sites
'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 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 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 on other sites
Thanks for the code!

Quote:
 da = bd = 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 on other sites
Quote:
 Would you agree here?
Sure. Inasmuch as you want a quaternion that will rotate b to a, your math looks correct.

##### 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 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.

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633662
• Total Posts
3013231
×