Graham Scan凸包演算法

2021-08-22 04:45:29 字數 1739 閱讀 7958

一:什麼是凸包

在乙個二維座標系中,有若干點雜亂排列著,將最外層的點連線起來構成的凸多邊型,它能包含給定的所有的點,這個多邊形就是凸包。

尋找凸包的演算法有很多種,graham scan 演算法是一種十分簡單高效的二維凸包演算法,能夠在 o(nlogn) 的時間內找到凸包。

二:graham scan 演算法

先將若干個點排序比較兩個點的 x 座標小的先被掃瞄。如果兩個點 x 座標相同,那麼就比較 y 座標,小的先被掃瞄(掃瞄上凸殼的時候反過來)。

我們可以定義乙個陣列que用來儲存可以構成凸包的點的下標。

先確定乙個起點(一般是最左邊的點和最右邊的點),並將他的下標存入que陣列中

接著看下乙個點 如果加入這個點和que陣列中之已存入的最後一點所構成的 「殼」 凸性沒有變化,就將他存入que陣列中。

否則就把que陣列中之已存入的最後一點刪去,再比較凸性,直到凸性不發生變化。

分別掃瞄上下兩個 「殼」,合併在一起,凸包就找到了。

對於二維向量a=(x1,y2)和b=(x2,y2),a×b定義為x1*y2-y1*x2。而它的幾何意義就是|a||b|sin。如果a與b夾角小於180度(逆時針),那麼這個值就是正值,大於180度就是負值。需要注意的是,左乘和右乘是不同的。如圖所示:

三,**詳解

先找 「下殼」(上下上下殼尋找方法是一樣的)。首先確定點 a 和為起始點。再找他的下乙個點b

判斷下乙個點c,能否插入。算向量 ab × bc的向量積,卻發現向量積係數小於(等於)0,也就是說向量 bc 在ab 的順時針方向上。那麼該點不可用。

刪去b點

按照這樣的方法依次掃瞄,找完 「下殼」 後,再找 「上殼」。

**

//n是一共有多少個點

//pt是結構體 用來存點的x(x),y(y)座標,還有下標(ps)

//que陣列儲存被選中的凸包的點的編號,now是凸包中點的個數

struct node

}pt[n];

long

long

get(int x,int y,int z)

int que[n];

void get_convex_hull()

temp=now;

for(int i = n-2;i >=0;i --) //掃瞄上殼

return now- 1;// 返回組成凸包的點的個數,實際上多了乙個,就是起點,所以組成凸包的點個數是 now - 1

}

凸包 Graham Scan演算法

graham scan演算法是一種靈活的凸包演算法,時間複雜度是o nlogn 演算法細節 1.選出最左下角的點 排序 x最小,其次是y最小 2.其餘點按極角排序,在極角相等的情況下距離極點 p 0 最近的優先 3.用乙個棧 陣列 儲存凸包上的點,先把p 0 p 1 壓入棧。4.掃瞄每乙個點,用叉積...

凸包Graham Scan演算法實現

凸包演算法實現點集合中搜尋凸包頂點的功能,可以處理共線情況,可以輸出共線點也可以不輸出而只輸出凸包頂點。經典的graham scan演算法,點排序使用極角排序方式,並對共線情況做特殊處理。一般演算法是將共線的點去掉距離小的,保留最遠的,這樣處理會導致不能輸出凸包邊上的點,只能輸出頂點。但是有時候需要...

凸包問題 Graham Scan演算法

平面中取一定點a,從a點出發的一條射線am,再選定乙個長度單位和角度的正方向 通常取逆時針方向 對於平面內任意一點b,都可以用有序對 這樣建立的座標系稱為極座標系,定點a稱為極點,射線am稱為極軸,若極座標系中定點a與直角座標系的原點o重合,極座標系中的極軸為直角座標系x軸正半軸,於x軸逆時針成90...