我实施这种圆形样条方案有什么问题?

时间:2018-07-08 16:50:25

标签: c# unity3d geometry spline

我正在尝试实现此circle spline scheme(付费专区)以便在Unity游戏中生成流畅的轨迹。想法是制作一条平滑的曲线,并在可能的情况下使用圆弧段进行无限延伸。我得到的代码确实在点之间插值,但是只要在每个点之间画一条直线即可,而与平滑度无关。

这是我作为单个函数的实现。对于[0,1]范围内的数字,它应该返回一个函数,该函数返回一系列点,描绘出currentnext之间的平滑曲线。外部生成函数还需要知道current之前的点previous,以及next之后的点future,以便使曲线保持在currentnext。除了点名称外,我还尝试遵守本文中的命名约定。

Func<float, Vector3> splineFunction (Vector3 current, Vector3 next, Vector3 previous, Vector3 future) {

    Vector3 a, b, c, d, e;
    a = (current - previous).normalized;
    b = (next - current).normalized;
    c = (next - previous).normalized;
    d = (future - next).normalized;
    e = (future - current).normalized;

    float tau_current = Mathf.Acos(Vector3.Dot(a, c));
    float tau_next = Mathf.Acos(Vector3.Dot(e, d));

    Func<float, float> tau = u => {
        float expression1 = Mathf.Cos(u * Mathf.PI / 2);
        float expression2 = Mathf.Sin(u * Mathf.PI / 2);

        return tau_current * expression1 * expression1  +  tau_next * expression2 * expression2;
    };

    Vector3 axis_current = Vector3.Cross(b, a);
    Vector3 t_current = Quaternion.AngleAxis(tau_current, axis_current) * b;

    Vector3 axis_next = Vector3.Cross(b, d);
    Vector3 tM_next = Quaternion.AngleAxis(-tau_next, axis_next) * b; // t_{i+1} mirrored about the perpendicular bisector of (current, next)

    Vector3 swivel_axis = Vector3.Cross(t_current, tM_next);
    Func<float, Vector3> t = u => {
        return Quaternion.AngleAxis(tau(u), swivel_axis) * b; // unsure about the b term here
    };

    return u => {
        Vector3 axis = Vector3.Cross(t(u), b);
        float distance = Vector3.Distance(current, next) * Mathf.Sin(u * tau(u)) / Mathf.Sin(tau(u));
        float angle = (1 - u) * tau(u);

        return current + (Quaternion.AngleAxis(angle, axis) * b * distance);
    };
}

根据this MathExchange question,我认为问题的部分原因在于我对“旋转”切线函数t的解释;更笼统地说,我觉得我错过了失败的几何图形。据我所知,除了t之外,这是作者编写程序时逐个单词的重写。为什么要跟踪一系列直线而不是平滑曲线?

0 个答案:

没有答案