簡體   English   中英

最小凸多邊形的質心

[英]Centroid of the minimum convex polygon

我有一個物種在一個地區的發生點。 我想計算包含該物種所有出現點的最小凸多邊形的質心。 誰能告訴我如何在 R 中做到這一點?

首先請注意,凸多邊形的質心不等於其頂點的質心,除非在特殊情況下,例如當多邊形是三角形時。 (如果您實際上想要頂點的質心而不是多邊形的質心,那么根據下面計算的chsapply(ch[c("x", "y")], mean) colMeans(X[ix, ])根據上一節中計算的ix 。)

為了使質心將凸包多邊形的區域划分為三角形(Delaunay 三角化),計算每個三角形的質心和面積,然后使用這些面積作為權重對質心進行加權平均。

voronoi.mosaic中的 voronoi.mosaic 將提供三角形頂點和三角形面積的索引。 在其 output p1中, p2p3是三角形頂點的輸入X的索引,而area是相應的區域。 由此我們計算xy作為三角形質心的坐標。 然后在他們計算之后的行中,我們采用他們的加權平均值來獲得整體質心cen 最后我們 plot 一切。

library(tripack)

set.seed(43)

# test data
n <- 25
X <- matrix(rnorm(2 * n), ncol = 2)

vm <- voronoi.mosaic(xy.coords(X))
x <- with(vm, rowMeans(cbind(X[p1, 1], X[p2, 1], X[p3, 1])))
y <- with(vm, rowMeans(cbind(X[p1, 2], X[p2, 2], X[p3, 2])))
cen <- apply(cbind(x, y), 2, weighted.mean, vm$area)  # centroid of conv hull

tri <- tri.mesh(xy.coords(X)) # triangularization
ch <- convex.hull(tri) # ch$i gives indexes of vertices of conv hull

# plot points & Delauney triangularization, conv hull (red) and centroid (red)
plot(tri)
lines(X[c(ch$i, ch$i[1]), ], col = "red", lwd = 2)
points(cen[1], cen[2], col = "red", pch = 20, cex = 2)

(劇情后續) 截屏

德爾迪爾

tripack 的替代方法是使用 deldir package 來獲取質心。 deldir function 在其 output del.wts中提供了對每個輸入點進行加權的數量,使得它們的加權平均值是質心。 cen.dd等於上面cen的浮點近似值,plot 也類似。 chull來自 R 的基礎。

library(deldir)

dd <- deldir(xy.coords(X))
cen.dd <- with(dd$summary, sapply(list(x, y), weighted.mean, del.wts))

# plot points & triangularization, compute & plot conv hull (red) and 
#  centroid (red)
plot(dd, wlines = "triang")
ix <- chull(X)
lines(X[c(ix, ix[1]), ], col = "red", lwd = 2)
points(cen.dd[1], cen.dd[2], col = "red", pch = 20, cex = 2)

更新

已完全修改答案。

正如G. Grothendieck指出的那樣,多邊形的質心不是頂點的平均值。 凸多邊形質心的公式並不難,我還沒有看到它們發布:

set.seed(42)
pts <- matrix(rnorm(40, 5, 1), 20, 2)
plot(pts)
# The centroid of the data points
points(t(pts.mn), pch=8, col="darkgreen", cex=2)
verts <- chull(pts)
poly <- pts[verts,]
polygon(poly)
cent <- colMeans(poly)
# The centroid of the vertices
points(t(cent), pch=8, col="blue", cex=2)

現在是面積和質心的公式。 這些假設多邊形是閉合的(第一行與最后一行相同)並且點逆時針遍歷多邊形:

poly <- rbind(poly, poly[1, ])
n <- nrow(poly)
x <- rev(poly[, 1])
y <- rev(poly[, 2])
i <- 1:(n-1)
# Area of the polygon
A <- sum(c(x[i] * y[i+1] - x[i+1] * y[i])) / 2
# Coordinates of the centroid
Cx <- sum((x[i] + x[i+1]) * (x[i] * y[i+1] - x[i+1] * y[i])) / (6 * A)
Cy <- sum((y[i] + y[i+1]) * (x[i] * y[i+1] - x[i+1] * y[i])) / (6 * A)
# The centroid of the polygon
points(Cx, Cy, pch=8, col="red", cex=2)

凸包

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM