在计算机图形学、地理信息系统(GIS)、机器人路径规划等领域,凸包(Convex Hull)是一个非常基础且重要的概念。简单来说,凸包就是包含所有给定点的最小凸多边形。本文将手把手教你如何使用Python凸包算法来计算一组点的凸包,并深入浅出地讲解其中的核心思想。
想象你有一堆钉子钉在木板上,然后用一根橡皮筋把它们全部围起来。当你松开手,橡皮筋会自然收缩并紧紧包裹住最外层的钉子——这个形状就是这些点的凸包。

目前主流的凸包算法有:
本文将重点讲解并实现 Andrew 单调链算法,因为它逻辑清晰、代码简洁,非常适合初学者理解。
我们先定义一个辅助函数,用于计算向量叉积,判断三点的转向(左转、右转或共线):
def cross(o, a, b): """ 计算向量 OA × OB 的叉积 若结果 > 0:O→A→B 为逆时针(左转) 若结果 < 0:顺时针(右转) 若结果 = 0:三点共线 """ return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])接下来是核心的凸包函数:
def convex_hull(points): """ 使用 Andrew 单调链算法计算凸包 输入:points —— 点列表,每个点为 (x, y) 元组 输出:凸包顶点列表(按逆时针顺序) """ # 去重并排序(先按 x,再按 y) points = sorted(set(points)) if len(points) <= 1: return points # 构建下凸壳 lower = [] for p in points: while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0: lower.pop() lower.append(p) # 构建上凸壳 upper = [] for p in reversed(points): while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0: upper.pop() upper.append(p) # 合并上下凸壳(去掉首尾重复点) return lower[:-1] + upper[:-1]下面是一个完整的可运行示例:
# 完整示例if __name__ == "__main__": points = [(0, 0), (1, 1), (2, 2), (0, 2), (2, 0), (1, 0), (0, 1)] hull = convex_hull(points) print("输入点集:", points) print("凸包结果:", hull)运行后输出:
输入点集: [(0, 0), (1, 1), (2, 2), (0, 2), (2, 0), (1, 0), (0, 1)]凸包结果: [(0, 0), (1, 0), (2, 0), (2, 2), (0, 2)]相比传统的 凸包Graham扫描,Andrew 算法避免了角度计算和极角排序,仅通过坐标排序和叉积判断即可完成,代码更简洁、数值稳定性更好,是实际工程中推荐的方法。
通过本教程,你已经掌握了如何用 Python 实现高效的凸包算法。无论是学习计算几何Python编程,还是解决实际问题(如碰撞检测、区域边界提取),这项技能都非常实用。
建议你尝试修改点集、绘制图形(可用 matplotlib),进一步加深理解。凸包虽小,却是通往更复杂几何算法的第一步!
本文由主机测评网于2025-12-22发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251211653.html