求二維凸包演算法詳解

2021-06-09 23:49:59 字數 1621 閱讀 5682

凸包

(convex hull)

是乙個計算幾何(圖形學)中的概念。用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有點的。嚴謹的定義和相關概念參見

維基百科:凸包

。這個演算法是由數學大師葛立恆

(graham)

發明的,他曾經是美國數學學會

(ams)

主席、at&t

首席科學家以及國際雜技師協會

(ija)

主席。(太汗了,這位大牛還會玩雜技~)

給定平面上的二維點集,求解其凸包。

1. 在所有點中選取

y座標最小的一點

h,當作基點。如果存在多個點的

y座標都為最小值,則選取

x座標最小的一點。座標相同的點應排除。然後按照其它各點

p和基點構成的向量與x

軸的夾角進行排序,夾角由大至小進行順時針掃瞄,反之則進行逆時針掃瞄。實現中無需求得夾角,只需根據向量的內積公式求出向量的模即可。以下圖為例,基點為

h,根據夾角由小至大排序後依次為h,

k,c,

d,l,

f,g,

e,i,

b,a,

j。下面進行逆時針掃瞄。

2. 線段一定在凸包上,接著加入

c。假設線段

也在凸包上,因為就h,

k,c三點而言,它們的凸包就是由此三點所組成。但是接下來加入

d時會發現,線段

才會在凸包上,所以將線段

排除,c

點不可能是凸包。

3. 即當加入一點時,必須考慮到前面的線段是否會出現在凸包上。從基點開始,凸包上每條相臨的線段的旋轉方向應該一致,並與掃瞄的方向相反。如果發現新加的點使得新線段與上線段的旋轉方向發生變化,則可判定上一點必然不在凸包上。實現時可用向量叉積進行判斷,設新加入的點為

pn + 1

,上一點為

pn,再上一點為

pn - 1

。順時針掃瞄時,如果向量

n - 1, pn>

與n, pn + 1>

的叉積為正(逆時針掃瞄判斷是否為負),則將上一點刪除。刪除過程需要回溯,將之前所有叉積符號相反的點都刪除,然後將新點加入凸包。

在上圖中,加入

k點時,由於線段

相對於為順時針旋轉,所以

c點不在凸包上,應該刪除,保留

k點。接著加入

d點,由於線段

相對為逆時針旋轉,故

d點保留。按照上述步驟進行掃瞄,直到點集中所有的點都遍例完成,即得到凸包。

這個演算法可以直接在原資料上進行運算,因此空間複雜度為

o(1)

。但如果將凸包的結果儲存到另一陣列中,則可能在**級別進行優化。由於在掃瞄凸包前要進行排序,因此時間複雜度至少為快速排序的

o(nlgn)

。後面的掃瞄過程複雜度為

o(n)

,因此整個演算法的複雜度為

o(nlgn)。

二維凸包演算法

部落格參考 謝謝 chao xun 把凸包寫的這麼詳細。關於凸包的問題的解決的最初思路是這樣的。1 找到乙個基準點 必須在凸邊上 2 以基準點做射線,然後將該射線向固定方向旋轉,直到接觸到乙個新的點。3 以 2 中找到的點作為新的基準點,作射線繼續朝著一開始的固定的方向旋轉 4 反覆重複2,3直到最...

二維凸包 Andrew演算法

把給定點包圍在內部的 面積最小的凸多邊形 設向量 p x1,y1 q x2,y2 則 p q x1 y2 x2 y1 其結果是乙個由 0,0 p,q,p q 所組成的平行四邊形的 帶符號的面積,p q q p p q p q 叉積的乙個非常重要的性質是可以通過它的符號來判斷兩向量相互之間的順逆時針關...

二維凸包求解(Andrew演算法 )

andrew演算法是graham演算法的變種。其主要思想為把凸包上的點依次放入棧中,如果發現形成了凹多邊形 叉積為負值 就刪除一些點,使得又能夠維持凸的形態。這時就會發現,處理各個點需要按照x從左往右的順序,排序即可 當然,這只是處理了下凸的乙個凸殼,倒過來再刷一次,就得到了整個凸包 include...