在多边形边界上生成一系列等距点

Generating a sequence of equidistant points on polygon boundary

我正在寻找一个程序,它允许我沿着任意多边形的边生成一系列等距点(坐标)。

对由其顶点坐标定义的多边形成像:

poly.mat <- matrix(c(0,0,
                   0,1,
                   0.5,1.5,
                   0.5,0,
                   0,0 # last row included to close the polygon
                   ), byrow = T, ncol = 2)
colnames(poly.mat) <- c("x", "y")
plot(poly.mat, type = "l")

如果我要生成的序列的长度是n(可调),我如何生成一个序列,从(0,0)开始,等距坐标。

我已经用 geosphere 包(我相信我需要)计算了形状的周长

library(geosphere)
n <- 50 # sequence of length set to be 50
perim <- perimeter(poly.mat)
perim/n # looks like every section needs to be 8210.768 something in length

您必须自己编写代码。抱歉,没有针对每个最后作业的每个最后细节的库函数。假设每对点定义一条线段,您可以沿着每条线段生成 N 个点,如

开始 = [x开始, y开始];
结束 = [xend, yend];

xdist = ( xend - xbegin ) / nintervals;
ydist = ( yend - ybegin ) / nintervals;

那么你的分数是 [ xbegin + i * xdist, ybegin + i * ydist ]

这是我想出的解决方案。

pointDistance <- function(p1, p2){
  sqrt((p2[,1]-p1[,1])^2) + sqrt((p2[,2]-p1[,2])^2)
}

getPos <- function(shp.mat, ll){
  greaterLL <- shp.mat$cumdis > ll
  if(all(greaterLL == FALSE)) return(poly.mat[nrow(poly.mat), c("x", "y")])
  smallRow <- min(which(greaterLL)) # the smallest coordinate that has greater length
  p.start <- shp.mat[smallRow-1, c("x","y")]
  p.end <- shp.mat[smallRow, c("x","y")]
  cumVal <- shp.mat$cumdis[smallRow]
  prop <- (ll-shp.mat$cumdis[smallRow-1])/(shp.mat$cumdis[smallRow]-shp.mat$cumdis[smallRow-1])

  p.start + (prop)* (p.end-p.start)
}

# shp1
poly.mat <- matrix(c(0,0,
                 0,1,
                 0.5,1.5,
                 0.5,0,
                 0,0
),byrow = T, ncol = 2)
colnames(poly.mat) <- c("x", "y")
poly.mat <- as.data.frame(poly.mat)


# Main fun
pointsOnPath <- function(shp.mat, n){

dist <- vector(mode = "numeric", length = nrow(shp.mat)-1)

for(i in 2:nrow(shp.mat)){
  dist[i] <- pointDistance(p1 = shp.mat[i,], p2 = shp.mat[i-1,])
}
shp.mat$dist <- dist
shp.mat$cumdis <- cumsum(shp.mat$dist)


dis <- matrix(seq(from = 0, to = max(shp.mat$cumdis), length.out = n+1), ncol = 1)

out <- lapply(dis, function(x) getPos(shp.mat = shp.mat, ll = x))
out <- do.call("rbind", out)
out$dis <- dis

out[-nrow(out),]
}

df <- pointsOnPath(shp.mat = poly.mat, 5)

# Plot
plot(poly.mat$x, poly.mat$y, type = "l", xlim = c(0,1.5), ylim = c(0,1.5))
points(df$x, df$y, col = "red", lwd = 2)

代码还有改进的余地,但应该return正确的结果