minimum convex polygons

by Jamie M. Kass

When you’re working with points, be it in geographical space, environmental space, ordination space, or outer space, you often want to generate a shape that neatly connects the outside dots and contains all the points inside. This is called a minimum convex polygon (mcp), or convex hull. It is often used in niche modeling to select background points from, as you want your background points to reflect areas that the species is able to move to, and not areas that may be inaccessible.
Depending on your study, your definition of inaccessibility for the species may be in the present, or could extend far back in time. For example, if a mountain range sprung up over the time period of study and isolated your species to one side, you may consider areas on the other side accessible.
In R, the base function chull() returns the indices of your point coordinate table that make up the borders of the mcp. This is not the most intuitive product to put to use for many people, so I made a nice helper function to return a neat mcp polygon. It handles dataframes, matrices, and spatial objects too.

mcp <- function (xy) {
  # handler for spatial objects -- extracts coordinates
  if (class(xy) == "SpatialPoints" | class(xy) == "SpatialPointsDataFrame") {
    xy <- as.data.frame(coordinates(xy))
  }
  # get mcp indices
  i <- chull(xy)
  # get rows in xy for i
  xy.mcp <- xy[i,]
  # copy first row to last position to close shape
  xy.mcp <- rbind(xy.mcp[nrow(xy.mcp),], xy.mcp)
  # return polygon of mcp
  return(SpatialPolygons(list(Polygons(list(Polygon(as.matrix(xy.mcp))), 1))))
}