问题描述
我正在 Unity 引擎中制作游戏,其中汽车按照贝塞尔曲线长度的百分比沿着贝塞尔曲线移动。
在此图像上,您可以看到带有 8 个停止点(黄色球体)的曲线。每个停靠点之间的距离为总距离的 20%。
在上图中,一切正常,但是当我移动手柄时,会出现手柄长度不同的问题。
如上图所示,停止点之间的距离不相等。这是因为我的算法,因为我通过将段长度乘以插值(t)来找到段点。简而言之,问题在于:如果 t=0.5,则它不在该段的 50% 中。正如您在第一张图像上看到的,停止点位于线段的一半,但在第二张图像中它不在线段的一半。这个问题就解决了,如果有一些数学公式,如何找到距离中点。
如上图所示,有两个中点。通过将 t 设置为 0.5 可以找到 T 参数中点(这是我现在正在做的),但它不是距离的一半。
如何找到距离中点(对于三次贝塞尔曲线,手柄的距离不同)?
解决方法
您已经正确观察到参数值t=0.5 一般不是长度中间的点。这是一个好的开始,但难点在于下面的数学。
用x(t)和y(t)表示参数曲线的组成部分,曲线的长度 t=0(开头)和选择的参数值 t = u 之间是 equal to
您要做的是找到 u 使得 l(u) 是 l(1) 的一半。这有时是可能的,但通常很困难或不可能。那你能做什么?
一种可能性是近似您想要的点。一种直接的方法是通过分段线性曲线来近似您的贝塞尔曲线(只需选择许多参数值 0 = t_0 t_1 t_n = 1 并通过线段连接这些参数中的值)。现在很容易计算整个长度(勾股定理是你的朋友)以及中间点(沿着分段线性曲线走规定的长度)。您采样的点越多,您就越精确,计算所需的时间也就越多,因此需要进行权衡。当然,您可以使用更复杂的数值方案进行近似,但这超出了答案的范围。
第二种可能性是将自己限制在 Bezier 曲线的一个子类中,让您可以随心所欲。这些被称为 Pythagorean-Hodograph(简称 PH)曲线。它们具有极其有用的特性,即存在一个多项式 sigma(t)使得
这意味着您可以计算上面的积分并搜索u的正确值。然而,一切都是有代价的,这里的代价是你将失去控制点放在哪里的自由度(对我来说,作为一个数学家,三次贝塞尔曲线有四个控制点;计算机图形学的人经常说“句柄”所以你可能需要翻译成你的术语)。对于立方情况,您可以在 Vito Vitrih 的 this seminar talk 幻灯片 15 中找到条件。
表示:
这取决于您是否可以在您的情况下强制执行此条件,或者它是否对您的应用程序过于严格。