static void ToAxisAngleRad(Quaternion q, out Vector3 axis, out float angle) { if (Mathf.Abs(q.w) > 1.0f) { q.Normalize(); } angle = 2.0f * (float)Mathf.Acos(q.w); // angle float den = (float)Mathf.Sqrt(1.0f - q.w * q.w); if (den > 0.0001f) { axis = q.xyz / den; } else { // This occurs when the angle is zero. // Not a problem: just set an arbitrary normalized axis. axis = new Vector3(1, 0, 0); } }
/// <summary> /// Assumes that the axis is UnitZ and calculates the euler angle. /// </summary> /// <param name="q"></param> /// <returns></returns> public static float AngleFromQuaternionUnitZ(Quaternion q) { q.Normalize(); // Quaternions don't remember our initial rotation axis. Quaternion.Angle always returns values in the range [0,PI). return(q.Angle * (q.Axis.Z >= 0 ? 1 : -1)); }