这个问题在这里回答了,但是没有用R语言回答。我是编码的新手,所以我一直无法弄清楚如何将已接受答案的 C++ 代码“翻译”成 R 代码。
与链接问题一样,我的线段由两个端点定义:A (x1,y1) 和 B (x2,y2)。我试图找到这条线段和点 C (x3,y3) 之间的最短(即垂直)距离。下面是一些示例代码,说明点“C”应该与线段有最短距离,但点“C1”不应该。
A <- c(2, 4)
B <- c(8, 16)
C <- c(3, 11)
C1<- c(11, 16)
plot(1, type = "n", xlim = c(0, 25), ylim = c(0, 25))
points(C[1], C[2], col = "red")
points(C1[1], C1[2], col = "blue")
points(A[1], A[2])
points(B[1], B[2])
segments(A[1], A[2], B[1], B[2])
提前感谢您的帮助!
我知道我必须删除分号和类类型才能“翻译”成 R,但我认为主要问题之一是找出与 C++ 代码中使用的 vec2 类型相当的类类型。
你在找这样的东西吗?
A <- c(2, 4)
B <- c(8, 16)
C <- c(3, 11)
C1<- c(11, 16)
library(sf)
library(sfheaders)
myline <- sf_linestring(matrix(c(A,B), ncol = 2))
mypoint <- sf_point(matrix(c(C,C1), ncol = 2))
st_length(st_nearest_points(mypoint, myline))
#[1] 0.2425356 7.0000000
视觉确认
library(ggplot2)
ggplot() +
geom_sf(data = myline, color = "green") +
geom_sf(data = mypoint, color = "blue") +
geom_sf(data = st_nearest_points(mypoint, myline), color = "magenta")
这主要是 javascript 答案的一个端口,尽管我已经让它更适合 R。特别是,它使用向量作为参数,就像 C++ 答案(
vec2
只是意味着一个二维向量),而不是提供个人x
和y
点。为此,我使用 x
和 y
值定义了您的观点:
A <- c(x = 2, y = 4)
B <- c(x = 8, y = 16)
C <- c(x = 3, y = 11)
C1 <- c(x = 11, y = 16)
你可以这样称呼它:
pDistance(start_point = C, segment_p1 = A, segment_p2 = B)
# Closest point is on segment
# [1] 2.236068
pDistance(start_point = C1, segment_p1 = A, segment_p2 = B)
# Closest point is: B
# [1] 3
我们可以用每个点的输出绘制一个半径的圆来检查答案:
pDistance <- function(start_point, segment_p1, segment_p2) {
dist_p1 <- start_point - segment_p1
dist_p2 <- segment_p2 - segment_p1
args <- as.list(match.call())
dot <- sum(dist_p1 * dist_p2)
len_sq <- sum(dist_p2^2)
param <- -1
if (len_sq != 0) { # in case of 0 length line
param <- dot / len_sq
}
if (param < 0) {
message("Closest point is: ", args$segment_p1)
xx <- segment_p1["x"]
yy <- segment_p1["y"]
} else if (param > 1) {
message("Closest point is: ", args$segment_p2)
xx <- segment_p2["x"]
yy <- segment_p2["y"]
} else {
message("Closest point is on segment")
xx <- segment_p1["x"] + param * dist_p2["x"]
yy <- segment_p1["y"] + param * dist_p2["y"]
}
dx <- unname(start_point["x"] - xx)
dy <- unname(start_point["y"] - yy)
sqrt(dx * dx + dy * dy)
}
我用
plotrix
将圆圈添加到您的情节中:
plotrix::draw.circle(C["x"], C["y"], pDistance(C, A, B))
plotrix::draw.circle(C1["x"], C1["y"], pDistance(C1, A, B))
实际功能没有使用任何额外的包