Bezier样条评估正确性

时间:2016-06-10 10:31:41

标签: qt math evaluation bezier spline

在任意点评估样条曲线的最佳/最正确方法是什么?

我已经绘制了我的评估结果,并将它们与使用UI库得到的结果进行了比较,并发现我的结果已关闭。

我使用立方公式作为中心段,并且对于第一个和第一个使用二次方程式。最后一段曲线。

http://www.it.hiof.no/~borres/j3d/jlatexmath/BezierFunction0small.png

我认为我遇到这个问题的原因是因为在评估中X坐标发生了变化(移位),我现在正在以恒定的阶梯坐标对其进行评估,这导致输入x和输入x之间存在一些差异。输出一个(我目前无视)

如果需要,我可以提供代码。 (我使用Qt作为检查正确性的方法,以防它有用)

1 个答案:

答案 0 :(得分:0)

结果是数学和编程的结合。

我已经扩展了我对正在实施的特定曲线类型的了解,现在我可以更好地解释我想要实现的目标以及我的问题。对此可能引起的任何混淆表示歉意。

我正在实施一个FCurve,并且需要能够以任意输入值“评估”它。 FCurves是表示函数的样条函数(对于任何给定的输入,它们返回单个唯一的输出)

在评估我的旧样条线实现时,我得到的评估结果不正确,因为我的评估代码没有考虑弧形长度,除了FCurves稍微限制一些事实。

我目前用来获得精确评估值的方法是填充一组沿着线段具有不同“t”的“线段样本”,然后迭代它以找到最接近的匹配并进行线性插值它们之间。我稍后会回到它并尝试找到一种聪明的方法来获得实际需要多少样本来评估该段以最小的错误但是现在这非常好用。

所有这一切都发生了,因为在应用上述公式(cubic bezier)时,从输入“x”和“t”获得不同的“x”值是相当普遍的。

以下是评估时我最终得到的一些代码:

    const uint32_t sampleCount = 20;
    Vec2 samples[sampleCount];
    fillSegmentSamples(x, &samples[0], sampleCount);

    uint32_t best = 0;
    for(uint32_t i = 0; i < sampleCount; i++)
    {
        if(samples[i].x > x)
            break;

        best = i;
    }

    uint32_t nxt = best + 1;
    if(nxt >= sampleCount)
    {
        best--;
        nxt--;
    }

    float t = (x - samples[best].x) / (samples[nxt].x - samples[best].x);

    y = lerp(samples[best].y, samples[nxt].y, t);

之前,我正在运行相当于下面的内容,这是错误的,因为它不会对x轴移位进行任何补偿。 (注意,在这种情况下,“t”从“x”中提取)

Vec2 samples[1];
fillSegmentSamples(x, &samples[0], 1);
y = samples[0].y;

这两个问题/答案帮助我理解出了什么问题:

他们并不特别关注曲线,但弧长给了我解决这个问题的暗示。

干杯!