一般来说凸包问题有三种解决方式:蛮力法、Graham-Scan法和分治法。关于蛮力法和分治法的python实现可参考博文:蛮力法、分治法,博主写的很清晰。
这里主要介绍Graham-Scan算法的实现,网上的Graham-Scan算法python实现很多,如这篇博文,原理和实现都很清晰,但是当时使用这个程序测试很大的数据量(如超过1000个点以上)时会报如下错误。
程序报错说栈空,应该是数据点很多的时候多点共线,栈内元素连续弹出,因此基于这篇博文改了一些代码(主要是103行和104行),实现代码如下:
import matplotlib.pyplot as plt
import math
import time
import numpy as np
start_t = time.clock()
# points中纵坐标最小点的索引,若有多个则返回横坐标最小的点
def get_bottom_point(points):
min_index = 0
n = len(points)
for i in range(0, n):
if points[i][1] < points[min_index][1] or (
points[i][1] == points[min_index][1] and points[i][0] < points[min_index][0]):
min_index = i
return min_index
# 按照与中心点的极角进行排序,余弦,center_point: 中心点
def sort_polar_angle_cos(points, center_point):
n = len(points)
cos_value = []
rank = []
norm_list = []
for i in range(0, n):
point_ = points[i]
point = [point_[0] - center_point[0], point_[1]