给定多个顶点的2D坐标,我想计算相应多边形的内角。
这是一个数据框,其中包含一些多边形及其顶点的坐标。问题是顶点没有排序。
structure(list(x = c(173L, 173L, 185L, 190L, 231L, 267L, 185L,
190L, 233L, 260L, 190L, 231L, 260L, 230L, 230L, 172L, 233L, 230L,
231L, 267L, 185L, 172L, 233L, 231L, 231L), y = c(299L, 299L,
321L, 360L, 361L, 377L, 321L, 360L, 363L, 309L, 360L, 361L, 309L,
322L, 322L, 378L, 363L, 322L, 391L, 377L, 321L, 378L, 363L, 391L,
361L), polygonID = c(2L, 4L, 5L, 3L, 6L, 7L, 2L, 5L, 7L, 6L, 2L,
3L, 4L, 5L, 6L, 2L, 3L, 4L, 3L, 6L, 4L, 3L, 6L, 7L, 5L)), row.names = c(1L,
2L, 3L, 4L, 5L, 6L, 7L, 9L, 10L, 12L, 13L, 14L, 15L, 16L, 17L,
19L, 20L, 21L, 24L, 25L, 27L, 29L, 30L, 31L, 34L), class = "data.frame")
从本质上讲,我会从一个顶点到另一个顶点来计算边缘/矢量,并使用它们来计算内角。但是我不清楚如何以算法方式进行此操作。任何提示都非常感谢。
答案 0 :(得分:2)
这是一个镜头:
shp <- structure(list(x = c(173L, 173L, 185L, 190L, 231L, 267L, 185L,
190L, 233L, 260L, 190L, 231L, 260L, 230L, 230L, 172L, 233L, 230L,
231L, 267L, 185L, 172L, 233L, 231L, 231L), y = c(299L, 299L,
321L, 360L, 361L, 377L, 321L, 360L, 363L, 309L, 360L, 361L, 309L,
322L, 322L, 378L, 363L, 322L, 391L, 377L, 321L, 378L, 363L, 391L,
361L), polygonID = c(2L, 4L, 5L, 3L, 6L, 7L, 2L, 5L, 7L, 6L,
2L, 3L, 4L, 5L, 6L, 2L, 3L, 4L, 3L, 6L, 4L, 3L, 6L, 7L, 5L)), class = "data.frame",
row.names = c(NA, -25L))
aa <- shp[ shp$polygonID == 2, ]
aa <- aa[ chull(aa[,1:2]), ]
aa
# x y polygonID
# 7 185 321 2
# 1 173 299 2
# 16 172 378 2
# 11 190 360 2
现在aa
是一个4点多边形,按顺时针方向排序。现在让我们对一些计算进行硬编码:
indm1 <- c(ind[-1], ind[1])
indp1 <- c(ind[length(ind)], ind[-length(ind)])
angles <- ((atan2(aa$y[indm1] - aa$y[ind], aa$x[indm1] - aa$x[ind]) -
atan2(aa$y[indp1] - aa$y[ind], aa$x[indp1] - aa$x[ind])) * 180 / pi) %% 360
cbind(indm1,ind,indp1)
# indm1 ind indp1
# [1,] 2 1 4
# [2,] 3 2 1
# [3,] 4 3 2
# [4,] 1 4 3
angles
# [1] 158.69530 29.33568 44.27478 127.69424
让我们看看(最初,我感到困惑的是,它在视觉上是不相关的,直到我意识到长宽比已经关闭,{ergo asp=1
)。
plot(y~x, data=aa, type='l', asp=1)
with(aa, text(x-5, y, seq_len(nrow(aa)), col="red"))
with(aa, text(x+5, y, round(angles, 0)))
好的,让我们尝试将其正式化:
getangles <- function(aa) {
aa <- aa[chull(aa[,1:2]),]
ind <- seq_len(nrow(aa))
indm1 <- c(ind[-1], ind[1])
indp1 <- c(ind[length(ind)], ind[-length(ind)])
((atan2(aa$y[indm1] - aa$y[ind], aa$x[indm1] - aa$x[ind]) -
atan2(aa$y[indp1] - aa$y[ind], aa$x[indp1] - aa$x[ind])) * 180 / pi) %% 360
}
by(shp, shp$polygonID, getangles)
# shp$polygonID: 2
# [1] 158.69530 29.33568 44.27478 127.69424
# ------------------------------------------------------------
# shp$polygonID: 3
# [1] 130.91438 136.39718 133.60282 57.42594 81.65967
# ------------------------------------------------------------
# shp$polygonID: 4
# [1] 29.98564 54.83259 119.88349 155.29828
# ------------------------------------------------------------
# shp$polygonID: 5
# [1] 92.74183 81.42121 98.70294 87.13402
# ------------------------------------------------------------
# shp$polygonID: 6
# [1] 72.44870 111.95989 136.46880 157.38014 61.74247
# ------------------------------------------------------------
# shp$polygonID: 7
# [1] 71.70548 64.66388 43.63064
(舍入/模数可能存在一些问题,我留给您来美化和验证其他问题。)