/// <summary> /// Performs interpolation between two quaternions using spherical linear interpolation. /// </summary> /// <param name="a">Quaternion</param> /// <param name="b">Quaternion</param> /// <param name="amount">Relative weight of the second quaternion in interpolation</param> /// <returns>Quaternion</returns> public static Quaternion32 Slerp(Quaternion32 a, Quaternion32 b, float amount) { float d, e, dot = Quaternion32.Dot(a, b); bool flag = false; if (dot < 0.0) { flag = true; dot = -dot; } if (dot > 0.999999) { d = 1.0f - amount; e = (flag ? (-amount) : amount); } else { float f = (float)Math.Acos(dot); float g = (float)(1.0 / Math.Sin(f)); d = (float)Math.Sin(((1.0 - amount) * f)) * g; e = (float)(flag ? ((-Math.Sin((amount * f))) * g) : (Math.Sin((amount * f)) * g)); } return(new Quaternion32( d * a.X + e * b.X, d * a.Y + e * b.Y, d * a.Z + e * b.Z, d * a.W + e * b.W)); }
/// <summary> /// Performs linear interpolation between two quaternions based on a value indicating the weighting of the second quaternion. /// </summary> /// <param name="a">Quaternion</param> /// <param name="b">Quaternion</param> /// <param name="amount">Relative weight of the second quaternion in interpolation</param> /// <returns>Quaternion</returns> public static Quaternion32 Lerp(Quaternion32 a, Quaternion32 b, float amount) { float f = 1.0f - amount; Quaternion32 quaternion3 = default(Quaternion32); float dot = Dot(a, b); if (dot >= 0.0) { quaternion3.X = f * a.X + amount * b.X; quaternion3.Y = f * a.Y + amount * b.Y; quaternion3.Z = f * a.Z + amount * b.Z; quaternion3.W = f * a.W + amount * b.W; } else { quaternion3.X = f * a.X - amount * b.X; quaternion3.Y = f * a.Y - amount * b.Y; quaternion3.Z = f * a.Z - amount * b.Z; quaternion3.W = f * a.W - amount * b.W; } float norm = 1.0f / quaternion3.Abs; quaternion3.X *= norm; quaternion3.Y *= norm; quaternion3.Z *= norm; quaternion3.W *= norm; return(quaternion3); }
/// <summary> /// Tries to parse the string into Quaternion. /// </summary> /// <param name="quaternion">Input string</param> /// <param name="result">Quaternion</param> /// <returns>Boolean</returns> public static bool TryParse(string quaternion, ref Quaternion32 result) { try { result = Quaternion32.Parse(quaternion); return(true); } catch (FormatException) { result = new Quaternion32(); return(false); } }
/// <summary> /// Concatenates two quaternions. /// </summary> /// <param name="a">Quaternion</param> /// <param name="b">Quaternion</param> /// <returns>Quaternion</returns> public static Quaternion32 Concatenate(Quaternion32 a, Quaternion32 b) { float x = b.X, y = b.Y, z = b.Z, w = b.W; float x2 = a.X, y2 = a.Y, z2 = a.Z, w2 = a.W; float e = y * z2 - z * y2; float f = z * x2 - x * z2; float c = x * y2 - y * x2; float d = x * x2 + y * y2 + z * z2; return(new Quaternion32( x * w2 + x2 * w + e, y * w2 + y2 * w + f, z * w2 + z2 * w + c, w * w2 - d)); }
/// <summary> /// Computes the scalar product of two quaternion. /// </summary> /// <param name="a">Quaternion</param> /// <param name="b">Quaternion</param> /// <returns>Quaternion</returns> public static float Dot(Quaternion32 a, Quaternion32 b) { return(a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W); }