Search code examples
geometrylinedistancepoint

Shortest distance from a point to a segmented line


I have a segmented line with about 80 points in 2D and a point P (X/Y) which is not on this line.

I need to know where point P' is on this line, which has the shortest distance to P.

Is there an easy way to calculate this?

EDIT:

Input files:

str(coords)
'data.frame':   80 obs. of  2 variables:
 $ x: num  2140 2162 2169 2167 2158 ...
 $ y: num  1466 1437 1412 1390 1369 ...

str(point)
'data.frame':   1 obs. of  2 variables:
 $ x: num  1778
 $ y: num  1911

Output files:

point on segmented line


Solution

  • I have the solution now...even though it is not very efficient. Perhaps someone finds this useful. I changed the coordinates of P to get a better result.

    distance <- data.frame(dist = NA)
    coordinates <- data.frame(x=NA,y=NA)
    
    coords <- data.frame(x=c(2140,2162,2169,2167,2158),y=c(1466,1437,1412,1390,1369))
    point <- data.frame(x=2130,y=1400)
    
    
    for(j in 1:(length(coords[,1]))){
      distance[2*j-1,1] <- sqrt((coords[j,1]-point[1,1])^2+(coords[j,2]-point[1,2])^2)
      coordinates[2*j-1,] <- coords[j,]
    }
    

    Calculate all perpendicular distances from point P and the coordinates of point P' which are lying on the segmented line

    for(j in 1:(length(coords[,1])-1)){
     d <- abs((coords[j+1,1]-coords[j,1])*(coords[j,2]-point[1,2])-
          (coords[j,1]-point[1,1])*(coords[j+1,2]-coords[j,2]))/
          sqrt((coords[j+1,1]-coords[j,1])^2+(coords[j+1,2]-coords[j,2])^2)
    
     t <- abs(((point[1,1]-coords[j,1])*(coords[j+1,1]-coords[j,1])+
          (point[1,2]-coords[j,2])*(coords[j+1,2]-coords[j,2]))/
          ((coords[j+1,1]-coords[j,1])^2+(coords[j+1,2]-coords[j,2])^2))
     x <- coords[j,1]+t*(coords[j+1,1]-coords[j,1])
     y <- coords[j,2]+t*(coords[j+1,2]-coords[j,2])
    
     if(min(coords$x[j],coords$x[j+1]) <= x && x <= max(coords$x[j],coords$x[j+1]) &&
        min(coords$y[j],coords$y[j+1]) <= y && y <= max(coords$y[j],coords$y[j+1])){
      if(coords[j,] != c(x,y) && coords[j+1,] != c(x,y)){
       distance[2*j,1] <- d
       coordinates[2*j,] <- c(x,y)
      }
     }
    }
    

    Position of minimal distance:

    p <- which(distance==min(distance, na.rm=TRUE))
    coordinates[p,]