0

Assume I have a straight line and set of points (red):

I need the shortest distance of this set of points orthogonal to the line? I know how I can calculate the distance between one point and the closest point on the line (e.g. raster::pointDistance) but how do I make sure that it is orthogonal. Is there a way to calculate this in R?

flyingr
  • 1
  • 1
  • 1
    You cannot. The `pointDistance` function computes differences between two sets of points. You want a function that computes the distance from a point to a line which is defined by two points or by a slope and intercept. Look [here](https://stackoverflow.com/questions/35194048/using-r-how-to-calculate-the-distance-from-one-point-to-a-line), [here](https://stackoverflow.com/questions/35194048/using-r-how-to-calculate-the-distance-from-one-point-to-a-line), or [here](https://stackoverflow.com/questions/42282212/calculating-shortest-distance-from-point-to-line-defined-by-intercept-and-slope). – dcarlson Apr 03 '21 at 20:07

2 Answers2

2

Given your reference to raster::pointDistance I am assuming you are referring to geospatial data. The below shows how you can check if distance is to the line or, as you fear, to the nearest vertex defining a (poly-)line (not strictly a line in the mathematical sense).

library(terra)
pnts <- cbind(seq(1000,10000,1000), seq(1000,10000,1000))
crs <- "+proj=utm +zone=1 +datum=WGS84"
# 8 points
p <- vect(pnts[2:9, ], crs=crs)
 
# line defined by 2 vertices
line <- pnts[c(1,10), ]
line[,1] = line[,1]-500
line[,2] = line[,2]+500
x <- vect(line, type="lines", crs=crs)

plot(x)
points(x)
points(p, col="red")

distance(p, x)
#         [,1]
#[1,] 707.1068
#[2,] 707.1068
#[3,] 707.1068
#[4,] 707.1068
#[5,] 707.1068
#[6,] 707.1068
#[7,] 707.1068
#[8,] 707.1068

sqrt(2*500^2)
#[1] 707.1068

The distances are all the same, so in this case you clearly get the distance to the line, not to its vertices. You could use the same test for methods in other packages.

And you can draw the orthogonal lines like this (with terra > 1.1-14):

n <- nearest(p, x)
lines(p, n)

For lon/lat data, you can use geosphere::distLine

Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
0

I believe that this is a problem with the mathematical understanding. If you have the shortest distance to the line this distance must be the length of a line between the point and the line which is orthogonal to the line.

The length of the orthogonal line must be the same as the shortest euclidean distance between the point and the line. The problem can be reduced to the two dimensional case.

In the 2d case if the line AB is not orthogonal to the line then we can construct a right angle triangle between points A, B and C where A is out point, B is where line AB meets D and C is the forms the last point in the right angle triangle and lies along D. AC is a line orthogonal to D. AB is the hypotenuse of the triangle. So: length(AC)^{2} + length(BC)^{2} = length(AB)^{2} therefore: length(AC)^{2} < length(AB)^{2} and length(AC) < length(AB) as we must take length to be positive. Therefore there is always a shorter distance unless your line is orthogonal/perpendicular to the original line.

You can look at: https://www.wikiwand.com/en/Distance_from_a_point_to_a_line

Please let me know if I have made a mistake I'll be happy to update this.

Joel Kandiah
  • 1,465
  • 5
  • 15