Adding alpha to Catmull-Rom

最后都变了- 提交于 2019-12-11 00:55:49

问题


I am trying to generate a Catmull-Rom curve from a list of points in Unity. As I do not want to store points in between points of the curve I opted to use a solution that could calculate a position in a Catmull-Rom curve based on time. There are a few examples of this, here and here, however, neither shows how to implement alpha.

The reason I want to implement alpha is so I can have the ability to change between a centripetal, chordal, and uniform Catmull-Rom curve.

private Vector3 GetCatmullRomPosition(float t, Vector3 p0, Vector3 p1,
                                      Vector3 p2, Vector3 p3, float alpha)
{
    Vector3 a = 2f * p1;
    Vector3 b = p2 - p0;
    Vector3 c = 2f * p0 - 5f * p1 + 4f * p2 - p3;
    Vector3 d = -p0 + 3f * p1 - 3f * p2 + p3;
    return 0.5f * (a + (b * t) + (c * t * t) + (d * t * t * t));
}

Source of code


回答1:


To anyone who comes here, the answer actually comes from the maths in one of the links from the original question. It is an answer from an SO question Catmull-rom curve with no cusps and no self-intersections . So credits to cfh.

The code posted in my original question is a great way to calculate points in a uniform Catmull-Rom spline, however, it did not factor in alpha. Therefore, it could not be used for chordal, or centripetal, (or anything in between) Catmull-Rom splines. The code below does take into account alpha and therefore supports both chordal and centripetal Catmull-Rom splines.

Without further ado, here is the code ported into C# for Unity.

private Vector3 GetCatmullRomPosition(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float alpha = 0.5f)
{
    float dt0 = GetTime(p0, p1, alpha);
    float dt1 = GetTime(p1, p2, alpha);
    float dt2 = GetTime(p2, p3, alpha);

    Vector3 t1 = ((p1 - p0) / dt0) - ((p2 - p0) / (dt0 + dt1)) + ((p2 - p1) / dt1);
    Vector3 t2 = ((p2 - p1) / dt1) - ((p3 - p1) / (dt1 + dt2)) + ((p3 - p2) / dt2);

    t1 *= dt1;
    t2 *= dt1;

    Vector3 c0 = p1;
    Vector3 c1 = t1;
    Vector3 c2 = (3 * p2) - (3 * p1) - (2 * t1) - t2;
    Vector3 c3 = (2 * p1) - (2 * p2) + t1 + t2;
    Vector3 pos = CalculatePosition(t, c0, c1, c2, c3);

    return pos;
}

private float GetTime(Vector3 p0, Vector3 p1, float alpha)
{
    if(p0 == p1)
        return 1;
    return Mathf.Pow((p1 - p0).sqrMagnitude, 0.5f * alpha);
}

private Vector3 CalculatePosition(float t, Vector3 c0, Vector3 c1, Vector3 c2, Vector3 c3)
{
    float t2 = t * t;
    float t3 = t2 * t;
    return c0 + c1 * t + c2 * t2 + c3 * t3;
}


来源:https://stackoverflow.com/questions/50655395/adding-alpha-to-catmull-rom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!