計算幾何 二維凸包問題 Andrew演算法

2021-06-21 23:07:41 字數 1655 閱讀 1707

凸包:把給定點包圍在內部的、面積最小的凸多邊形。

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 是我亂搞的符號,雖然我搞不懂為什麼是這樣,但是這...