二次贝塞尔曲线上的最近点

时间:2011-07-26 02:03:05

标签: java bezier quadratic

我在计算鼠标位置的二次曲线上的最近点时遇到了一些问题。我尝试了一些API,但是没有运气找到一个有效的功能。我找到了一个适用于5度三次贝塞尔曲线的实现,但我没有数学技能将其转换为二次曲线。我发现一些方法可以帮助我解决问题,如果我有一个t值,但我不知道如何开始找到t。如果有人可以指向我找到t的算法,或者用于找到二次曲线上最近点到任意点的一些示例代码,我将非常感激。

由于

3 个答案:

答案 0 :(得分:1)

我可以让你开始数学。 我不确定如何定义二次Bezier,但它必须是等价的 到:

(x(t), y(t)) = (a_x + b_x t + c_x t^2, a_y + b_y t + c_y t^2),

其中0 < t < 1。 a,b,c是定义曲线的6个常数。

你想要到(X,Y)的距离:

sqrt( (X - x(t))^2 + (Y - y(t))^2  )

由于您希望找到最小化上述数量的t,您可以使用它 相对于t的一阶导数并将其设置为等于0。 这给你(丢弃sqrt和因子2):

0 = (a_x - X + b_x t + c_x t^2) (b_x + 2 c-x t) + (a_y - Y + b_y t + c_y t^2) ( b_y + 2 c_y t) 

t中的三次方程式。分析解决方案是已知的,您可以在网上找到它;你可能需要做一些代数来得到t的幂的系数(即0 = a + b t + c t ^ 2 + d t ^ 3)。您也可以使用例如Newton-Raphson来数字地求解这个等式。

但请注意,如果3个解决方案都不在您的范围0 < t < 1内。在这种情况下,只计算t = 0t = 1处(X,Y)(第一个等式)的距离值,并取两者的最小距离。

修改
实际上,当你求解一阶导数= 0时,你得到的解是最大距离和最小距离。因此,您应该计算所得解的距离(第一个等式)(最多3个t值),以及t=0t=1处的距离,并选择实际最小值所有这些价值观。

答案 1 :(得分:0)

有一个ActionScript实现可以很容易地适应在线here提供的Java。

它源自“图形宝石”一书中的算法,您可以在Google图书here上仔细阅读。

答案 2 :(得分:-1)

愚蠢,天真的方式是迭代曲线上的每个点并计算该点与鼠标位置之间的距离,最小的一个是胜利者。根据您的应用,您可能不得不选择比这更好的东西。