如何计算2条曲线上的最近点?


Answers:


3

这是我的尝试。以下算法远非完美,但它们很简单,我相信您应该从此开始,检查它们是否在您的情况下起作用,然后稍后再转换为更快和/或更准确的方法。

这个想法如下:

  • 采样贝塞尔曲线,找到该采样点上的最近点
  • 在找到的点附近对附近进行采样,找到新的最近点
  • 继续直到该点不再变化太多

贝塞尔曲线到直线距离的算法

贝塞尔曲线是通过F(t)使用一组控制点和一个可变参数的函数进行参数设置的t。生成点的数量并不重要。

该线由两个点A和设置参数B

  1. SAMPLES = 10例如

  2. t0 = 0和开始t1 = 1

  3. dt = (t1 - t0) / SAMPLES

  4. 如果dt < 1e-10(或您认为合适的任何其他精度条件),则算法完成并且答案为F(t0)

  5. 计算SAMPLES + 1贝塞尔曲线上的点列表:

    • L[0] = F(t0)
    • L[1] = F(t0 + dt)
    • L[2] = F(t0 + 2 * dt)
    • L[SAMPLES] = F(t0 + SAMPLES * dt)
  6. 查找L索引i中最接近该线的点。使用任何已知的点/线距离方法,例如平方距离||AB^L[i]A||² / ||AB||²,其中^表示叉积,||…||是距离。

  7. 如果i == 0,设置i = 1; 如果i == SAMPLES,设置i = SAMPLES - 1

  8. t1 = t0 + (i + 1) * dtt0 = t0 + (i - 1) * dt

  9. 返回步骤3。

贝塞尔曲线到贝塞尔曲线的距离算法

这次我们有两条由F(t)和设定的贝塞尔曲线G(t)

  1. SAMPLES = 10例如

  2. 开始t0 = 0t1 = 1s0 = 0s1 = 1

  3. dt = (t1 - t0) / SAMPLES

  4. ds = (s1 - s0) / SAMPLES

  5. 如果dt < 1e-10(或您认为合适的任何其他精度条件),则算法完成并且答案为F(t0)

  6. 如果这是循环的第一次运行:

    6.1。计算上的SAMPLES + 1点列表F请参见上文)。

    6.2。计算上的SAMPLES + 1点列表G

    6.3。查找哪对点彼此最接近。

    6.4。更新t0t1s0s1如上面看到的。

  7. ELSE:或者计算上的点列表F 或上的点列表G,然后查找上的哪个​​点F最接近G(s0)和更新t0t1或找到上的哪个点G最接近F(t0)和更新s0s1

  8. 返回步骤3。

问题

通过设计,这些算法将始终收敛到局部最小值。但是,不能保证它们会收敛到最佳解决方案。特别是Bézier曲线算法一点也不好,如果两条曲线在许多地方彼此靠近,很不幸,您可能会错过很长一段时间。

但是正如我所说,在开始考虑更强大的解决方案之前,您应该首先尝试使用那些简单的解决方案。


0

1)将所有内容平移到一个轴,因此无需计算到“线”的一个点的长度,而“线”就是Y轴。

然后,呃,给定一个贝塞尔曲线,这取决于控制点的数量。

如果有三个(开始,“控制”和结束),我将进行某种扫描(说出每个百分比,然后在最接近的两个百分比之间进行细化(使用“二进制”方法)。

我会尝试更多点(最接近Y轴)。

我相信数学专家可以为您提供精确的解决方案(在数学中),但是如果您想在视频游戏中找到该解决方案,则最好选择稍微好的解决方案,因为真正的解决方案可能包含多个答案(我什至没有在谈论处理能力。


ps。2条曲线,甚至不要去想(根据控制点的数量,您可能会(至少可能得到。)得到任何东西)
Valmond


0

对于贝塞尔曲线-直线情况,找到答案的最准确方法是执行以下操作:

  1. 变换问题,使直线始终在Y = 0处为水平。这是通过将所有控制点乘以适当的仿射矩阵来完成的。(我假设您熟悉用具有3个固定项的3x3矩阵表示平面的仿射变换。)
  2. 检查控制点的Y坐标。如果它们的符号都不相同,则可能与直线相交。计算Bezier曲线的Y部分的根。您可以对多项式使用任何求根方法,文献中有很多方法。例如,谷歌“凸壳行进”-对于贝塞尔曲线中使用的多项式来说,这是一种相当不错的方法。找到的每个根都是与直线相交的时间值,距离为零-完成工作。
  3. 如果所有Y坐标具有相同的符号,请计算Bezier曲线的Y部分的导数。您可以忽略点的X坐标,因为它们没有区别-目标线是水平的。找到该衍生物的根。这些是曲线局部最接近直线的时间值。
  4. 显式评估上一步中找到的所有根的Bezier曲线,并报告与直线距离最小的根。您还需要检查端点-端点的距离可能小于任何根。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.