You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中绘制quickhull算法(convhulln函数)生成的凸包及一致性验证

Great question! Let's tackle this from two angles: first, whether chull and convhulln produce the same convex hull for 2D data, and second, how to plot the convex hull generated by convhulln.

Are chull and convhulln results consistent?

For 2D data, yes—both functions are based on the QuickHull algorithm, so they'll identify exactly the same set of convex hull vertices. The only difference is how they return the results:

  • chull (from base R) returns a vector of vertex indices sorted in counter-clockwise order, starting from the rightmost point.
  • convhulln (from the geometry package) is designed for n-dimensional data, so it returns a matrix ($hull) where each row represents a "face" of the convex hull. In 2D, each face is just a line segment, so each row contains the indices of two vertices that form an edge of the hull.

How to plot the convex hull from convhulln

Since convhulln returns edges instead of an ordered list of vertices, we need to extract the unique vertices first, then sort them into a closed polygon (just like chull does). Here's a step-by-step implementation:

Step 1: Generate data and compute the convex hull

library(geometry)
set.seed(123) # Make results reproducible
x1 <- rnorm(100, 0.8, 0.3)
y1 <- rnorm(100, 0.8, 0.3)

# Compute convex hull with convhulln (the "FA" flag returns faces and area)
ConVexHull <- convhulln(cbind(x1, y1), "FA")

Step 2: Extract and order convex hull vertices

# Get all unique vertex indices from the hull edges
hull_vertex_indices <- unique(as.vector(ConVexHull$hull))

# Sort these vertices into a closed, counter-clockwise order (using chull for simplicity)
ordered_indices <- chull(x1[hull_vertex_indices], y1[hull_vertex_indices])
ordered_indices <- c(hull_vertex_indices[ordered_indices], hull_vertex_indices[ordered_indices[1]])

Step 3: Plot the data and convex hull

# Set plot parameters for cleaner output
par(tck = 0.02, mgp = c(1.7, 0.3, 0))

# Plot the raw data points
plot(x1, y1, type = "p", pch = 1, col = "black", xlim = range(x1), ylim = range(y1))

# Draw the convex hull from convhulln
lines(x1[ordered_indices], y1[ordered_indices], col = "darkred", lwd = 2)

Step 4: Compare with chull (optional)

To confirm the results match, we can overlay the chull convex hull:

# Plot chull's convex hull for comparison
hpts_chull <- chull(x1, y1)
hpts_chull <- c(hpts_chull, hpts_chull[1])
lines(x1[hpts_chull], y1[hpts_chull], col = "steelblue", lty = 2, lwd = 1)

# Add a legend
legend("topright", 
       legend = c("convhulln Hull", "chull Hull"),
       col = c("darkred", "steelblue"),
       lty = c(1, 2),
       lwd = c(2, 1))

Wrapping it up

If you're working strictly with 2D data, chull is more straightforward for plotting. But if you need to handle higher-dimensional data later, convhulln is the way to go—and as we've seen, its 2D results align perfectly with chull.

You can also wrap the convhulln plotting logic into a reusable function, just like your Plot_ConvexHull function:

Plot_ConvexHull_convhulln <- function(xcoord, ycoord, lcolor, lwd = 1) {
  conv_hull <- convhulln(cbind(xcoord, ycoord), "FA")
  hull_vertices <- unique(as.vector(conv_hull$hull))
  ordered_idx <- chull(xcoord[hull_vertices], ycoord[hull_vertices])
  ordered_idx <- c(hull_vertices[ordered_idx], hull_vertices[ordered_idx[1]])
  lines(xcoord[ordered_idx], ycoord[ordered_idx], col = lcolor, lwd = lwd)
}

# Usage example
par(tck = 0.02, mgp = c(1.7, 0.3, 0))
plot(x1, y1, type = "p", pch = 1, col = "black", xlim = range(x1), ylim = range(y1))
Plot_ConvexHull_convhulln(xcoord = x1, ycoord = y1, lcolor = "darkgreen", lwd = 2)

内容的提问来源于stack exchange,提问作者Nile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:48