I used distm()
function in geosphere
package to calculate the distence when points and apexes are presented in coordinate system. Also, you can easily make some alternation by substitude dis <- function(x0,x1,y0,y1){sqrt((x0-x1)^2 +(y0-y1)^2)}
for distm()
.
algo.p2poly <- function(pt, poly){
if(!identical(poly[1,],poly[nrow(poly),])){poly<-rbind(poly,poly[1,])}
library(geosphere)
n <- nrow(poly) - 1
pa <- distm(pt, poly[1:n, ])
pb <- distm(pt, poly[2:(n+1), ])
ab <- diag(distm(poly[1:n, ], poly[2:(n+1), ]))
p <- (pa + pb + ab) / 2
d <- 2 * sqrt(p * (p - pa) * (p - pb) * (p - ab)) / ab
cosa <- (pa^2 + ab^2 - pb^2) / (2 * pa * ab)
cosb <- (pb^2 + ab^2 - pa^2) / (2 * pb * ab)
d[which(cosa <= 0)] <- pa[which(cosa <= 0)]
d[which(cosb <= 0)] <- pb[which(cosb <= 0)]
return(min(d))
}
Example:
poly <- matrix(c(114.33508, 114.33616,
114.33551, 114.33824,
114.34629, 114.35053,
114.35592, 114.35951,
114.36275, 114.35340,
114.35391, 114.34715,
114.34385, 114.34349,
114.33896, 114.33917,
30.48271, 30.47791,
30.47567, 30.47356,
30.46876, 30.46851,
30.46882, 30.46770,
30.47219, 30.47356,
30.47499, 30.47673,
30.47405, 30.47723,
30.47872, 30.48320),
byrow = F, nrow = 16)
pt1 <- c(114.33508, 30.48271)
pt2 <- c(114.6351, 30.98271)
algo.p2poly(pt1, poly)
algo.p2poly(pt2, poly)
Outcome:
> algo.p2poly(pt1, poly)
[1] 0
> algo.p2poly(pt2, poly)
[1] 62399.81
spatstat
package? I know they have, at least, some distance algorithms for line segment and point sets. – Fractious