Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save davidfoster/67fd38be5c0e9011eed47f7a8d45d13e to your computer and use it in GitHub Desktop.
Save davidfoster/67fd38be5c0e9011eed47f7a8d45d13e to your computer and use it in GitHub Desktop.
Quaternion to Angular Velocity
using UnityEngine;
public static class QuaternionExtensions {
//-----------------------------------------------------------------------------------------
// Public Methods:
//-----------------------------------------------------------------------------------------
/// <summary>Returns a <c>Vector3</c> angular velocity representation of this <c>Quaternion</c>.</summary>
public static Vector3 ToAngularVelocity(this Quaternion self) {
// return a default vector if our magnitude overshoots.
if (Mathf.Abs(self.w) > 1023.5f / 1024.0f) return new Vector3();
// work out gain which will be our components' magnitude.
float angle = Mathf.Acos(Mathf.Abs(self.w));
float gain = Mathf.Sign(self.w) * 2.0f * (angle / Mathf.Sin(angle));
return new Vector3(self.x * gain, self.y * gain, self.z * gain);
}
}
using UnityEngine;
public static class Vector3Extensions {
//-----------------------------------------------------------------------------------------
// Public Methods:
//-----------------------------------------------------------------------------------------
/// <summary>Returns a <c>Quaternion</c> from this angular velocity <c>Vector3</c>.</summary>
public static Quaternion FromAngularVelocity(this Vector3 self) {
// grab magnitude and return identity if there is none.
float magnitude = self.magnitude;
if (magnitude <= 0) return Quaternion.identity;
// work out sin gain.
float cos = Mathf.Cos(magnitude * 0.5f);
float sinGain = Mathf.Sin(magnitude * 0.5f) / magnitude;
return new Quaternion(self.x * sinGain, self.y * sinGain, self.z * sinGain, cos);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment