- Home /
Rotation quaternion to angular velocity
Given an object's rotation over a given time period I would like to calculate its angular velocity. Here is what I think I need to do:
1) Scale the quaternion that represents the rotation of the object by the period of time over which the rotation occurred.
2) Convert the quaternion to a Vector3 angular velocity.
The documentation doesn't specify how angular velocity is represented other than to show that it is a Vector3. I suspect that the vector's direction represents the axis of rotation of the object and its magnitude represents the rate of rotation.
On the other hand the Vector3 returned by quaternion.eulerAngles contain rotations in degrees not a vector representing an axis of rotation. I believe that there is a way to get from the quaternion to the angular velocity vector but I don't know the right approach.
Thank for any help you can provide.
Answer by Nimred · Jan 31, 2015 at 03:11 PM
This is an old question but I couldn't find a good answer anywhere in Unity Answers, I thought I'd share what I figured out:
The angular velocity is indeed the rotation axis, normalized, multiplied by the rotation speed in radians.
Quaternion.ToAngleAxis(out angle, out axis) give a rotation's axis, and the angle IN DEGREES.
So in order to get an angular velocity from a Quaternion, you can do the following:
float angleInDegrees;
Vector3 rotationAxis;
myQuaternion.ToAngleAxis(out angleInDegrees, out rotationAxis);
Vector3 angularDisplacement = rotationAxis * angleInDegrees * Mathf.Deg2Rad;
Vector3 angularSpeed = angularDisplacement / Time.deltaTime;
This is awesome--thank you for posting this. Exactly what I needed.
For anyone else hunting down this information, if you need the relative angular velocity, use:
Vector3 angularSpeed = transform.rotation * (angularDisplacement / Time.deltaTime);
Wow, can I send you a $100 bill? I just spent hours looking for that answer.
This comment doesn't get enough credit. So basically if you have a quaternion rotation that you want your rigidbody to follow - you assign to rigidbody.angularVelocity what @$$anonymous$$antBiscuits wrote. Not the original formula.
Answer by hellcats · Feb 25, 2011 at 03:19 AM
The problem is that scaling the quaternion won't work because it will no longer be a rotation (it has to be unit length to represent a rotation). The Slerp function does something similar to what you want and is a clue. Here is Slerp:
Slerp(q0, q1, t) = q(t) = (q1 q0*)^t q0
(q0* is Conj[q0], which is the inverse for unit length quaternions)
This interpolates between two rotations q0 and q1 with t varying from [0, 1]. So if you think of t as being time, then the time derivative dq/dt is:
Log[q1 q0*] (q1 q0*)^t q0
also,
dq/dt = 1/2 w(t) q(t)
Note the equivalent form, the Log[q1 q0*] part of dq/dt matches with 1/2 w(t), so the angular velocity is:
2 Log[q1 q0*]
For unit length quaternions this evaluates to
2 v / ||v|| ArcCos(s)
where quaterion q is (s, vx, vy, vz) (i.e. s is the scalar part and v the vector part)
One additional detail: the above derivation made the assumption that t (which varies from 0 to 1) is time, but that assumption is only valid if you are using two rotations 1 sec. apart. If your rotations are 1/60 second apart, then you will have to multiply the answer by 60.