与参考线成直角的距离

时间:2015-03-04 07:03:19

标签: matlab math geometry computational-geometry

几个星期前,我收到一个脚本,我认为,它会计算一个点与参考线的距离(以直角),并返回沿参考线的距离以及从参考线到参考线的距离。点。说实话,这就是我认为它的作用,但是我并不完全理解该脚本,即使它只有26行。

由于我认为脚本是问题,为什么另一个依赖它的脚本变得不稳定,我认为真正理解正在发生的事情实际上很方便。我曾希望有人能帮助我。

脚本(用Matlab编写,但如果有必要,我也在python中得到它):

function [sp,np]=locate(s,x,y,xp,yp)
ipp=0;
ns=length(s);
for ip=1:length(xp);
    for i=1:ns-2
        cosa=(x(i+2)-x(i))/(s(i+2)-s(i));
        sina=(y(i+2)-y(i))/(s(i+2)-s(i));
        sproj=s(i)+(xp(ip)-x(i))*cosa+(yp(ip)-y(i))*sina;
        if sproj<s(1)
            ipp=ipp+1;
            sp(ipp)=sproj;
            np(ipp)=-(xp(ip)-x(1))*sina+(yp(ip)-y(1))*cosa;
            break
        elseif sproj>=s(i)&sproj<=s(i+2)
            ipp=ipp+1;
            sp(ipp)=sproj;
            np(ipp)=-(xp(ip)-x(i))*sina+(yp(ip)-y(i))*cosa;
            break
        elseif sproj>s(ns)
            ipp=ipp+1;
            sp(ipp)=sproj;
            np(ipp)=-(xp(ip)-x(ns))*sina+(yp(ip)-y(ns))*cosa;
            break
        end
    end
end

这里s是沿参考线的距离,x和y是参考线上的x和y点,xp和yp是与线的距离(直角)的点的坐标因为需要计算沿参考线的距离。脚本调用如下:

dist(1)=0;
for i=2:length(xref);
    dist(i)=dist(i-1)+sqrt((xref(i)-xref(i-1))^2+(yref(i)-yref(i-1))^2);
end

%% Create computational grid
ds=(dist(end)-dist(1))/(ns-1);  % stepsize
s=0:ds:dist(end);               % distance
xr=spline(dist,xref,s);            % x of line grid points
yr=spline(dist,yref,s);            % y of line grid points

%% Compute locations of initial line
[si,ni]=locate(s,xr,yr,xi,yi);
n=interp1(si,ni,s,'linear','extrap');    % distance change at right angle

是否有人可以通过解释第一个脚本中究竟发生的事情来帮助我,因为我无法真正理解它。

2 个答案:

答案 0 :(得分:1)

我对第一个函数的看法取决于数组x,y所描述的点是否位于一条线上(如你所说)或不存在(如第二个函数所示;在第二个脚本中,它们是从样条插值中获得的。< / p>

如果x,y是该行的连续点

然后,循环内的sina,cosa的计算是多余的,因为角度总是相同的。对于数组xp,yp中的每个点,函数计算其在线上的正交投影。它返回沿着直线的位置,从第一个点x(1),y(1)和有符号的正常距离开始测量。对于此任务,所有这些都以相当低效的方式发生。

如果x,y不在一行

然后计算sina,cosa是不正确的。这些是从(x(i),y(i))到(x(i + 2),y(i + 2))的方向上的单位矢量的分量。但分母是s(i + 2)-s(i),[看第二个函数]通常会大于从(x(i),y(i))到(x(x)的直线距离。 I + 2),Y(I + 2))。

以下更有意义:

cosa = (x(i+2)-x(i))/sqrt((x(i+2)-x(i))^2 + (y(i+2)-y(i))^2);
sina = (y(i+2)-y(i))/sqrt((x(i+2)-x(i))^2 + (y(i+2)-y(i))^2);

直线距离和沿曲线距离的混淆在函数的其余部分持续存在:sproj与s(i + 2)的比较,尤其是s(ns)的比较不是几何动机的。

无论如何,该函数试图将xp,yp正交投影附近的点定位到曲线上(开始时不是唯一的);取决于曲线的摇摆程度,它可能会有轻微的成功或失败。

答案 1 :(得分:1)

如果我理解你正在寻找的东西,就是这样。

该函数取三个点,前两个作为x值的矢量和y值的矢量(I&lt; ll称它们为p1和p2)和第三个点(p3)。该函数返回从p3到与p1&amp; p2相交的线的最小距离以及从(p1到交点)或(p2到交点)的距离的最小值。

示例:

定义线的两点是(1,2)和(5,10)。定义它们的线将是y = 2x。如果第三点是(1,0)。垂直线是 y = - (x-1)/ 2。两条线的交点是(2 / 5,1 / 5)。 定义参考线的最近点是(1,2),距离(2 / 5,1 / 5)到(1,2)的距离是1.7,距离(2 / 5,1 / 5)到( 1,0)是0.89。该函数将返回[1.7,0.89]。

如果这是你想要的,请告诉我。

function [ dRef, dInt ] = StackExchange( x, y, xP, yP )
%StackExchange: Calculate line intersecting (x(1), y(1)) & (x(2), y(2))
%finds perpendicular line which intersects (xP, yP) which occurs as
%(IP(1), IP(2)) then calculated the minimum distance from the reference points
%(x(1), y(1)) or (x(2), y(2)) to (IP(1), IP(2))
%and from (IP(1), IP(2)) to (xP, yP)

%Calculate  slope of reference line, the slope of the perpendicular line
%will be -1/m
m = diff(y) ./ diff(x) ;

%IP(1) is the x-coordinate of the intersection point
%This formula is solving the equation
% m * (x - x(1)) + y(1) = -(1/m) * (x - xP) + yP
%for x
IP(1) = (m^2 * x(1) + xP + m * (yP - y(1))) ./ (m^2 + 1);
%IP(2) is the y-coordinate of the intersection point
IP(2) = m * (IP(1) - x(1)) + y(1);

%Minimum distance from the reference points to the intersection point
dRef = sqrt(min((IP(1) - x).^2 + (IP(2) - y).^2));

%Distance from the intersection point to  point of interest
dInt = sqrt(sum(([xP, yP] - IP).^2));

end