コード例 #1
0
    /// <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));
        }
    }
コード例 #2
0
    /// <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));
    }