简体   繁体   English

如何找到点到线的距离(知道所有点)?

[英]How to find the distance of a point to a line (knowing all the points)?

I have a line made of two points BA and a point P. I would like to find the distance from P to the perpendicular of BA and to the parallel of BA.我有一条由两点 BA 和一个点 P 组成的线。我想找到从 P 到 BA 的垂线和 BA 的平行线的距离。 Do you know if there is any fuction aready doing it in R or Matlab??你知道在 R 或 Matlab 中是否有任何功能吗? I attacht a picture to make it easier to understand.我附上一张图片,以便更容易理解。

Sketch given as below:草图如下: 在此处输入图片说明

The function coding is straightforward from the textbook formula.从教科书公式来看,函数编码很简单。

dist_point2line <- function(P, A, B){
    dx <- B[1] - A[1]
    dy <- B[2] - A[2]
    numer <- abs(dy*P[1] - dx*P[2] + B[1]*A[2] - B[2]*A[1])
    denom <- sqrt(dx^2 + dy^2)
    d <- numer/denom
    inv_cos_ang <- if(dy == 0) 1 else sqrt(1 + (dx/dy)^2)
    p <- d*inv_cos_ang
    list(dist = d, parallel = p)
}

Test with the distance from the origin to the line passing by (0, 1) and (1, 0) .测试从原点到经过(0, 1)(1, 0)的线的距离。 The result is sqrt(2)/2 and the distance parallel to the x axis is 1 .结果是sqrt(2)/2并且平行于 x 轴的距离是1

sqrt(2)/2
#[1] 0.7071068

dist_point2line(c(0, 0), c(1, 0), c(0, 1))
#$dist
#[1] 0.7071068
#
#$parallel
#[1] 1

Another example, taken from @ ThomasIsCoding 's answer .另一个例子,取自@ ThomasIsCoding回答 Note that the results are different, this one is right.注意结果不同,这个是对的。

A <- c(1, 3)
B <- c(5, 10)
P <- c(7, 7)
dist_point2line(P, A, B)
#$dist
#[1] 3.224903
#
#$parallel
#[1] 3.714286

To see that this one is right just notice that the distance from P to the line segment parallel to the x axis is visibly around 3, not 0.8.要看到这个是正确的,请注意从 P 到平行于 x 轴的线段的距离明显在 3 左右,而不是 0.8。

plot(1, type = "n", xlim = c(0, 8), ylim = c(0, 11))
points(P[1], P[2], col = "red")
points(A[1], A[2])
points(B[1], B[2])
segments(A[1], A[2], B[1], B[2])
abline(h = P[2])

在此处输入图片说明

Edit编辑

Following a request by the OP to have the function compute the distance parallel to the y axis, here is a new version of the above function.根据 OP 要求让函数计算平行于 y 轴的距离,这里是上述函数的新版本。

dist_point2line <- function(P, A, B){
  dx <- B[1] - A[1]
  dy <- B[2] - A[2]
  numer <- abs(dy*P[1] - dx*P[2] + B[1]*A[2] - B[2]*A[1])
  denom <- sqrt(dx^2 + dy^2)
  d <- numer/denom
  inv_cos_ang <- if(dy == 0) 1 else sqrt(1 + (dx/dy)^2)
  inv_sin_ang <- if(dx == 0) 1 else sqrt(1 + (dy/dx)^2)
  px <- d*inv_cos_ang
  py <- d*inv_sin_ang
  list(dist = d, parallel = c(xdist = px, ydist = py))
}

You can try the code below, where function names perp_dist and xparal denotes perpendicular to AB and parallel to x-axis distances你可以试试下面的代码,其中函数名perp_distxparal表示垂直于 AB 和平行于 x 轴的距离

R version R版

perp_dist <- function(P,A,B) {
  norm(pracma::cross(c(P-A,0),c(B-A,0)),"2")/norm(B-A,"2") # use cross product of vectors to calculate the distance 
}

xparal_dist <- function(P,A,B) {
  AB <- B-A
  perp_dist(P,A,B)*ifelse(AB[2]==0,1,sqrt(1+(AB[1]/AB[2])**2))
}

Example例子

A <- c(1,3)
B <- c(5,10)
P <- c(7,7)
perp_dist(P,A,B)
xparal_dist(P,A,B)

which gives这使

> perp_dist(P,A,B)
[1] 0.6933752

> xparal_dist(P,A,B)
[1] 0.8333333

Matlab version MATLAB版

function d = perp_dist(P,A,B) 
  d = norm(cross([P-A,0],[B-A,0]))/norm(B-A); % use cross product of vectors to calculate the distance 
end

function d = xparal_dist(P,A,B)
  AB = B-A;
  if AB(2)==0
    f = 1;
  else
    f = sqrt(1+(AB(1)/AB(2))^2);
  end
  d = perp_dist(P,A,B)*f;
end

Example例子

A = [0,0];
B = [6,9];
P = [2.5,2.5];
perp_dist(P,A,B)
xparal_dist(P,A,B)

such that以至于

>> perp_dist(P,A,B)
ans =  0.6934

>> xparal_dist(P,A,B)
ans =  0.8333

Update (R language) :更新(R 语言)

If you have A , B and P in form of data.frame , eg,如果您有data.frame形式的ABP ,例如,

set.seed(1)
A <- data.frame(X = rnorm(5),Y = rnorm(5))
B <- data.frame(X = rnorm(5),Y = rnorm(5))
P <- data.frame(X = rnorm(5),Y = rnorm(5))

then you can use Vectorize over your data frames, ie,那么你可以在你的数据帧上使用Vectorize ,即,

dperp <- Vectorize(perp_dist)(data.frame(t(P)),data.frame(t(A)),data.frame(t(B)))
dxparal <- Vectorize(xparal_dist)(data.frame(t(P)),data.frame(t(A)),data.frame(t(B)))

such that以至于

> dperp
       X1        X2        X3        X4        X5 
0.1916007 0.3101444 2.2245761 1.2821965 0.2617655 
> dxparal
        X1         X2         X3         X4         X5 
 0.5619376  0.3351336  3.2146859 19.9448870  0.3494685 

Update 2 (R version)更新 2(R 版)

If you want to calculate distance parallel to y axis, you can use the following code (MATLAB version is similar)如果要计算平行于y轴的距离,可以使用以下代码(MATLAB版本类似)

yparal_dist <- function(P,A,B) {
  AB <- B-A
  perp_dist(P,A,B)*ifelse(AB[1]==0,1,sqrt(1+(AB[2]/AB[1])**2))
}

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

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