R中多边形边缘的样本点

4
如果我在R中有一个spatialpolygons对象,我该如何生成一组n个点,使其位于该多边形的边缘上?
起初我想只从多边形顶点进行采样,但似乎有时会出现没有顶点的拉伸部分,因为多边形边缘是一条直线...
2个回答

3
一个简单的解决方案是使用sf包中的st_segmentize(),它会在直线上添加点,然后沿着这些更细的点进行采样。 st_segmentize()有一个参数dfMaxLength,它定义了允许沿线行进的最大距离。您设置得越小,就会得到更多的点。它至少应该与任何两个点之间的最小距离一样小。
library(sf)
library(tidyverse)

## original form
poly <- st_polygon(x=list(cbind(x=c(1,2,3,1),y=c(1,2,1,1))))

# segmentize, then convert to points
poly_points <- st_segmentize(poly, dfMaxLength = 0.1) %>% 
  st_coordinates() %>% 
  as.data.frame() %>% 
  select(X, Y) %>% 
  st_as_sf(coords = c("X", "Y"))

## plot: you can just use sample() now on your point dataset
plot(poly, reset = FALSE, main = "segmentize (black point), then sample 5 (red points)")
plot(poly_points, reset = FALSE, add = TRUE)
plot(poly_points[sample(1:nrow(poly_points), size = 5),], add = TRUE, col = 2, pch = 19)

enter image description here

获取任意两点之间的最小距离(注意避免零):
 poly %>% 
  st_coordinates() %>% 
  as.data.frame() %>% 
  st_as_sf(coords = c("X", "Y")) %>% 
  st_distance() %>%  c() %>% 
  unique() %>% 
  sort

2
假设您想在周长上绘制点,我会将其分为两部分:

P(边缘e上的点p) = P(点p | 边缘e) * P(边缘e)

其中P(边缘e)与其长度成比例。因此,首先随机选择一条边,然后在其上随机选择一个点。

这是一个三角形示例:

  poly <- Polygon(list(x=c(1,2,3,1),y=c(1,2,1,1)))

我们将计算边长:

  require(gsl) #for fast hypot function
  xy <- poly@coords
  dxy <- diff(xy)
  h <- hypot(dxy[,"x"], dxy[,"y"])

并随机选择一侧:

  e <- sample(nrow(dxy), 1, probs=h)

然后在该边缘上绘制一个点:

  u <- runif(1)
  p <- xy[e,] + u * dxy[e,]

将整个内容包装在一个函数中,我们有:

  rPointOnPerimeter <- function(n, poly) {
    xy <- poly@coords
    dxy <- diff(xy)
    h <- hypot(dxy[,"x"], dxy[,"y"])

    e <- sample(nrow(dxy), n,replace=TRUE, prob=h)

    u <- runif(n)
    p <- xy[e,] + u * dxy[e,]

    p
  }

带有演示:

plot( rPointOnPerimeter(100,poly) )

这段代码示例是Python版本的吗?我不懂R语言。 - machen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接