简体   繁体   English

在MATLAB中找到点和曲线之间的最小距离

[英]Find minimum distance between a point and a curve in MATLAB

I would like to use a MATLAB function to find the minimum length between a point and a curve? 我想使用MATLAB函数来找到点和曲线之间的最小长度? The curve is described by a complicated function that is not quite smooth. 该曲线由一个不太平滑的复杂函数描述。 So I hope to use an existing tool of matlab to compute this. 所以我希望使用matlab的现有工具来计算它。 Do you happen to know one? 你碰巧知道吗?

When someone says "its complicated" the answer is always complicated too, since I never know exactly what you have. 当有人说“复杂”时,答案总是很复杂,因为我从来不知道你到底有什么。 So I'll describe some basic ideas. 所以我将描述一些基本的想法。

If the curve is a known nonlinear function, then use the symbolic toolbox to start with. 如果曲线是已知的非线性函数,则使用符号工具箱开始。 For example, consider the function y=x^3-3*x+5, and the point (x0,y0) =(4,3) in the x,y plane. 例如,考虑函数y = x ^ 3-3 * x + 5,并且x,y平面中的点(x0,y0)=(4,3)。

Write down the square of the distance. 记下距离的平方。 Euclidean distance is easy to write. 欧几里德距离很容易写。

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

So, in MATLAB, I'll do this partly with the symbolic toolbox. 因此,在MATLAB中,我将使用符号工具箱进行部分操作。 The minimal distance must lie at a root of the first derivative. 最小距离必须位于一阶导数的根部。

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

I'm not interested in the complex roots. 我对复杂的根源不感兴趣。

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

Which one is a minimzer of the distance squared? 哪一个是距离平方的最小值?

subs(P,r(1))
ans =
    35.5086

subs(P,r(2))
ans =
    42.0327

subs(P,r(3))
ans =
    6.9875

That is the square of the distance, here minimized by the last root in the list. 这是距离的平方,这里最小化列表中的最后一个根。 Given that minimal location for x, of course we can find y by substitution into the expression for y(x)=x^3-3*x+5. 给定x的最小位置,当然我们可以通过代入y(x)= x ^ 3-3 * x + 5的表达式来找到y。

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

So it is fairly easy if the curve can be written in a simple functional form as above. 因此,如果曲线可以用如上所述的简单函数形式编写,则相当容易。 For a curve that is known only from a set of points in the plane, you can use my distance2curve utility. 对于仅从平面中的一组点知道的曲线,您可以使用我的distance2curve实用程序。 It can find the point on a space curve spline interpolant in n-dimensions that is closest to a given point. 它可以在最接近给定点的n维中找到空间曲线样条插值上的点。

For other curves, say an ellipse, the solution is perhaps most easily solved by converting to polar coordinates, where the ellipse is easily written in parametric form as a function of polar angle. 对于其他曲线,例如椭圆,解决方案可能最容易通过转换为极坐标来解决,其中椭圆很容易以参数形式写入,作为极角的函数。 Once that is done, write the distance as I did before, and then solve for a root of the derivative. 完成后,按照我之前的步骤编写距离,然后求解导数的根。

A difficult case to solve is where the function is described as not quite smooth. 一个难以解决的案例是功能被描述为不太平滑。 Is this noise or is it a non-differentiable curve? 这是噪音还是不可微分的曲线? For example, a cubic spline is "not quite smooth" at some level. 例如,三次样条曲线在某种程度上“不太平滑”。 A piecewise linear function is even less smooth at the breaks. 分段线性函数在断点处甚至更不平滑。 If you actually just have a set of data points that have a bit of noise in them, you must decide whether to smooth out the noise or not. 如果你实际上只有一组数据点中有一点噪音,你必须决定是否消除噪音。 Do you wish to essentially find the closest point on a smoothed approximation, or are you looking for the closest point on an interpolated curve? 您希望基本上找到平滑近似上的最近点,还是在寻找插值曲线上的最近点?

For a list of data points, if your goal is to not do any smoothing, then a good choice is again my distance2curve utility, using linear interpolation. 对于数据点列表,如果您的目标是不进行任何平滑处理,那么使用线性插值可以再次选择我的distance2curve实用程序。 If you wanted to do the computation yourself, if you have enough data points then you could find a good approximation by simply choosing the closest data point itself, but that may be a poor approximation if your data is not very closely spaced. 如果你想自己进行计算,如果你有足够的数据点,你可以通过简单地选择最接近的数据点来找到一个很好的近似值,但如果你的数据间距不是很近,那么这可能是一个很差的近似值。

If your problem does not lie in one of these classes, you can still often solve it using a variety of methods, but I'd need to know more specifics about the problem to be of more help. 如果您的问题不在于其中一个类,您仍然可以使用各种方法解决它,但我需要了解更多有关该问题的细节才能获得更多帮助。

There's two ways you could go about this. 有两种方法可以解决这个问题。

The easy way that will work if your curve is reasonably smooth and you don't need too high precision is to evaluate your curve at a dense number of points and simply find the minimum distance: 如果您的曲线相当平滑并且您不需要太高的精度,那么简单的方法就是在密集的点数处评估曲线并简单地找到最小距离:

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

The harder way is to minimize a function of t (or x ) that describes the distance 更难的方法是最小化描述距离的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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM