定义
在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,…Xn)的凸组合来构造.
在二维欧几里得空间中,凸包可想象为一条刚好包著所有点的橡皮圈。
用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点。
————转自百度百科。
给一张图应该就能懂了:
求解
目前比较常见的解法是Graham 扫描法。
在讲这个方法之前,先来解释一个东西:
极角排序
在平面内取一个定点O,叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向)。
对于平面内任何一点M,用ρ表示线段OM的长度(有时也用r表示),θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标。
那么给定平面上的一些点,把它们按照一个选定的中心点排成顺(逆)时针。
实现有两种:
1.用cmath库自带的atan2函数求解。
atan2(y,x)返回的是点 (x,y) ( x , y ) 与x轴正方向的夹角正切值。
bool cmp(node a,node b){
return atan(a.y,a.x)-atan(b.y,b.x)<eps?a.x<b.x:atan(b.y,b.x)-atan(a.y,a.x)>eps;
}
2.利用叉积得到其相对位置。
看看代码应该能懂。
bool cmp2(node a,node b){
return a*b>0;
}
讲完了继续
Graham 扫描法有以下几个步骤:
1.找到所有点中最下面的点