我在计算二次曲线上离鼠标位置最近的点时遇到了一些问题。我已经尝试了一些 API,但没有任何运气找到一个有效的函数。我找到了一个适用于 5 度三次贝塞尔曲线的实现,但我没有将其转换为二次曲线的数学技能。如果我有价值,我已经找到了一些可以帮助我解决问题的方法,但我不知道如何开始寻找 t。如果有人可以向我指出寻找 t 的算法,或者一些用于在二次曲线上找到最近点到任意点的示例代码,我将不胜感激。
谢谢
我可以让你开始数学。我不确定二次贝塞尔曲线是如何定义的,但它必须等同于:
(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 + bt + ct^2 + dt^3)。您也可以使用例如 Newton-Raphson 以数值方式求解此方程。
但是请注意,如果这 3 种解决方案都不在您的范围内0 < t < 1
。在这种情况下,只需计算到 (X, Y)(第一个方程)的距离值,t = 0
然后t = 1
取两者中的最小距离。
编辑:
实际上,当您解决一阶导数 = 0 时,您得到的解决方案可以是最大距离也可以是最小距离。所以你应该计算你得到的解决方案的距离(第一个方程)(最多 3 个 值t
),以及 和 处的距离,t=0
并t=1
选择所有这些值的实际最小值。
愚蠢、幼稚的方法是遍历曲线上的每个点,并计算该点与鼠标位置之间的距离,以最小的为赢家。尽管取决于您的应用程序,但您可能必须使用比这更好的东西。