凸包演算法實現點集合中搜尋凸包頂點的功能,可以處理共線情況,可以輸出共線點也可以不輸出而只輸出凸包頂點。經典的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演算法是一種靈活的凸包演算法,時間複雜度是o nlogn 演算法細節 1.選出最左下角的點 排序 x最小,其次是y最小 2.其餘點按極角排序,在極角相等的情況下距離極點 p 0 最近的優先 3.用乙個棧 陣列 儲存凸包上的點,先把p 0 p 1 壓入棧。4.掃瞄每乙個點,用叉積... 一 什麼是凸包 在乙個二維座標系中,有若干點雜亂排列著,將最外層的點連線起來構成的凸多邊型,它能包含給定的所有的點,這個多邊形就是凸包。尋找凸包的演算法有很多種,graham scan 演算法是一種十分簡單高效的二維凸包演算法,能夠在 o nlogn 的時間內找到凸包。二 graham scan 演... 平面中取一定點a,從a點出發的一條射線am,再選定乙個長度單位和角度的正方向 通常取逆時針方向 對於平面內任意一點b,都可以用有序對 這樣建立的座標系稱為極座標系,定點a稱為極點,射線am稱為極軸,若極座標系中定點a與直角座標系的原點o重合,極座標系中的極軸為直角座標系x軸正半軸,於x軸逆時針成90...凸包 Graham Scan演算法
Graham Scan凸包演算法
凸包問題 Graham Scan演算法