2016-06-10 17 views
-1

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

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

我使用中心段的三次方程式,而曲线的第一段使用二次方程式。

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

我认为我有这个问题的原因是因为在其评估的X坐标的变化(位移)和我目前在不断评估其踏下导致输入之间存在一些差异坐标x和输出之一(我目前忽略)

我可以根据需要提供代码。 (我使用Qt作为检查正确性的一种方式,以防万一)

+0

“我有这个问题的原因”什么问题? //“如果需要,我可以提供代码”当然需要! //“我使用Qt来检查......”只有Qt?基础语言是什么? – DYangu

+0

@Dangangu谢谢你的回复。它确实是一个数学问题,而不是一个程序化的问题,这就是为什么我没有包含代码,也没有在首位指定语言。尽管我很乐意提供它。 我现在已经证实,问题来自于对曲线进行“常数阶跃评估”,而没有考虑曲线的导数。如果我要考虑弧长,它可能会工作,但不能完全解决如何做到这一点。我会更新该帖子,如果我这样做。干杯。 –

+0

是的,请。提供一些代码和错误输出。我仍不清楚你的错误是什么。 – DYangu

回答

0

原来是数学和编程的结合。

我已经扩展了自己对于正在实施的特定曲线类型的知识,现在我可以更好地解释我想要实现的目标以及我的问题。对于这可能造成的任何混淆抱歉。

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

当评估我的旧样条实现时,我得到的评估结果不正确,因为我的评估代码没有考虑曲线,除了FCurves稍微更具限制性之外。

我目前使用的方法来获得确切的评估值,一直填满一组沿着线段具有不同“t”的“线段样本”,然后遍历它以找到最接近的匹配并进行线性它们之间的插值。我稍后会回到它并试图找到一个聪明的方式,以获取多少样本真正需要以最小的误差来评估分段,但现在这个工作非常好。

所有这些都是因为应用上述公式(立方贝塞尔)时,从输入“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; 

这是两个问题/答案,帮助我明白发生了什么事情不对:

他们没有专门针对fcurves,但弧长给了我一个修复这个问题的提示。

干杯!