C# 检查鼠标是否在Bé上;齐尔曲线
我的方法是通过曲线循环并检查鼠标到各个点的距离 但是随着曲线变得更陡,点之间的距离越来越近,如果鼠标距离阈值太高,则会优先考虑循环中的第一个点,而不是鼠标的壁橱C# 检查鼠标是否在Bé上;齐尔曲线,c#,math,bezier,C#,Math,Bezier,我的方法是通过曲线循环并检查鼠标到各个点的距离 但是随着曲线变得更陡,点之间的距离越来越近,如果鼠标距离阈值太高,则会优先考虑循环中的第一个点,而不是鼠标的壁橱 有没有一种方法可以在其中获得一致点?或者检查鼠标是否在Bézier曲线上并获得曲线中的位置?有两种主要方法-将曲线细分为小线段和解析解 对于第二种情况,您必须根据参数t为点到曲线的平方距离构建多项式,对其进行微分,并找到结果的零点(5阶多项式)。然后选择距t[i],t=0,t=1的点的最小距离。 另一个观点-得到点在曲线上的投影,所以
有没有一种方法可以在其中获得一致点?或者检查鼠标是否在Bézier曲线上并获得曲线中的位置?有两种主要方法-将曲线细分为小线段和解析解 对于第二种情况,您必须根据参数t为点到曲线的平方距离构建多项式,对其进行微分,并找到结果的零点(5阶多项式)。然后选择距
t[i],t=0,t=1的点的最小距离。
另一个观点-得到点在曲线上的投影,所以这一点上的曲线切线垂直于向量点曲线点,它应该给出相同的表达式
关于均匀点-这是一个相当困难的问题,因为曲线长度无法用解析法计算。但是细分给出了很好的近似值。主要有两种方法-将曲线细分为小线段和解析解
对于第二种情况,您必须根据参数t为点到曲线的平方距离构建多项式,对其进行微分,并找到结果的零点(5阶多项式)。然后选择距t[i],t=0,t=1的点的最小距离。
另一个观点-得到点在曲线上的投影,所以这一点上的曲线切线垂直于向量点曲线点,它应该给出相同的表达式
关于均匀点-这是一个相当困难的问题,因为曲线长度无法用解析法计算。但是细分给出了很好的近似值。我这样做:
将曲线细分为几个块
块的数量取决于曲线的顺序。由于我通常使用立方体,我根据经验发现~8块就足够了(出于我的目的)
计算与块最近的点
因此,只需将每个块处理为直线,并计算直线上距离鼠标位置最近的点(最小垂直距离)。通过计算每个块的值并记住最近的一个
现在我们知道哪个块包含“最近的”点,从直线和垂直线的交点到上一步鼠标位置,我们应该有一个参数u=
告诉我们块线上最近的点在哪里,我们还知道块线两个端点的曲线参数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
这是一个由2个二维线性方程组组成的系统。在3D中,您需要利用叉积来获得dq
,系统将包含3个方程。求解此系统将给出u,v
,其中u
将告诉您块中最近点的位置,|v |
是垂直距离本身。不要忘记,如果u
不在范围
内,则必须使用直线的较近端点作为最近点
该系统可以用代数方法求解(但要注意边的情况,因为2D中有两个方程的解),或者使用逆矩阵…我这样做:
将曲线细分为几个块
块的数量取决于曲线的顺序。由于我通常使用立方体,我根据经验发现~8块就足够了(出于我的目的)
计算与块最近的点
因此,只需将每个块处理为直线,并计算直线上距离鼠标位置最近的点(最小垂直距离)。通过计算每个块的值并记住最近的一个
现在我们知道哪个块包含“最近的”点,从直线和垂直线的交点到上一步鼠标位置,我们应该有一个参数u=
告诉我们块线上最近的点在哪里,我们还知道块线两个端点的曲线参数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
这是一个由2个二维线性方程组组成的系统。在3D中,您需要利用交叉积