c# - 向 Catmull-Rom 添加 alpha

标签 c# unity-game-engine interpolation curve catmull-rom-curve

我正在尝试从 Unity 中的点列表生成 Catmull-Rom 曲线。由于我不想在曲线点之间存储点,因此我选择使用一种可以根据时间计算 Catmull-Rom 曲线中位置的解决方案。有几个这样的例子,herehere但是,两者都没有展示如何实现 alpha。

我想要实现 alpha 的原因是这样我就能够在向心曲线、弦曲线和均匀 Catmull-Rom 曲线之间进行更改。

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

最佳答案

对于来到这里的任何人来说,答案实际上来自原始问题链接之一中的数学。这是一个answer来自一个SO问题Catmull-rom curve with no cusps and no self-intersections 。所以归功于 cfh .

我原来的问题中发布的代码是计算统一 Catmull-Rom 样条中的点的好方法,但是,它没有考虑 alpha。因此,它不能用于弦、向心、(或介于两者之间的任何东西)Catmull-Rom 样条。下面的代码确实考虑了 alpha,因此支持弦和向心 Catmull-Rom 样条线。

言归正传,这里是移植到 Unity 的 C# 中的代码。

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;
}

关于c# - 向 Catmull-Rom 添加 alpha,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50655395/

相关文章:

c# - .NET Core 3.1 ChangePasswordAsync 内部异常 "Cannot update Identity column"

html - 哪个框架更适合 RAD - Corona、Actionscript、HTML5、Unity 还是 Marmalade?

python - 如何使用 Python 插入 3D 曲面图(2D 数组)的缺失值(未定义区域)?

c# - COM 服务器如何在具有不同 ComInterfaceType 枚举的 C# 类库中编码可为空?

c# - ASP.NET MVC 中 TextBoxFor 的默认值

c# - 从 UWP 应用读取设备序列号和/或 IMEI

c# - 在 Unity 中检测 iPad 屏幕何时关闭或按下 Home 按钮的事件?

iOS clang : error Xcode 7. 3.1

javascript - 在谷歌图中插入空值

python - 如何使用网格从数据集中采样点?