1、首先,凸包是啥:
若是在二維平面上,則一般的,給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有的點。
2、那麼,如何通過某種演算法求二維平面上的凸包呢?
有graham掃瞄法(graham scan algorithm),複雜度o(nlogn)。
話不多說,先上當年大佬的**……
呃,可以看到,這個標題是非常的酷嗷,對於有限平面點集的凸包計算的高效演算法,劃重點。
給乙個平面點集s,標號為s1~sn,據說我們經常對找它的凸包感興趣(真的嗎……我怎麼從來沒感興趣過……)
然後graham教授就給了我們一種炫酷的五步法,來求凸包。
第一步:
目標是找個在凸包內部的點p。
我們對集合s三個點三個點進行檢測,檢測它們是否共線:
若共線,扔掉中點;
若不共線,就選這三個點所組成的三角形的質心作為點p。
第二步:
以p為原點,任意乙個方向為θ=0軸,建立乙個極座標系;
對集合s中的每個點si,都按這個座標系表示一下它們的座標。
第三步:
現在每個點都有座標 r i ∠ θ i ,我們對這些點,按照θ的公升序進行排序。
第四步:
如果有某兩個點的角度相等,就刪掉r較小的那個點,因為它顯然不可能是凸包邊界上的點。
另外呢,所有r=0的,也可以刪了,反正也impossible。
then,重新給還存在著的點編號,新的集合記為s'。
第五步:
對於s'中連續的三個點k,k+1,k+2,如圖2,有兩種可能:
1)α + β ≥ π,看圖,就很容易知道,這個點k+1,顯然不可能是凸包邊界上的點了;
回到步驟五,重新選擇點k-1,k,k+2作為新的三個點;
2)α + β
相當於往前進。
原檔案:
3、那麼放到程式中,具體如何實現呢?
我們保留「對於三個點,判斷角α、β和是否小於180度,並且進行相應的前進退後」的思想,不過對於選取原點的方法進行一定的修改。
①找到點集s中縱座標最小的點(如果y座標相同,則選其中橫座標最小的),作為原點p0。
②計算其他所有點的輻角,並且將他們按從小到大排序,如果遇到輻角相同的一些點,則按與原點距離從小到大排序,記為p1~pn。
③建棧,入棧p0,p1,p2;
④選取乙個點pi(i初始值為3),前往步驟⑤;
⑥獲得棧頂點和次棧頂點pk,pk-1,
進行判定:如果 pk-1 -> pk -> pi 是右轉的(其實就是α + β ≥ π),就彈出棧頂元素,並且返回步驟⑥;
如果是左轉的(α + β < π),就入棧點pi,並且i+=1,返回步驟④;
4、**模板:
#include#define max 10005#define eps 1e-6
using
namespace
std;
struct
point
}p[max];
typedef point vctor;
vctor
operator - (point a,point b)
int dcmp(double
x)//
叉積double cross(vctor a,vctor b)
//距離
double dist(point p1,point p2)
bool
cmp(point p1,point p2)
vector
graham_scan(int
n)
int idx=0
;
for(int i=1;i//
選出y座標最小的點,若y座標相等,選擇x座標小的點
swap(p[
0],p[idx]);
sort(p+1,p+n,cmp);
for(int i=0;i<=2;i++) ans.push_back(p[i]);
int top=2
;
for(int i=3;i)
ans.push_back(p[i]);
top++;
}return
ans;
}
凸包(Graham掃瞄法構建)
ps 我的媽呀,心態 好像也不太難,看各種模板看的雲裡霧裡的,真的還是自己動手敲來的好,幾乎沒多久就懂的差不多了。乙個本該寒假就該掌握的知識,居然熬了我幾個小時。這一次還是很好的了解了凸包,以前看群裡學長們說,覺得好高大上,好難的樣子,仔細了解後發現其實也沒有想象中的那麼恐怖 凸包基本概念 這就是乙...
凸包問題 Graham掃瞄法
凸包點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。右圖中由紅色線段表示的多邊形就是點集q 的凸包。頂點個數n 1 排序 在點集q中找最左下方的點p0,就是x座標和y座標都最小的點,其餘的點計算它們的極座標幅角,以幅角的非降序順序來排序,如果有幅角...
尋找凸包的graham 掃瞄法
1,點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。2,凸包最常用的凸包演算法是graham掃瞄法和jarvis步進法。3,graham掃瞄法 首先,找到所有點中最左邊的 y座標最小的 如果y座標相同,找x座標最小的.以這個點為基準求所有點的極角 ...