Plot convex hull given by quickhull algorithm in R (convhulln function)

馋奶兔 提交于 2019-12-04 19:09:32

Reproducible example:

library(geometry)

set.seed(0)

x1 <- rnorm(100, 0.8, 0.3)
y1 <- rnorm(100, 0.8, 0.3)

xdf <- data_frame(x1, y1)

(ConVexHull <- convhulln(cbind(x1,y1), "FA"))
## $hull
##      [,1] [,2]
## [1,]   63   59
## [2,]   10   53
## [3,]   10   63
## [4,]   80   59
## [5,]   80   15
## [6,]   37   53
## [7,]   37   15
## 
## $area
## [1] 4.258058
## 
## $vol
## [1] 1.271048

Those are the from/to edge pairs in $hull, so we shall build said set of vertex pairs:

data.frame(
  do.call(
    rbind,
    lapply(1:nrow(ConVexHull$hull), function(i) {
      rbind(xdf[ConVexHull$hull[i,1],], xdf[ConVexHull$hull[i,2],])
    })
  )
) -> h_df

and, prove they are, indeed, correct:

ggplot() +
  geom_point(data=xdf, aes(x1, y1), color="red") +
  geom_point(data=h_df, aes(x1, y1), shape=21, fill=NA, color="black", size=3)

They are, however, not in "order":

ggplot() +
  geom_point(data=xdf, aes(x1, y1), color="red") +
  geom_point(data=h_df, aes(x1, y1), shape=21, fill=NA, color="black", size=3) +
  geom_path(data=h_df, aes(x1, y1), color="blue")

So, we need to get them in order (sort them) if you want to have a path or polygon around the points (which was the meaning of the comment / link by the anonymous user).

We can sort them clockwise:

h_df <- h_df[order(-1 * atan2(h_df$y1 - mean(range(h_df$y1)), h_df$x1 - mean(range(h_df$x1)))),]
h_df <- rbind(h_df, h_df[1,])

(remove the -1 for the reverse)

and, we have a lovely outer wrapper:

ggplot() +
  geom_point(data=xdf, aes(x1, y1), color="red") +
  geom_point(data=h_df, aes(x1, y1), shape=21, fill=NA, color="black", size=3) +
  geom_path(data=h_df, aes(x1, y1), color="blue")

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!