基于点的中心创建多边形区域
Create polygon area based on center of points
我对 R 很陌生,我想创建一个函数,它需要几个点,找到这些点的中心(比如质心),然后从这些点画出分隔线点组,该中心位于点的中间。类似于制作馅饼的切片:我们从中心划分馅饼,以获得相等数量的部分。
我用来寻找中心和绘图本身的代码如下:
distance <- function(points1, points2) {
distanceMatrix <- matrix(NA, nrow=dim(points1)[1], ncol=dim(points2)[1])
for(i in 1:nrow(points2)) {
distanceMatrix[,i] <- sqrt(rowSums(t(t(points1)-points2[i,])^2))
}
distanceMatrix
}
find_cluster <- function(x, centers, distFun, nItter=10) {
clusterHistory <- vector(nItter, mode="list")
centerHistory <- vector(nItter, mode="list")
for(i in 1:nItter) {
distsToCenters <- distFun(x, centers)
clusters <- apply(distsToCenters, 1, which.min)
centers <- apply(x, 2, tapply, clusters, mean)
# Saving history
clusterHistory[[i]] <- clusters
centerHistory[[i]] <- centers
}
list(clusters=clusterHistory, centers=centerHistory)
}
a3=as.matrix(test)
centers <- a3[sample(nrow(a3), 5),]
theResult <- find_cluster(a3, centers, myEuclid, 10)
剧情:
plot(a3, col=theResult$clusters[[i]],
main=paste("itteration:", i), xlab="x", ylab="y")
points(theResult$centers[[i]],
cex=1, pch=19, col=1:nrow(theResult$centers[[i]]))
所以函数应该这样做:
- 取输入中心
- 找到这些点(即聚类中心)的质心(或质点)
- 从主要中心(即质心)画线或多边形,以便将集群分开
测试数据集可以在pastebin. An example of what I would like to have is here(及以下)找到:
你可以这样做(n
是你想要的簇数)
dat <- read.table(file="test.txt", header=T)
separateClusts <- function(n, dat) {
## Cartesian to polar (is there a function for this?)
cart2pol <- function(x, y, deg = FALSE) {
r <- sqrt(x^2 + y^2)
theta <- atan(y / x)
theta[x < 0] <- theta[x < 0] + pi
theta[x >= 0 & y < 0] <- theta[x >= 0 & y < 0] + 2*pi
if (deg) theta <- theta * 180/pi
out <- cbind(r, theta)
names(out) <- c("r", "theta")
return( out )
}
## Get clusters
clusts <- kmeans(dat, n)
centers <- clusts$centers
## Center of mass of clusters
com <- matrix(colMeans(centers), ncol=2)
## Order them
cent <- t(t(centers) - c(com)) # center
pol <- cart2pol(cent[,1], cent[,2])
ord <- sort(pol[,2], index=T)$ix
ordered <- as.data.frame(centers[ord, ])
## Get midpoints
mids <- with(ordered, {
data.frame(
xmid=c(x[-1] - x[-length(x)], x[1]-x[length(x)])/2 + x,
ymid=c(y[-1] - y[-length(y)], y[1]-y[length(y)])/2 + y
)
})
## Plot
plot(dat, col=clusts$cluster)
points(com, col="blue", pch=16, cex=2)
points(centers, col="red", pch=16, cex=2)
points(mids, col="orange", pch=16, cex=2)
## Draw line segments
ms <- (tmp <- t(t(mids) - c(com)))[,2] / tmp[,1]
for (i in 1:nrow(mids))
segments(com[,1], com[,2],
com[,1] + (s <- sign(mids$x[i]-com[,1]))*5,
com[,2] + s*ms[i]*5, col="orange", lwd=2)
}
separateClusts(5, dat)
红点是簇中心,橙色点是连续中心之间的中点。中心的顺序是通过将它们转换为极坐标并使用角度来确定的。
我对 R 很陌生,我想创建一个函数,它需要几个点,找到这些点的中心(比如质心),然后从这些点画出分隔线点组,该中心位于点的中间。类似于制作馅饼的切片:我们从中心划分馅饼,以获得相等数量的部分。
我用来寻找中心和绘图本身的代码如下:
distance <- function(points1, points2) {
distanceMatrix <- matrix(NA, nrow=dim(points1)[1], ncol=dim(points2)[1])
for(i in 1:nrow(points2)) {
distanceMatrix[,i] <- sqrt(rowSums(t(t(points1)-points2[i,])^2))
}
distanceMatrix
}
find_cluster <- function(x, centers, distFun, nItter=10) {
clusterHistory <- vector(nItter, mode="list")
centerHistory <- vector(nItter, mode="list")
for(i in 1:nItter) {
distsToCenters <- distFun(x, centers)
clusters <- apply(distsToCenters, 1, which.min)
centers <- apply(x, 2, tapply, clusters, mean)
# Saving history
clusterHistory[[i]] <- clusters
centerHistory[[i]] <- centers
}
list(clusters=clusterHistory, centers=centerHistory)
}
a3=as.matrix(test)
centers <- a3[sample(nrow(a3), 5),]
theResult <- find_cluster(a3, centers, myEuclid, 10)
剧情:
plot(a3, col=theResult$clusters[[i]],
main=paste("itteration:", i), xlab="x", ylab="y")
points(theResult$centers[[i]],
cex=1, pch=19, col=1:nrow(theResult$centers[[i]]))
所以函数应该这样做:
- 取输入中心
- 找到这些点(即聚类中心)的质心(或质点)
- 从主要中心(即质心)画线或多边形,以便将集群分开
测试数据集可以在pastebin. An example of what I would like to have is here(及以下)找到:
你可以这样做(n
是你想要的簇数)
dat <- read.table(file="test.txt", header=T)
separateClusts <- function(n, dat) {
## Cartesian to polar (is there a function for this?)
cart2pol <- function(x, y, deg = FALSE) {
r <- sqrt(x^2 + y^2)
theta <- atan(y / x)
theta[x < 0] <- theta[x < 0] + pi
theta[x >= 0 & y < 0] <- theta[x >= 0 & y < 0] + 2*pi
if (deg) theta <- theta * 180/pi
out <- cbind(r, theta)
names(out) <- c("r", "theta")
return( out )
}
## Get clusters
clusts <- kmeans(dat, n)
centers <- clusts$centers
## Center of mass of clusters
com <- matrix(colMeans(centers), ncol=2)
## Order them
cent <- t(t(centers) - c(com)) # center
pol <- cart2pol(cent[,1], cent[,2])
ord <- sort(pol[,2], index=T)$ix
ordered <- as.data.frame(centers[ord, ])
## Get midpoints
mids <- with(ordered, {
data.frame(
xmid=c(x[-1] - x[-length(x)], x[1]-x[length(x)])/2 + x,
ymid=c(y[-1] - y[-length(y)], y[1]-y[length(y)])/2 + y
)
})
## Plot
plot(dat, col=clusts$cluster)
points(com, col="blue", pch=16, cex=2)
points(centers, col="red", pch=16, cex=2)
points(mids, col="orange", pch=16, cex=2)
## Draw line segments
ms <- (tmp <- t(t(mids) - c(com)))[,2] / tmp[,1]
for (i in 1:nrow(mids))
segments(com[,1], com[,2],
com[,1] + (s <- sign(mids$x[i]-com[,1]))*5,
com[,2] + s*ms[i]*5, col="orange", lwd=2)
}
separateClusts(5, dat)
红点是簇中心,橙色点是连续中心之间的中点。中心的顺序是通过将它们转换为极坐标并使用角度来确定的。