RT。求平面上点集的凸包。
1. GrahamScan算法,《算法导论》上的例子,先找到y最小的点O,以O建立极坐标,其它点按极角排序后再从头开始扫描(配合stack实现)。
2.BruteForce算法,依赖定理:如果一个点在平面上某三个点组成的三角形内,那么这个点不可能是凸包上的点。
所以暴力的思路是平面上的点每4个进行枚举,并判断是否满足定理,若满足,则删除这个点继续找;一直找到没有满足定理的点为止。。
3.DivideAndConquer思路:有很多种,这里我实现的只是严格意义上最后一步的分治,基于递归的分治暂时还没想明白;
思路即:首先找点集x-坐标的中位数(排序法O(nlogn),或随机法更快O(n)),将每次将点集分为左右两部分。
分别递归求左右部分的凸包,这里我就是用Graham求的凸包。这样会过滤掉许多内部点,将左边凸包上的点序列称为left,右边凸包上的点序列称为right。
right按顺时针和逆时针分成两部分right1和right2(以y最大和y最小的点为界),得到这三个极角有序列表后,合并这三个有序表为一个list(merge的操作O(n),原理类似归排的merge)
对新list直接进行GrahamScan,只需过滤掉极少的点即可得到大凸包。
ConvexHull.py:
#coding=utf-8
import math
import numpy
import pylab as pl
#画原始图
def drawGraph(x,y):
pl.figure(1)
pl.subplot(131) #1
pl.title("ConvexHull-GrahamScan")
pl.xlabel("x axis")
pl.ylabel("y axis")
pl.plot(x,y,'ro')
pl.subplot(132) #2
pl.title("ConvexHull-BruteForce")
pl.xlabel("x axis")
pl.ylabel("y axis")
pl.plot(x,y,'ro')
pl.subplot(133) #3
pl.title("ConvexHull-DivideConquer")
pl.xlabel("x axis")
pl.ylabel("y axis")
pl.plot(x,y,'ro')
#画凸包
def drawCH(CHQ):
x