凸包:把給定點包圍在內部的、面積最小的凸多邊形。
andrew演算法是graham演算法的變種,速度更快穩定性也更好。
首先把所有點排序,按照第一關鍵字x第二關鍵字y從小到大排序,刪除重複點後得到點序列p1...pn。
1)把p1,p2放入凸包中,凸包中的點使用棧儲存
2)從p3開始,當下乙個點在凸包當前前進方向(即直線p1p2)左邊的時候繼續;
3)否則依次刪除最近加入凸包的點,直到新點在左邊。
如圖,新點p18在當前前進方向p10p15的右邊(使用叉積判斷),因此需要從凸包上刪除點p15和p10,讓p8的下乙個點為p18。重複該過程直到碰到最右邊的pn,求出下凸包即凸包的下輪廓。然後從pn反過來重複該步驟求出上凸包,合併起來後就是完整的凸包。
該演算法掃瞄為o(n)複雜度,排序o(nlogn)。
c++ code(劉汝佳《演算法競賽入門經典-訓練指南》模板)
#include #include #include #include #include #include using namespace std;
const double eps = 1e-8,pi=3.14159265;
int n;
inline int dcmp(double x)//三態函式
#define vector point
struct point
}p[10000+5],ch[10000+5];
bool mycmp(point a, point b)
vector operator + (vector a, vector b)
vector operator - (vector a, vector b)
bool operator == (const vector& a, const vector& b)
inline double cross(vector a, vector b)//叉積
int convexhull()
int k = m;
for(int i = n-2; i >= 0; i--)
if(n > 1) m--;
return m;
}double dis(point a, point b)
int main()
m = convexhull();
//計算凸包周長
double ans=0.0;
for(int i = 0; i < m-1; i++)
ans += dis(ch[i],ch[i+1]);
ans += dis(ch[m-1],ch[0]);
printf("%.1f",ans);
}
例題:wikioi1298(click me)
求解二維凸包並計算周長
wikioi3201(click me)
求解二維凸包並計算周長
poj1113(click me)
本題翻譯:
求解二維凸包並加入乙個圓的周長
計算幾何 凸包問題
給定平面上的二維點集,求解其凸包。一 graham掃瞄法 1.在所有點中選取y座標最小的一點h,當作基點。如果存在多個點的y座標都為最小值,則選取x座標最小的一點。座標相同的點應排除。然後按照其它各點p和基點構成的向量與x軸的夾角進行排序,夾角由大至小進行順時針掃瞄,反之則進行逆時針掃瞄。實現中無需...
二維凸包演算法
部落格參考 謝謝 chao xun 把凸包寫的這麼詳細。關於凸包的問題的解決的最初思路是這樣的。1 找到乙個基準點 必須在凸邊上 2 以基準點做射線,然後將該射線向固定方向旋轉,直到接觸到乙個新的點。3 以 2 中找到的點作為新的基準點,作射線繼續朝著一開始的固定的方向旋轉 4 反覆重複2,3直到最...
題解 二維凸包
呵呵呵複習一下這個東西免得做到計算幾何連暴力都不會嚶嚶嚶 免得到時候寫斜率優化結果凸包不會了嚶嚶嚶 數學走起 vec x 1,y 1 vec x 2,y 2 shadow times vec x 1y 2 x 2y 1 根據右手螺旋定則。shadow 是我亂搞的符號,雖然我搞不懂為什麼是這樣,但是這...