如何得到贝塞尔曲线的曲线长度和 t 的近似关系?

三次贝塞尔曲线方程中的 t 和走过的总曲线长度关系不是线性的,然后我搜索到下面的某位前辈的一段话: --- For each bezier curve…
关注者
145
被浏览
97,883
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

这个问题网上 《匀速贝塞尔曲线运动的实现》这篇文章有较完整的解答。不过不够详细,我结合Milo yip大神给出的参考文献详细说明下:

大部分内容都来自这两篇文章,我只添加了自己的理解


二次贝塞尔公式:

x坐标 X(t) = (1 - t)^2 * p0.x + 2t(1-t) * P1.x + t^2 * p2.x ---------------- (1)

y坐标 Y(t) = (1 - t)^2 * p0.y + 2t(1-t) * P1.y + t^2 * p2.y ---------------- (2)


化简(1) 得: X(t) = (p2.x - 2p1.x + p0.x) * t^2 + (2p1.x - p0.x) * t + p0.x ---- (3)

同理,对y有(4)


为了方便计算, 令 (p2.x - 2p1.x + p0.x) = a.x ; (2p1.x - p0.x) = b.x

即,定义如下变量:


这步是为了(3), (4)表达式不要那么啰嗦.


至此,我们得到(x,y)坐标关于t 和给定点 p0, p1, p2的表达式


我们下一步希望得到移动距离相对于t的表达式

首先对 (3) , (4) 求导,得出在某个点处的瞬时速度:

B'x(t) = 2a.x*t + b.x

B'y(t) = 2a.y*t + b.y

根据平面距离公式,此时速度的大小 s(t) 为:

s(t) = sqrt( (B'x(t))^2 + (B'y(t) ^2) )

s(t) = sqrt( 4a.x^2 * t^2 + 4a.y^2 * t^2 + 4a.x*b.x + 4a.y * b.y + b.x^2 + b.y^2 )

为方便计算,令



s(t) = sart( At^2 + Bt +C)

至此,我们得到瞬时速度大小关于t 和给定点 p0, p1, p2的表达式

长度就是对于瞬时速度的积分,所以求长度 L(t)即是对 s(t)做积分

感谢伟大的计算机科技,我找到了一个在线计算不定积分的网站:


按照这里的计算:

注意这里算的是不定积分,按定积分算的话还要再减去一个 L(0)

我没有验算这个过程,直接使用的《匀速贝塞尔曲线运动的实现》一文的计算结果:


原文下边这个显然法看不懂,谁看懂了麻烦告诉我...

/*****

设t`就是能够使L实现匀速运动的自变量,那么显然L(t`)=L(1.0)*t,即

*****/

从此处起,我按照Milo yip给出的文献继续进行。

对于游戏应用来说, 问题实际上是: 已知长度, 反求这个长度下的t , 这样我们可以匀速的滑动长度,求得t,然后再求得坐标

也就是说,已知长度 Distance, 记为D( 由于前边s被当成瞬时速度函数,所以不用这个字母) , 求 L(t) = D 下的 t

即:

已知 L(t) 表达式, L'(t)表达式 (即前文瞬时速度表达式 s(t))

给定常数D, 令L(t) - D = 0 , 求 t

此问题可以用牛顿切线法近似求解


预估一个初始值x0, 对以下表达式迭代即可