【问题标题】:Draw a parallel line in R offset from a line在 R 中绘制一条与直线偏移的平行线
【发布时间】:2018-05-10 14:24:03
【问题描述】:

我有一个线串,代表沿着一些街道行驶的旅程。但我想实际代表一个骑自行车的人的旅程,它偏离这条线,即他们在路边附近行驶。我正在为如何做到这一点而苦苦挣扎。我制作了一段可重现的 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 圈,但“左”当然是相对于线路的方向 旅程的开始实际上看起来像这样 注意“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 以创建一条连续的线,表示骑自行车者的旅程偏离道路中心

【问题讨论】:

    标签: r coordinates gis geospatial spatial


    【解决方案1】:

    有一个包为样条线提供偏移计算: https://www.stat.auckland.ac.nz/~paul/Reports/VWline/offset-xspline/offset-xspline.html

    这是一些非常基本的近似值。我故意留下角落被切断,因为这可能是自行车如何在拐角处转弯的更好近似值。另请注意,如果您需要计算“向内”偏移,则需要一些额外的步骤:

    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)
    

    【讨论】:

    • 这看起来很棒。好聪明。谢谢卡蒂亚。早上会玩它,然后将其标记为答案。再次感谢。
    • 如果我们想添加多条相距 x 英尺的平行线怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2019-04-03
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多