【问题标题】:Find minimum distance between a point and a curve in MATLAB在MATLAB中找到点和曲线之间的最小距离
【发布时间】:2012-05-10 17:53:33
【问题描述】:

我想使用 MATLAB 函数来找到点和曲线之间的最小长度?该曲线由一个不太平滑的复杂函数描述。所以我希望使用现有的matlab工具来计算这个。你碰巧认识一个吗?

【问题讨论】:

    标签: matlab distance numeric


    【解决方案1】:

    当有人说“它很复杂”时,答案也总是很复杂,因为我永远不知道你到底有什么。所以我将描述一些基本的想法。

    如果曲线是已知的非线性函数,则使用符号工具箱开始。例如,考虑函数 y=x^3-3*x+5,x,y 平面上的点 (x0,y0) =(4,3)。

    写下距离的平方。欧几里得距离很容易写。

    (x - x0)^2 + (y - y0)^2 = (x - 4)^2 + (x^3 - 3*x + 5 - 3)^2
    

    因此,在 MATLAB 中,我将部分使用符号工具箱来执行此操作。最小距离必须在一阶导数的根处。

    sym x
    distpoly = (x - 4)^2 + (x^3 - 3*x + 5 - 3)^2;
    r = roots(diff(distpoly))
    r =
          -1.9126              
          -1.2035              
           1.4629              
          0.82664 +    0.55369i
          0.82664 -    0.55369i
    

    我对复杂的根源不感兴趣。

    r(imag(r) ~= 0) = []
    r =
          -1.9126
          -1.2035
           1.4629
    

    哪个是距离平方的最小值?

    subs(P,r(1))
    ans =
        35.5086
    
    subs(P,r(2))
    ans =
        42.0327
    
    subs(P,r(3))
    ans =
        6.9875
    

    这是距离的平方,这里被列表中的最后一个根最小化。鉴于 x 的最小位置,当然我们可以通过代入 y(x)=x^3-3*x+5 的表达式来找到 y。

    subs('x^3-3*x+5',r(3))
    ans =
           3.7419
    

    因此,如果可以将曲线写成如上所述的简单函数形式,则相当容易。对于仅从平面中的一组点已知的曲线,您可以使用我的distance2curve 实用程序。它可以在n维空间曲线样条插值上找到离给定点最近的点。

    对于其他曲线,比如椭圆,通过转换为极坐标可能最容易求解,在极坐标中,椭圆很容易以参数形式写成极角的函数。完成后,像以前一样写下距离,然后求解导数的根。

    一个难以解决的情况是函数被描述为不太平滑。这是噪声还是不可微分曲线?例如,三次样条曲线在某种程度上“不太平滑”。分段线性函数在中断处甚至更不平滑。如果您实际上只有一组数据点,其中有一点噪音,您必须决定是否消除噪音。您是希望在平滑近似上找到最近点,还是在插值曲线上寻找最近​​点?

    对于数据点列表,如果您的目标是不进行任何平滑处理,那么我的distance2curve 实用程序也是一个不错的选择,它使用线性插值。如果您想自己进行计算,如果您有足够的数据点,那么您可以通过简单地选择最接近的数据点本身来找到一个很好的近似值,但如果您的数据间隔不是很近,这可能是一个很差的近似值。

    如果您的问题不属于这些类之一,您通常仍然可以使用多种方法解决它,但我需要了解有关该问题的更多细节才能获得更多帮助。

    【讨论】:

      【解决方案2】:

      有两种方法可以解决这个问题。

      如果您的曲线相当平滑并且您不需要太高的精度,那么简单的方法是在密集的点处评估您的曲线并简单地找到最小距离:

      t = (0:0.1:100)';
      minDistance = sqrt( min( sum( bxsfun(@minus, [x(t),y(t)], yourPoint).^2,2)));
      

      更难的方法是最小化描述距离的t(或x)函数

      distance = @(t)sum( (yourPoint - [x(t),y(t)]).^2 );
      %# you can use the minimum distance from above as a decent starting guess
      tAtMin = fminsearch(distance,minDistance);
      
      minDistanceFitte = distance(tAtMin);
      

      【讨论】:

        猜你喜欢
        • 2013-10-06
        • 1970-01-01
        • 2021-08-02
        • 2014-01-28
        • 2023-01-28
        • 2013-12-09
        • 2015-01-25
        • 1970-01-01
        • 2018-05-21
        相关资源
        最近更新 更多