Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a parallel line in R offset from a line

I have linestring which represent a driving journey down some streets. But I want to actually represent a cyclists journey, which is offset from the line i.e. they travel near the kerb of the road. I'm struggling with how to do it. I've made a reproducible piece of R code to illustrate.

## 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)

enter image description here

But what I want to do it model as though someone were cycling. Let's say they cycle 0.5 away from the centre line of the road, to the left but of course 'left' is relative to the direction of the line The start of the journey would actually look something like this Note the 'new_x' and 'new_y' are not mathmatically correct. They're estimations for illustrative purposes.

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')

enter image description here

So the question is how do I correctly calculate new_x and new_y to create a continuous line representing a cyclists journey as offset from the centre of the road

like image 328
TheRealJimShady Avatar asked May 10 '18 14:05

TheRealJimShady


People also ask

What tool is used to draw a line parallel to an existing line at an exact distance from it AutoCAD?

Using AutoCAD, you can quickly draw a new line parallel to a given line and through a given point using the Offset command with the Through option.

How do you find the equation of a line parallel to coordinates?

To find a line that's parallel to a line and goes through a particular point, use the point's coordinates for (x1, y1) in point slope form: y - y1 = m (x - x1). Then, just plug the old line's slope in for m!


1 Answers

There is a package that provides offset calculation for splines: https://www.stat.auckland.ac.nz/~paul/Reports/VWline/offset-xspline/offset-xspline.html

Here is some very basic approximation. I purposely left the corners to be cut off since that is probably be a better approximation of how bikes will turn around the corner. Please also note that some extra steps will be needed if you need to calculate the "inward" shift:

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)

enter image description here

like image 71
Katia Avatar answered Sep 17 '22 11:09

Katia