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

Math 如何计算直线和曲线的最近点。。还是曲线和曲线?,math,geometry,lines,bezier,curve,Math,Geometry,Lines,Bezier,Curve,给定直线和二次贝塞尔曲线的点,如何计算它们的最近点 法线匹配的点是它们最近的点。我的意思是你画一条与这条线正交的线。如果该直线也与曲线正交,则交点是最近的点。简单的坏方法-通过迭代从第一条曲线逐点,从第二条曲线逐点,得到最小值 2.确定曲线间距离的数学函数和该函数的计算极限,如: |Fcur1(t)-Fcur2(t)|->0 Fs是向量 我想我们可以计算它的导数来确定极值,得到最近点和最远点 一段时间后我思考了这个问题,并给出了完整的回答。印度研究院有一篇关于这个问题的科学论文:()用标准分析的

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


法线匹配的点是它们最近的点。我的意思是你画一条与这条线正交的线。如果该直线也与曲线正交,则交点是最近的点。简单的坏方法-通过迭代从第一条曲线逐点,从第二条曲线逐点,得到最小值 2.确定曲线间距离的数学函数和该函数的计算极限,如:

|Fcur1(t)-Fcur2(t)|->0

Fs是向量

我想我们可以计算它的导数来确定极值,得到最近点和最远点


一段时间后我思考了这个问题,并给出了完整的回答。

印度研究院有一篇关于这个问题的科学论文:()

用标准分析的方式来描述你的问题:你有一个要最小化的数量(距离),所以你为这个量建立一个方程,找到一阶导数为零的点。通过使用曲线的参数
p
(第一点为0,最后一点为1)使用单个参数进行参数化

在直线情况下,方程相当简单:从样条曲线方程获得x/y坐标,并通过向量方程(直线法线的标量积)计算到给定直线的距离


在曲线的情况下,解析解可能变得相当复杂。您可能需要使用数值最小化技术,如Nelder Mead,或者,因为您有一个一维连续问题,所以需要简单的二等分。

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

  • 计算从P0、P1、P2到P3P4的距离
  • 如果P0或P2是最近点-->这是从P3P4开始的曲线的最近点。结束:=)
  • 如果P1是最近的点,而Pi(i=0或1)是第二个最近的点,则PiPC和P3P4之间的距离是您所寻求的距离的估计值,可能足够精确,具体取决于您的需要
  • 如果您需要更精确:计算P1',这是Q.B.曲线上离P1最近的点:您可以使用t=0.5的BQC公式找到它。-->从PiP1'到P3P4的距离是一个更准确的估计,但成本更高
  • 请注意,如果P1P1'定义的直线与P3P4相交,则P1'是距离P3P4最近的QBC点
  • 如果P1P1'没有与P3P4相交,那么你就不走运了,你必须走艰苦的道路
  • 现在,如果(以及何时)需要精度:

    考虑对曲线的参数使用分治算法: 哪一个离P3P4最近??P0P1'还是P1'P2???如果是P0P1'->t介于0和0.5之间,则计算t=0.25的Pm。 现在哪一个离P3P4最近??P0Pm或PmP1’??如果是PmP1'->计算t=0.25+0.125=0.375的Pm2,那么哪一个最接近?PM2或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上停止递归,曲线2上最近的点是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之间找到的距离低于阈值时停止算法。 该函数可能看起来像计算距离(curveParam1、A、C、shouldSplitCurve1、curveParam2、D、F、shouldSplitCurve2、previousDistance),其中点还存储其t参数


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

    我曾经写过一个工具来完成类似的任务。贝塞尔样条曲线通常是参数三次多项式。要计算三次线段和直线之间距离的平方,这只是两个多项式之间距离的平方