凸包判斷 Graham掃瞄演算法模板

2021-08-19 16:31:34 字數 2128 閱讀 6737

昨天在做zoj 3537的時候,遇到了凸包的判定,用之前的面積判定計算的時候,總是錯誤,所以學習了一下凸包的判定演算法

對我這個幾何一點都不會的人來說,叉積判定兩個向量方向的地方,這裡是根據叉積的基本定義來計算的,下面我們會進行講解......

a × b > 0 則向量a在向量b的順時針方向

a × b < 0則向量a在向量b的逆時針方向

a × b = 0 則向量a與向量b共線

演算法步驟:

1、首先找打最左下角的點a,也就是y最小,如果y相同,就取x較小的

2、以a點為基點求出其他所有點的極角,按照極角從小到大排序(這裡就可以使用上面叉積的性質,當叉積大於零時,那麼a的極角就小於b的極角,因為a在b的順時針方向)

3、將a,以及極角最小的節點放入佇列,按照順序極角增長的順序,每次取乙個新的節點c,和佇列中兩個點a(較前面的節點)、b作比較,如果向量bc × 向量ac >= 0 說明:bc在ac順時針方向或者同方向,那麼這時b節點就不能取,因為c節點在b節點的相對較外的位置,b節點刪除,這樣一直比較,直到c節點處於相對較內的位置,將c節點放入佇列;如果向量bc × 向量ac  <0 說明:bc在ac逆時針方向,那麼b節點是可取的,c節點直接放入佇列

4、最終佇列中的點就是凸包上的節點

#include #include #include #include #include #include #include #define inf 0x3f3f3f3f

using namespace std;

typedef long long ll;

const int n = 400;

int n,tot;//n為二維平面上點的個數,tot為凸包上點的個數

struct node

a[n],p[n];//p用來儲存凸包

double dis(node a,node b)

double multi(node p0,node p1,node p2)

int cmp(node p1,node p2)//極角排序;使用atan2計算會有部分誤差,所以使用叉積計算比較精確

{ int x=multi(a[0],p1,p2);//叉積大於0,表示向量a在向量b的順時針方向,叉積小於0,向量a在向量b的逆時針方向,等於0,表示兩個向量重合!

if(x>0||(x==0&&dis(p1,a[0])叉積又叫向量積,假設存在三個向量分別為u(x1,y1) , v(x2,y2) ,  w

首先叉積的定義為:u×v= uv sin(u,v) =(x1 * y2) - (x2*y1) 

那麼後面的等號是怎麼成立的呢?下面開始講解

另外我們假設兩個純量r,s,那麼叉積的性質有下面五條:

那麼我們使用上面所述的性質來將叉積定義化簡一下:

這樣我們就得到了上面我們所用到的公式,那麼這裡可以看到叉積的方向只有兩種情況,一種是垂直於xy平面向上,一種是垂直於xy平面向下,那麼實質上這裡的方向判斷就是根據我們的右手定則(四指指向a向量方向,握向b向量方向,那麼拇指方向就是叉積的方向)

那麼這裡就可以解釋上面用到的叉積判斷向量角度關係,我們叉積定義為:u×v= uv sin(u,v),最終的方向也就是sin(u,v)來決定,也就是當為負數時,也就是u、v之間夾角大於180度,也就是在逆時針方向.........

叉積的數值的基本含義就是:以向量u、v為兩邊的平行四邊形的面積,那麼我們就可以用來求解三角形或者多邊形的面積了:

這樣計算三角形面積我們就不會開根號,那麼面積就會更精確一些

叉積還會別用在跨立實驗中,等等

叉積含義:

模板:

凸包演算法詳解 Graham掃瞄法

凸包 給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有的點。如圖所示 來自wiki 步驟 1 先將點按從下向上,從左向右的順序排序。排完序的第乙個點,一定為凸包上的點,記為p0。2,計算各個點相對於 p0 的幅角 按從小到大的順序對各個點排序。當 相同時,距離 p...

凸包(Graham掃瞄法構建)

ps 我的媽呀,心態 好像也不太難,看各種模板看的雲裡霧裡的,真的還是自己動手敲來的好,幾乎沒多久就懂的差不多了。乙個本該寒假就該掌握的知識,居然熬了我幾個小時。這一次還是很好的了解了凸包,以前看群裡學長們說,覺得好高大上,好難的樣子,仔細了解後發現其實也沒有想象中的那麼恐怖 凸包基本概念 這就是乙...

凸包問題 Graham掃瞄法

凸包點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。右圖中由紅色線段表示的多邊形就是點集q 的凸包。頂點個數n 1 排序 在點集q中找最左下方的點p0,就是x座標和y座標都最小的點,其餘的點計算它們的極座標幅角,以幅角的非降序順序來排序,如果有幅角...