Answers:
这是我的尝试。以下算法远非完美,但它们很简单,我相信您应该从此开始,检查它们是否在您的情况下起作用,然后稍后再转换为更快和/或更准确的方法。
这个想法如下:
贝塞尔曲线是通过F(t)
使用一组控制点和一个可变参数的函数进行参数设置的t
。生成点的数量并不重要。
该线由两个点A
和设置参数B
。
让SAMPLES = 10
例如
从t0 = 0
和开始t1 = 1
让 dt = (t1 - t0) / SAMPLES
如果dt < 1e-10
(或您认为合适的任何其他精度条件),则算法完成并且答案为F(t0)
。
计算SAMPLES + 1
贝塞尔曲线上的点列表:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
查找L
索引i
中最接近该线的点。使用任何已知的点/线距离方法,例如平方距离||AB^L[i]A||² / ||AB||²
,其中^
表示叉积,||…||
是距离。
如果i == 0
,设置i = 1
; 如果i == SAMPLES
,设置i = SAMPLES - 1
让t1 = t0 + (i + 1) * dt
和t0 = t0 + (i - 1) * dt
返回步骤3。
这次我们有两条由F(t)
和设定的贝塞尔曲线G(t)
。
让SAMPLES = 10
例如
开始t0 = 0
,t1 = 1
,s0 = 0
和s1 = 1
让 dt = (t1 - t0) / SAMPLES
让 ds = (s1 - s0) / SAMPLES
如果dt < 1e-10
(或您认为合适的任何其他精度条件),则算法完成并且答案为F(t0)
。
如果这是循环的第一次运行:
6.1。计算上的SAMPLES + 1
点列表F
(请参见上文)。
6.2。计算上的SAMPLES + 1
点列表G
。
6.3。查找哪对点彼此最接近。
6.4。更新t0
,t1
,s0
,s1
如上面看到的。
ELSE:或者计算上的点列表F
或上的点列表G
,然后查找上的哪个点F
最接近G(s0)
和更新t0
和t1
,或找到上的哪个点G
最接近F(t0)
和更新s0
和s1
。
返回步骤3。
通过设计,这些算法将始终收敛到局部最小值。但是,不能保证它们会收敛到最佳解决方案。特别是Bézier曲线算法一点也不好,如果两条曲线在许多地方彼此靠近,很不幸,您可能会错过很长一段时间。
但是正如我所说,在开始考虑更强大的解决方案之前,您应该首先尝试使用那些简单的解决方案。
1)将所有内容平移到一个轴,因此无需计算到“线”的一个点的长度,而“线”就是Y轴。
然后,呃,给定一个贝塞尔曲线,这取决于控制点的数量。
如果有三个(开始,“控制”和结束),我将进行某种扫描(说出每个百分比,然后在最接近的两个百分比之间进行细化(使用“二进制”方法)。
我会尝试更多点(最接近Y轴)。
我相信数学专家可以为您提供精确的解决方案(在数学中),但是如果您想在视频游戏中找到该解决方案,则最好选择稍微好的解决方案,因为真正的解决方案可能包含多个答案(我什至没有在谈论处理能力。
Algorithmist博客页面上的一些答案,可以正确找到给定二次贝塞尔曲线上的最近点。
演示。
对于贝塞尔曲线-直线情况,找到答案的最准确方法是执行以下操作: