凸包Graham Scan演算法實現

2021-05-24 08:47:32 字數 1582 閱讀 1885

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

實現如下:

#include

#include

using namespace std;

typedef struct point;

void qsortpoint(point s,point base,int start,int end);

void sortstartedge(point s,int nums);

//向量(x1,y1),(x2,y2)的叉積

double crossmul(double x1,double y1,double x2,double y2)

//向量(x1,y1),(x2,y2)的點積

double dotmul(double x1,double y1,double x2,double y2)

//跨立判斷

//判斷點c是在向量ab的逆時針方向還是順時針方向,大於零逆時針,等於0則共線

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

//計算向量ab和ac點積

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

//判斷浮點數符號

int doublecmp(double d)

//判斷同一直線上的三個點位置,點c是否在點ab之間

bool betweencmp(point a,point b,point c)

//判斷j是否在base->i向量的左邊或當共線時j是否位於它們的線段之間

bool isleftornearer(point base,point i,point j)

void swap(point& a,point& b)

//以s中的最低點為參考點,對其他所有點進行極角排序(逆時針)

//共線時離參考點較遠的點排在前面,凸包的起始邊共線點從近到遠排列

void sortpoint(point s,int nums)

void sortstartedge(point s,int nums)

else

}//最後加入起點形成閉包

while(crossmul(result[top-2],result[top-1],s[0])<=0)

result[top++]=s[0];

resultnums = top;

}int main()

,,,,,

,,,,

,,,,

,,,,};

cout<<"convex hull is:"for(int i=0;icout

}經驗證,演算法無誤。

凸包 Graham Scan演算法

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

Graham Scan凸包演算法

一 什麼是凸包 在乙個二維座標系中,有若干點雜亂排列著,將最外層的點連線起來構成的凸多邊型,它能包含給定的所有的點,這個多邊形就是凸包。尋找凸包的演算法有很多種,graham scan 演算法是一種十分簡單高效的二維凸包演算法,能夠在 o nlogn 的時間內找到凸包。二 graham scan 演...

凸包問題 Graham Scan演算法

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