如何确定一个点是否在给定公差范围内的二次贝塞尔曲线上?

时间:2017-02-03 17:17:30

标签: kotlin contains point bezier

我正在为Bézier曲线编写一个库。我已经可以将曲线计算为一定分辨率的一组点,但我现在需要反过来;在给定的容差范围内检测给定点是否在曲线上(例如0.0001)。 是否有一个简单的数学函数可以做到这一点?

请以函数的形式表达您的答案,该函数包含两个参数(xy)和一个公差(距离曲线的距离仍被视为“on”)并输出一个布尔值?

3 个答案:

答案 0 :(得分:1)

您可以利用https://docs.python.org/2/library/email-examples.html处描述的“距离曲线”方法,但这会为任何坐标找到一个$memo = {} def calculate(something) $memo[something] ||= case something when 'foo' then 'bar' else perform_calculation(something) end end 值。因为“曲线上的这一点是什么?”检查,这很好(多个t值不会改变答案; 0是曲线外的,1是曲线上的,2个或更多仍然在曲线上。)

t的几个(相对较近的间隔)值处对曲线进行采样(我假设您已经为了仅仅计算一次绘制坐标而不是每次需要绘制曲线时的效率) ),然后用最接近的t产生,开始走弯道,减少距离,直到找到最小距离(你走路如何取决于你:你可以做一个粗到细的走路,或者从罚款开始,或者根据曲线切线确定跳跃的距离等等。)

然后你的结果只是t

答案 1 :(得分:0)

对于定义为

的二次贝塞尔曲线
  

C(t)= P0(1-t)^ 2 + 2P1t(1-t)+ P2t ^ 2 = P0 + 2(P1-P0)t +(P0-2P1 + P2)t ^ 2,

对于给定点Q位于C(t)上必须存在满足

的0到1之间的t的解决方案
  

(P0-Q)+2(P1-P0)t +(P0-2P1 + P2)t ^ 2 = 0

因此,您可以尝试找到以下两个方程的公共实根

  

(P0x-2P1x + 2P2x)t ^ 2 + 2(P1x-P0x)t +(P0x-Qx)= 0
  (P0y-2P1y + 2P2y)t ^ 2 + 2(P1y-P0y)t +(P0y-Qy)= 0

如果存在这样一个共同的实根并且它在0和1之间,则意味着点Q位于曲线上。

对于三次贝塞尔曲线,您可以以类似的方式遵循此过程,但您必须找到三次方程的根。

答案 2 :(得分:0)

您想在曲线上找到最接近该点的参数,然后您可以找到该距离。如果你有一个贝塞尔曲线B(t)和一个点P,那么求解

  

(P-B(t))·B'(t)= 0。

对于二次贝塞尔曲线,这给出了一个可以通过分析求解的三次方程。或者,您可以使用迭代求解器。那么最小距离为|| P-B(t)||。