/// <summary> /// 球形插值(无限制) /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="t"></param> /// <returns></returns> public static Quaterniond SlerpUnclamped(Quaterniond q1, Quaterniond q2, double t) { double dot = Dot(q1, q2); Quaterniond tmpQuat = new Quaterniond(); if (dot < 0) { dot = -dot; tmpQuat.Set(-q2.x, -q2.y, -q2.z, -q2.w); } else { tmpQuat = q2; } if (dot < 1) { double angle = Math.Acos(dot); double sinadiv, sinat, sinaomt; sinadiv = 1 / Math.Sin(angle); sinat = Math.Sin(angle * t); sinaomt = Math.Sin(angle * (1 - t)); tmpQuat.Set((q1.x * sinaomt + tmpQuat.x * sinat) * sinadiv, (q1.y * sinaomt + tmpQuat.y * sinat) * sinadiv, (q1.z * sinaomt + tmpQuat.z * sinat) * sinadiv, (q1.w * sinaomt + tmpQuat.w * sinat) * sinadiv); return(tmpQuat); } else { return(Lerp(q1, tmpQuat, t)); } }
/// <summary> /// 线性插值(无限制) /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="t"></param> /// <returns></returns> public static Quaterniond LerpUnclamped(Quaterniond a, Quaterniond b, double t) { Quaterniond tmpQuat = new Quaterniond(); if (Dot(a, b) < 0.0F) { tmpQuat.Set(a.x + t * (-b.x - a.x), a.y + t * (-b.y - a.y), a.z + t * (-b.z - a.z), a.w + t * (-b.w - a.w)); } else { tmpQuat.Set(a.x + t * (b.x - a.x), a.y + t * (b.y - a.y), a.z + t * (b.z - a.z), a.w + t * (b.w - a.w)); } double nor = Math.Sqrt(Dot(tmpQuat, tmpQuat)); return(new Quaterniond(tmpQuat.x / nor, tmpQuat.y / nor, tmpQuat.z / nor, tmpQuat.w / nor)); }