凸包问题的蛮力算法及python实现
蛮力法的基本思想是先用排除法确定凸包的顶点,然后按逆时针顺序输出这些顶点。在判断点P是不是凸包上的顶点时,有如下性质:
给定平面点集S,P,Pi,Pj,Pk是S中四个不同的点,如果P位于Pi,Pj,Pk组成的三角形内部或边界上,则P不是S的凸包顶点。
那么如何判断点P在三角形内部或边界上?给定平面两点AB,直线方程g(A,B,P)=0时,P位于直线上,g(A,B,P)>0和g(A,B,P)<0时,P分别位于直线的两侧。
判断点P在三角形内部或边界上只需依次检查P和三角形的每个顶点是否位于三角形另外两个顶点确定的直线的同一侧,即判断:
t1=g(pj,pk,p)*g(pj,pk,pi)>=0 ,
t2=g(pi,pk,p)*g(pi,pk,pj)>=0,
t3=g(pj,pi,p)*g(pj,pi,pk)>=0
是否同时成立
凸包问题的蛮力算法伪代码如下:
BruteForce(S):
输入:平面n个点的集合S
输出:按逆时针顺序输出S的凸包的所有顶点
If n=3
Then 以逆时针顺序输出S的顶点,算法结束
找到S中纵坐标最小的点P,该点一定位于凸包上
For S中任意三点Pi,Pj,Pk Do
If Pi,Pj,Pk 一点位于其他两点与P构成的三角形内
Then 删除该点
找出S中横坐标最小的点A和横坐标最小的点B
将S划分问直线AB上方点集SU,直线AB下方点集SL,A,B两点属于SL
将SL按横坐标递增排序,SU按横坐标递减排序
顺序输出SL,SU
首先随机生成点集S
import random
import itertools
def generate_num(n):
random_list = list(itertools.product(range(1, 100), range(1, 100)))
lists=random.sample(random_list, n)
return lists
- 判断点P在三角形内部或边界上,即判断点P是否在凸包上
- 在具体的判断过程中,尤其时坐标点比较密集的情况下,还有有三种比较特殊的情况
- 组成直线的两点垂直于x轴
- 除点P外其余三点在一条直线上时,不应删除点P,因为此时点P可能时凸包上的点
- 除点P外其余三点在一条直线上且垂直于x轴时,不应删除点P,因为此时点P可能时凸包上的点