gpt4 book ai didi

r - 计算垂直于线的点的距离

转载 作者:行者123 更新时间:2023-12-04 02:02:57 25 4
gpt4 key购买 nike

Not to be confused with this post.

And very similar to this post.

这是一个非常简单的概念。

我有一个 点,我想计算每个点的距离 正常 到一条线。

在这个可重复的示例中,我加载了 sp::meuse 数据并画了一条线。如何添加一列到 meuse 等于每个点法线(以直角)到线的距离?

# load data
library(sp)
data(meuse)

# create new line
newline = data.frame(y = seq(from = 330000, to = 334000, length.out = 100), x = seq(from = 178000, to = 181000, length.out = 100))
# plot the data
meuse %>%
ggplot(aes(x, y)) + geom_point() +
ggtitle("Zinc Concentration (ppm)") + coord_equal() +
geom_line(data = newline, aes(x,y))

为了显示:

enter image description here

最佳答案

当您使用 meuse 数据时,使用空间对象和空间计算似乎很自然:

library(sf)
library(sp)
data(meuse)

# create new line - please note the small changes relative to your code :
# x = first column and cbind to have a matrix instead of a data.frame
newline = cbind(x = seq(from = 178000, to = 181000, length.out = 100),
y = seq(from = 330000, to = 334000, length.out = 100))

# transform the points and lines into spatial objects
meuse <- st_as_sf(meuse, coords = c("x", "y"))
newline <- st_linestring(newline)

# Compute the distance - works also for non straight lines !
st_distance(meuse, newline) [1:10]
## [1] 291.0 285.2 409.8 548.0 647.6 756.0 510.0 403.8 509.4 684.8


# Ploting to check that your line is were you expect it
plot_sf(meuse)
plot(meuse, add = TRUE)
plot(newline, add = TRUE)

通过在只有 2 个坐标的直线上运行相同的代码,您可以说服自己这些是相对于直线的垂直距离。
但是请注意,这是到线的最小距离。因此,对于靠近线段尖端或直线范围之外的点,您将不会获得垂直距离(只是到尖端的最短距离)。
你必须有足够长的线来避免这种情况......
newline = cbind(x = c(178000, 181000), 
y = c(330000, 334000))

# transform the points and lines into spatial objects
meuse <- st_as_sf(meuse, coords = c("x", "y"), crs = 31370)
newline <- st_linestring(newline)

# Compute the distance - works also for non straight lines !
st_distance(meuse, newline) [1:10]
## [1] 291.0 285.2 409.8 548.0 647.6 756.0 510.0 403.8 509.4 684.8


# Ploting to check that your line is were you expect it
plot_sf(meuse)
plot(meuse, add = TRUE)
plot(newline, add = TRUE)

如果线的斜率为 1,您可以计算点在
使用 Pytagoras 的线(x 的差异 = y 的差异 = 到线的距离/sqrt(2))。

这在这里不起作用(红色线段不垂直于线)
因为斜率不是 1,因此 y 坐标的差异
不等于 x 坐标的差值。毕达哥拉斯方程在这里不可解。
(但由 st_distance 计算的距离是 垂直于线。)
distances <- st_distance(meuse, newline)
newline = data.frame(x = c(178000, 181000),
y = c(330000, 334000))

segments <- as.data.frame(st_coordinates(meuse))
segments <- data.frame(
segments,
X2 = segments$X - distances/sqrt(2),
Y2 = segments$Y + distances/sqrt(2)
)

library(ggplot2)
ggplot() +
geom_point(data = segments, aes(X,Y)) +
geom_line(data = newline, aes(x,y)) +
geom_segment(data = segments, aes(x = X, y = Y, xend = X2, yend = Y2),
color = "orangered", alpha = 0.5) +
coord_equal() + xlim(c(177000, 182000))

enter image description here

如果你只想绘制它,你可以使用 rgeos gProject功能(在
sf 暂时)来获得线上点的投影坐标。您需要 s 中的点和线 sp格式而不是 sf格式并在 sp 的矩阵和 ggplot 的 data.frame 之间转换。
library(sp)
library(rgeos)

newline = cbind(x = c(178000, 181000),
y = c(330000, 334000))

spline <- as(st_as_sfc(st_as_text(st_linestring(newline))), "Spatial") # there is probably a more straighforward solution...
position <- gProject(spline, as(meuse, "Spatial"))
position <- coordinates(gInterpolate(spline, position))
colnames(position) <- c("X2", "Y2")

segments <- data.frame(st_coordinates(meuse), position)

library(ggplot2)
ggplot() +
geom_point(data = segments, aes(X,Y)) +
geom_line(data = as.data.frame(newline), aes(x,y)) +
geom_segment(data = segments, aes(x = X, y = Y, xend = X2, yend = Y2),
color = "orangered", alpha = 0.5) +
coord_equal() + xlim(c(177000, 182000))

enter image description here

关于r - 计算垂直于线的点的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46106489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com