如何计算直线和曲线的最近点? ..还是曲线和曲线?

时间:2011-12-12 11:26:52

标签: math geometry lines bezier curve

给定一条直线和二次贝塞尔曲线的点,你如何计算它们的最近点?

enter image description here

7 个答案:

答案 0 :(得分:7)

INRIA有一篇关于这个问题的科学论文:Computing the minimum distance between two Bézier curvesPDF here

答案 1 :(得分:6)

我曾经写过一个工具来完成类似的任务。贝塞尔样条通常是参数三次多项式。要计算立方体段和直线之间距离的平方,这只是两个多项式函数之间距离的平方,它本身只是另一个多项式函数!请注意,我说的是距离的平方,而不是平方根。

基本上,对于立方体片段上的任何点,可以计算从该点到该线的距离的平方。这将是一个6阶多项式。我们可以最小化距离的平方吗?是。最小值必须发生在该多项式的导数为零的地方。因此,区分,得到五阶多项式。使用您最喜欢的根查找工具,以数字方式生成所有根。詹金斯& Traub,无论如何。从该组根中选择正确的解决方案,排除任何复杂的解决方案,并且只有当它位于相关的立方体段内时才选择解决方案。确保排除与距离的局部最大值相对应的点。

所有这些都可以有效地完成,并且除了多项式根查找器之外不需要使用迭代优化器,因此不需要使用需要起始值的优化工具,只能在该起始值附近找到解决方案。

例如,在3-d图中我显示了由3-d(红色)中的一组点生成的曲线,然后我采取了另一组位于外面的圆,我计算了最近点在每条曲线的内部曲线上,向下划线到该曲线。这些最小距离点是由上述方案产生的。

enter image description here

答案 2 :(得分:1)

1.简单的坏方法 - 通过迭代从第一条曲线逐点进行,并从第二条曲线逐点进行并获得最小值 2.确定曲线之间距离的数学函数和该函数的计算限值,如:

| Fcur1(t)的-Fcur2(T)| - 大于0

Fs是矢量。

我认为我们可以计算出它的导数来确定极值并获得最近和最近点

我想到这一段时间后,并发布完整的回复。

答案 3 :(得分:1)

根据标准分析制定您的问题:您有一个最小化(距离)的数量,因此您需要为此数量制定一个等式,并找到一阶导数为零的点。使用曲线的参数p使用单个参数进行参数化,该参数在第一个点的0和最后一个点的1之间。

在线的情况下,方程式非常简单:从样条方程中获取x / y坐标,并通过矢量方程计算到给定线的距离(标量乘以线的法线)。

在曲线的情况下,分析解决方案可能变得相当复杂。你可能想要使用数值最小化技术,如Nelder-Mead,或者,因为你有一维连续问题,简单的二分法。

答案 4 :(得分:1)

