在任意点评估样条曲线的最佳/最正确的方法是什么?贝塞尔样条评估的正确性
我绘制了我的评估结果,并将它们与使用UI库所得到的结果进行了比较,结果发现我的结果已关闭。
我使用中心段的三次方程式,而曲线的第一段使用二次方程式。
我认为我有这个问题的原因是因为在其评估的X坐标的变化(位移)和我目前在不断评估其踏下导致输入之间存在一些差异坐标x和输出之一(我目前忽略)
我可以根据需要提供代码。 (我使用Qt作为检查正确性的一种方式,以防万一)
在任意点评估样条曲线的最佳/最正确的方法是什么?贝塞尔样条评估的正确性
我绘制了我的评估结果,并将它们与使用UI库所得到的结果进行了比较,结果发现我的结果已关闭。
我使用中心段的三次方程式,而曲线的第一段使用二次方程式。
我认为我有这个问题的原因是因为在其评估的X坐标的变化(位移)和我目前在不断评估其踏下导致输入之间存在一些差异坐标x和输出之一(我目前忽略)
我可以根据需要提供代码。 (我使用Qt作为检查正确性的一种方式,以防万一)
原来是数学和编程的结合。
我已经扩展了自己对于正在实施的特定曲线类型的知识,现在我可以更好地解释我想要实现的目标以及我的问题。对于这可能造成的任何混淆抱歉。
我正在实施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,但弧长给了我一个修复这个问题的提示。
干杯!
“我有这个问题的原因”什么问题? //“如果需要,我可以提供代码”当然需要! //“我使用Qt来检查......”只有Qt?基础语言是什么? – DYangu
@Dangangu谢谢你的回复。它确实是一个数学问题,而不是一个程序化的问题,这就是为什么我没有包含代码,也没有在首位指定语言。尽管我很乐意提供它。 我现在已经证实,问题来自于对曲线进行“常数阶跃评估”,而没有考虑曲线的导数。如果我要考虑弧长,它可能会工作,但不能完全解决如何做到这一点。我会更新该帖子,如果我这样做。干杯。 –
是的,请。提供一些代码和错误输出。我仍不清楚你的错误是什么。 – DYangu