《計算幾何》01.Convex Hull

Convex Hull

Divide-and-conquer

Merge

將大問題分解成小問題,最後進行合併。

Common Kernel

和歸併排序一樣,我們將點分成兩個子集,分別求凸包,問題就變成了如何將兩個凸包合併。

如何將兩個凸包處理成星形多邊形

爲了找到Star-shape-polygon,我們要找到兩個多邊形相交的公共的點,那麼兩個多邊形相交會出現什麼情況呢?

如上圖所示,如s1s_1,是比較理想的情況,我們很容易找到公共點,對於s2s_2,找到公共點的可能就會小很多。

更壞的情況,例如s3s_3,我們甚至無法找到兩個凸包的公共點,那麼如何處理呢?

Interior

對於一個凸包來說,我們如何找到一個點使得這個點在凸包的內部呢?

我們可以選擇凸包上任意三個點,選擇這三個點組成的三角形的重心即可,計算複雜度爲常數時間。

那麼我們現在判斷選出的內點是否在另一個凸包的內部,如果是:

可以發現兩個凸包分別對於內點成一個環形的有序序列(圖中黃色和藍色的直線),則問題變成了經典的環形歸併。歸併之後再次進行Graham-Scan即可。

那麼如何判斷所選內點是否在另一個多邊形內部呢?

In-Convex-polygon-Test。但凸包是動態的,所以要用n次To-Left-Test:

幸運的是,O(n)O(n)次TLT並不會影響整體算法的複雜度,因爲我們可以將這nn次操作都可以納入Merge的過程中。

Exterior

接下來我們討論下一種情況,所選內點落在另一個子凸包的外側。

如圖所示,我們可以找出圖中s,ts,t 兩個切點,找到sttsst和ts 兩個線段。同理,tsts線段在總凸包中沒有貢獻。

那麼我們可以得到了一個環形有序序列和一個線性有序序列,進行歸併,再次Graham-Scan。

Divide-and-conquer (2)

Preprocessing

歸併算法我們可以看到,有些過於複雜。對於兩個圖包:

如果他們沿着水平方向是可分割的,彼此獨立,那麼合併就非常的簡單。

將點集中的座標按x軸排序,取中點分割即可,那麼我們關注的就是兩個凸包中的兩對點l,rl,r

Common Tangents

找到兩個凸包的公切線(Common Tangents)。那麼如何找這兩個凸包的公切線呢?問題可能很複雜:

我們從rrll開始:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qGCTI8Y5-1584153950700)(C:\Users\szx74\Desktop\Blog\計算幾何\image-20200314100712514.png)]

先將兩個點連起來,那麼恩麼找到這兩個點呢?我們在從最開始從下向上歸併的過程中,記下每個凸包的l,rl,r即可。

接下來我們思考連接了r,lr,l之後的動作。

對於每次固定的rr,找到最優的右側的ll,使得ll兩側的點都在它的同一側,這樣我們就得到了局部最優的ll,那麼我們反觀之前固定的rr,同樣的方法找到局部最優的rr,再反觀ll,反覆進行,直到保證r,lr,l兩個點都爲最優,既兩個點的臨點皆再他們的同一側,這樣我們就找到了一條切線。時間複雜度爲O(n+m)O(n+m)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章