我只是想给你一些提示,对于Q.B.Curve //段: 为了获得足够快的计算,我认为你应该首先考虑为你的算法使用一种“边界框”。 假设P0是Q的第一个点.B。曲线,P2是第二个点,P1是控制点,P3P4是段然后:

  1. 计算从P0,P1,P2到P3P4的距离
  2. 如果P0或P2是最近点 - >这是P3P4曲线的最近点。结束:=)。
  3. 如果P1是最近点,而Pi(i = 0或1)是第二个最近点,则PiPC和P3P4之间的距离是您寻找可能足够精确的距离的估计值,视您的需要而定。
  4. 如果你需要更精确:计算P1',这是距离P1最近的Q.B.curve上的点:你发现它应用了t = 0.5的BQC公式。 - >从PiP1'到P3P4的距离是一个更准确的估计 - 但更昂贵 - 。
  5. 请注意,如果P1P1'定义的线与P3P4相交,则P1'是距离P3P4最近的QBC点。
  6. 如果P1P1'没有与P3P4相交,那么你运气不好,你必须走得很厉害......
  7. 现在,如果(以及何时)你需要精确度:

    考虑在曲线参数上使用分而治之算法:  哪个离P3P4最近? P0P1'或P1'P2 ???如果它是P0P1' - > t在0和0.5之间,因此对于t = 0.25计算Pm。 现在哪个离P3P4最近? P0Pm或PmP1'??如果它是PmP1' - >计算Pm2为t = 0.25 + 0.125 = 0.375那么哪个最近? PmPm2或Pm2P1'???等等 您将立即获得准确的解决方案,例如6次迭代,您的t精度为0.004!当两点之间的距离变得低于给定值时,您可能会停止搜索。 (并没有区别两个参数,因为参数稍有变化,点可能很远) 实际上,该算法的原理是每次越来越精确地近似曲线。

    对于曲线/曲线情况,我首先将它们“装箱”以避免无用的计算,因此首先使用分段/分段计算,然后(可能)分段/曲线计算,并且仅在需要的曲线/曲线计算时使用。

    对于曲线/曲线,分而治之的作品也很难解释,但你可能会弄明白。 :=)

    希望您可以通过以下方式找到速度/准确度的良好平衡:=)

    编辑:想想我为一般情况找到了一个很好的解决方案:-) 你应该迭代每个B.Q.C的(内部)边界三角形。 因此我们有三角形T1,点A,B,C具有't'参数tA,tB,tC。 和三角形T2,点D,E,F,具有t参数tD,tE,tF。 最初我们有tA = 0 tB = 0.5 tC = 1.0,T2 tD = 0,tE = 0.5,tF = 1.0 我们的想法是递归调用一个过程,将T1和/或T2分成更小的矩形,直到我们达到精度。 第一步是计算T1与T2之间的距离,跟踪每个三角形上最近的段。第一个“技巧”:如果在T1上该段是AC,则在T1上停止递归,曲线1上的最近点是A或C.如果在T2上最近的段是DF,则在T2上停止递归,最近的点在Curve2是D或F.如果我们停止了两者的递归 - >返回距离= min(AD,AF,CD,CF)。然后,如果我们在T1上具有递归性,并且段AB最接近,则新的T1变为:A'= AB =曲线的点,其中tB =(tA + tC)/ 2 = 0.25,C =旧B.同样适用于T2:应用所需的递归,并在新T1和新T2上调用相同的算法。当在T1和T2之间找到距离减去在先前T1和T2之间找到的距离时停止算法低于阈值。 该函数可能看起来像ComputeDistance(curveParam1,A,C,shouldSplitCurve1,curveParam2,D,F,shouldSplitCurve2,previousDistance),其中points也存储它们的t参数。

    请注意,距离(曲线,线段)只是此算法的一个特例,您应该实现距离(三角形,三角形)和距离(线段,三角形)以使其工作。玩得开心。

答案 5 :(得分:1)

如果是Bézier曲线和一行

最接近该线的三个候选者:

  1. Bézier曲线段上与线平行的位置(如果存在这样的位置),
  2. 曲线段的一端
  3. 曲线段的另一端。
  4. 测试所有三个;最短距离获胜。

    在两条Bézier曲线的情况下

    取决于您是否需要精确的分析结果,或者优化的数值结果是否足够好。

    分析结果

    给出两条Bézier曲线 A t )和 B (< em> s ),您可以推导出本地方向的方程 A ' t )和 (适用取值)。点对 A ' t )= B '(< em> s )是候选者,即曲线在本地平行的( t s )。我没有检查过,但我认为 A ' t ) - B '< / strong>( s )= 0可以通过分析解决。如果您的曲线与您在示例中显示的曲线类似,那么应该只有一个解决方案或没有该方程的解决方案,但可能有两个(或者在曲线相同但翻译的情况下无限多个 - 在这种情况下您可以忽略这一点,因为获胜者将始终是曲线段端点之一)。

    在类似于上面的曲线情况轮廓的方法中,测试每个点对以及曲线段端点。最短距离获胜。

    数值结果

    假设两条Bézier曲线上的点被定义为 A t )和 B 取值)。您希望最小化距离 d t s )= | A t ) - B s )|。这是一个简单的双参数优化问题:找到最小化 d s t t s )约束0≤ t ≤1且0≤ s ≤1。

    由于 d = SQRT((xA - xB)²+(yA - yB)²),您还可以最小化函数 f t s )= [ d t s )]²保存平方根计算。

    此类优化问题有numerous ready-made methods。挑选。


    请注意,在上述两种情况下,任何高于二次Bézier曲线的数据都可以为您提供多个局部最小值,因此需要注意这一点。从您给出的示例来看,您的曲线看起来没有拐点,因此这种担忧可能不适用于您的情况。

答案 6 :(得分:0)

法线匹配的点是它们最近的点。我的意思是你绘制一条与线正交的线。 。如果该线与曲线正交,则交点是最近点