public Quaternion Exp()
{
// If q = A*(x*i+y*j+z*k) where (x,y,z) is unit length, then
// exp(q) = cos(A)+sin(A)*(x*i+y*j+z*k). If sin(A) is near zero,
// use exp(q) = cos(A)+A*(x*i+y*j+z*k) since A/sin(A) has limit 1.
Real angle = Utility.Sqrt( x * x + y * y + z * z );
Real sin = Utility.Sin( angle );
// start off with a zero quat
Quaternion result = Quaternion.Zero;
result.w = Utility.Cos( angle );
if ( Utility.Abs( sin ) >= EPSILON )
{
Real coeff = sin / angle;
result.x = coeff * x;
result.y = coeff * y;
result.z = coeff * z;
}
else
{
result.x = x;
result.y = y;
result.z = z;
}
return result;
}