这个问题在这里已有答案:
我的方法是循环曲线并检查鼠标到各个点的距离
但随着曲线越来越陡,点越来越近,如果鼠标距离阈值太高,则优先考虑循环中的第一个点而不是鼠标的壁橱。
有没有办法在其中获得统一的分数?或者检查鼠标是否在Bézier曲线上并获得曲线中的位置?
我是这样做的:
u=<0,1>
告诉我们在块线上最近点的位置和我们也知道块线(t
)的两个端点的曲线参数t0,t1
。从这里我们可以通过这样做来近似t
最近点:
t = t0 + (t1-t0)*u
在图像t0=0.25
和t1=0.375
。这有时候足够了,但是如果你想要更好的解决方案,那么在此之后只需设
dt = (t1-t0)/4
t0 = t-dt
t1 = t+dt
使用t0,t,t1
计算2个块的3个端点并再次查找最近的点。您可以递归执行此操作,因为每次迭代都会增加结果的精度
点与线的垂直距离是通过计算直线与穿过所讨论的点的轴之间的交点来计算的。因此,如果线由端点p0,p1
定义并且查询点(鼠标)是q
那么2D中的轴将是:
dp=p1-p0 // line direction
dq=(dp.y,-dp.x) // axis direction is perpendicular to dp
dq/= |dq| // normalize
p(u) = p0+dp*u // point on line
p(v) = q +dq*v // point on axis
u = <0,1> // parameter on line
v = <-inf,+inf> // parameter on axis
我们想知道来自的u,v
p0+dp*u = q +dq*v
这是2D中的2个线性方程组。在3D中,您需要利用交叉产品来获得dq
,系统将包含3个方程式。解决这个系统会给你u,v
,其中u
将告诉你最近点的块在哪里,|v|
是垂直距离本身。不要忘记,如果u
不在<0,1>
范围内,那么你必须使用该线的更近端点作为最近点。
系统可以用代数方式求解(但要注意边缘情况,因为2D中有两个方程解决方案)或使用逆矩阵...