《模板》《計算幾何》凸包及其基本演算法

2021-06-11 21:05:49 字數 3277 閱讀 5193

[poj 1113] 計算幾何之凸包(一) - master_chivu -

利用計算向量叉積判斷點的位置關係時應確保夾角小於180度。

演演算法筆記 - convex hull

卷包裹演算法

演算法複雜度o(n^2),適合隨機點集

即"卷包裹演算法"

p為平面上的哪些點.這裡設定為剛好100點

ch為凸包上的點.這裡設定為照逆時針順序排列*/

struct point

p[100],ch[100];

// 小於,用以找出最低最左邊的點

bool compare (point& a, point& b)

// 向量oa cross 向量ob。大於零表示從oa到ob為順時針旋轉

double cross(point& o, point& a, point& b)

void findconvexhull() }

[poj 2187] 計算幾何之凸包(二) - master_chivu -

graham『s scan演算法

演算法複雜度o(nlog2n)

極角序:

處理共線問題時容易出現bug

//graham 掃瞄法極角序

#include #include #include using namespace std;

const int num=1005;

struct point

point(double _x,double _y)

void get()

}pt[num],ch[num],temp;

const double std=1e-8;

int n,len;

int db (double x)

double dis (point a,point b)

//判斷p在向量ab的哪一側

//右側:返回正值

//左側:返回負值

//在向量ab上返回0

double cross(point a,point b,point p)

int cmp (point a,point b)

//求凸包函式

//pt:所有的點,n個,pt[0]到pt[n-1]

//q:求完的凸包中的點,len個,ch[0]到ch[len-1]

void graham (point pt,point ch,int &len,int n)

len--; //頭尾是同乙個點

}

水平序:

選擇兩個點a,b,使ya最大,yb最小,然後把所有點根據在直線ab的兩側分成兩個點集(特殊的,a,b可歸於任一點集)。

分別對每個點集中的點進行主關鍵字為y座標遞增,次關鍵字為x座標遞增的排序。

將兩個點集合並,其中乙個倒序插入另乙個的末尾。

在精度上,水平序要好一些。

//graham水平序-double

#include #include #include using namespace std;

struct point

}pt[1005],ch[1005];

int n,len;

int db (double d)

double cross (point p,point ch,point x)

int cmp (const void *a,const void *b)

//ch[0]~ch[len-1]儲存凸包,只儲存頂點

//pt為源資料,n為原點數

void graham (point pt,point ch,int &len,int n)

int temp=top;

for (i=n-2;i>=0;i--)

len=top;

}

//graham水平序-int

#include #include #include using namespace std;

#define max(x,y) ((x)>(y)?(x):(y))

const int num=50005;

struct point

bool operator < (const point& _p) const

;}pt[num],ch[num];

int cross (point p,point q,point x)

//ch[0]~ch[len-1]儲存凸包,只儲存頂點,逆時針儲存

//pt為源資料,n為原點數

void graham (point pt,point ch,int &len,int n)

int temp=top;

for (i=n-2;i>=0;i--)

len=top;

}

melkman

構建乙個雙端棧,維護棧裡的點為右手系(即棧中任意連續三點組成的路徑是左旋的,或至少成直線),

初始時將開始的三點放入佇列

while 點沒加完

begin

讀入乙個點

if 該點對於棧頂左旋 and 該點對於棧底右旋 then

continue;  //該點在凸包內,捨去

while 該點對於棧頂右旋 do

棧頂-1; //確保滿足右手系

將點加入棧頂

while 該點對於棧底左旋 do

棧底+1; //確保滿足右手系

將點加入棧底

end;

//melkman

#include struct point

pt[2005];

int n,d[2005];

int db (double d)

double cross (point c,point a,point b)

double dis (point a,point b)

void melkman (int &front,int &tail,int d,int n,point pt)

}

計算幾何 凸包演算法

凸包演算法總結 凸包是指覆蓋平面座標系內若干點的面積最小的凸多邊形。求凸包的第一步是確定 凸包的定點都在給定的點中。通過幾何方法反證很容易得到這一結論。所以,只要從所有點中挑選若干正確的點,按順序 順時針或逆時針 排列,就相當與求得了凸包。計算幾何中的凸包問題程式 graham演算法 include...

計算幾何 凸包演算法 收藏

計算幾何 凸包演算法 收藏 計算幾何中的凸包問題程式 graham演算法 i nclude i nclude i nclude define maxn 10000 頂點的型別定義 typedef struct point1 int n 頂點的個數 point1 points maxn 頂點陣列 in...

計算幾何 經典演算法 凸包

在學習了一些有關計算機幾何的基礎知識和一些基本工具之後要快速的解決一些簡單的幾何問題,如兩點之間的距離 兩線段的交點個數等等是可以輕鬆應付的,但是對於複雜點的幾何問題,我們還是要有更好的演算法,這樣才可以更高效的解決它。在這一篇中來總結 平面凸包 的 graham演算法 平面凸包 定義 對乙個簡單多...