在 R 中绘制一条偏离直线的平行线
Draw a parallel line in R offset from a line
我有代表在某些街道上行驶的线串。但我实际上想代表骑自行车的人的旅程,这是偏离路线的,即他们在路边附近行驶。我正在为如何去做而苦苦挣扎。我制作了一段可重现的 R 代码来说明。
## Let's say I have a route along some streets.
library(ggplot2)
## It can be described by this
data <- data.frame(x = c(1,3,10,5,0,5),
y = c(1,3,1,0,5,7),
label = c('a', 'b', 'c', 'd', 'e', 'f'))
## Visualised by this
ggplot(data, aes(x, y)) +
geom_path() +
geom_text(aes(label=label),hjust=0, vjust=0)
但我想做的是模拟有人在骑自行车。假设他们从道路中心线向左骑行 0.5,当然 'left' 是相对于这条线的方向 旅程的开始实际上看起来像这样 注意 'new_x' 和 'new_y' 在数学上不正确。它们是用于说明目的的估计值。
data <- data.frame(x = c(1,3,10,5,0,5),
y = c(1,3,1,0,5,7),
new_x = c(0.7, 3, 10.5,NA, NA, NA) ,
new_y = c(1.5, 3.5, 1, NA, NA, NA),
label = c('a', 'b', 'c', 'd', 'e', 'f'))
## Visualised by this showing the old line and the new line
ggplot(data, aes(x, y)) +
geom_path() +
geom_text(aes(label=label),hjust=0, vjust=0) +
geom_path(data = data, aes(new_x, new_y), colour='red')
所以问题是我如何正确计算 new_x 和 new_y 以创建代表骑车人旅程的连续线作为偏离道路中心的偏移量
有一个提供样条偏移计算的包:
https://www.stat.auckland.ac.nz/~paul/Reports/VWline/offset-xspline/offset-xspline.html
这是一些非常基本的近似值。我特意留下要切断的角落,因为这可能更接近自行车在拐角处转弯的方式。另请注意,如果您需要计算 "inward" 偏移量,则需要一些额外的步骤:
x <- c(1,3,10,5,0,5)
y <- c(1,3,1,0,5,7)
d <- 0.5 # distance away from the road
# Given a vector (defined by 2 points) and the distance,
# calculate a new vector that is distance away from the original
segment.shift <- function(x, y, d){
# calculate vector
v <- c(x[2] - x[1],y[2] - y[1])
# normalize vector
v <- v/sqrt((v[1]**2 + v[2]**2))
# perpendicular unit vector
vnp <- c( -v[2], v[1] )
return(list(x = c( x[1] + d*vnp[1], x[2] + d*vnp[1]),
y = c( y[1] + d*vnp[2], y[2] + d*vnp[2])))
}
plot(x,y, xlim=c(-1,11), ylim=c(-1,11), type="l", main= "Bicycle path" )
# allocate memory for the bike path
xn <- numeric( (length(x) - 1) * 2 )
yn <- numeric( (length(y) - 1) * 2 )
for ( i in 1:(length(x) - 1) ) {
xs <- c(x[i], x[i+1])
ys <- c(y[i], y[i+1])
new.s <- segment.shift( xs, ys, d )
xn[(i-1)*2+1] <- new.s$x[1] ; xn[(i-1)*2+2] <- new.s$x[2]
yn[(i-1)*2+1] <- new.s$y[1] ; yn[(i-1)*2+2] <- new.s$y[2]
}
# draw the path
lines(xn, yn, col="brown", lwd =2, lty=2)
我有代表在某些街道上行驶的线串。但我实际上想代表骑自行车的人的旅程,这是偏离路线的,即他们在路边附近行驶。我正在为如何去做而苦苦挣扎。我制作了一段可重现的 R 代码来说明。
## Let's say I have a route along some streets.
library(ggplot2)
## It can be described by this
data <- data.frame(x = c(1,3,10,5,0,5),
y = c(1,3,1,0,5,7),
label = c('a', 'b', 'c', 'd', 'e', 'f'))
## Visualised by this
ggplot(data, aes(x, y)) +
geom_path() +
geom_text(aes(label=label),hjust=0, vjust=0)
但我想做的是模拟有人在骑自行车。假设他们从道路中心线向左骑行 0.5,当然 'left' 是相对于这条线的方向 旅程的开始实际上看起来像这样 注意 'new_x' 和 'new_y' 在数学上不正确。它们是用于说明目的的估计值。
data <- data.frame(x = c(1,3,10,5,0,5),
y = c(1,3,1,0,5,7),
new_x = c(0.7, 3, 10.5,NA, NA, NA) ,
new_y = c(1.5, 3.5, 1, NA, NA, NA),
label = c('a', 'b', 'c', 'd', 'e', 'f'))
## Visualised by this showing the old line and the new line
ggplot(data, aes(x, y)) +
geom_path() +
geom_text(aes(label=label),hjust=0, vjust=0) +
geom_path(data = data, aes(new_x, new_y), colour='red')
所以问题是我如何正确计算 new_x 和 new_y 以创建代表骑车人旅程的连续线作为偏离道路中心的偏移量
有一个提供样条偏移计算的包: https://www.stat.auckland.ac.nz/~paul/Reports/VWline/offset-xspline/offset-xspline.html
这是一些非常基本的近似值。我特意留下要切断的角落,因为这可能更接近自行车在拐角处转弯的方式。另请注意,如果您需要计算 "inward" 偏移量,则需要一些额外的步骤:
x <- c(1,3,10,5,0,5)
y <- c(1,3,1,0,5,7)
d <- 0.5 # distance away from the road
# Given a vector (defined by 2 points) and the distance,
# calculate a new vector that is distance away from the original
segment.shift <- function(x, y, d){
# calculate vector
v <- c(x[2] - x[1],y[2] - y[1])
# normalize vector
v <- v/sqrt((v[1]**2 + v[2]**2))
# perpendicular unit vector
vnp <- c( -v[2], v[1] )
return(list(x = c( x[1] + d*vnp[1], x[2] + d*vnp[1]),
y = c( y[1] + d*vnp[2], y[2] + d*vnp[2])))
}
plot(x,y, xlim=c(-1,11), ylim=c(-1,11), type="l", main= "Bicycle path" )
# allocate memory for the bike path
xn <- numeric( (length(x) - 1) * 2 )
yn <- numeric( (length(y) - 1) * 2 )
for ( i in 1:(length(x) - 1) ) {
xs <- c(x[i], x[i+1])
ys <- c(y[i], y[i+1])
new.s <- segment.shift( xs, ys, d )
xn[(i-1)*2+1] <- new.s$x[1] ; xn[(i-1)*2+2] <- new.s$x[2]
yn[(i-1)*2+1] <- new.s$y[1] ; yn[(i-1)*2+2] <- new.s$y[2]
}
# draw the path
lines(xn, yn, col="brown", lwd =2, lty=2)