計算幾何入門 3:凸包的構造——增量構造法
阿新 • • 發佈:2019-02-15
極點法和極邊法的複雜度分別為O(n^4)和O(n^3),當點集S的規模稍大時就難以適用了。為了滿足實際需要必須尋找更高效的演算法來構造凸包。
一、減治
在引入新演算法之前首先來回顧一下經典的演算法思想:減治(decrease and conquer),注意不是分治(divided and conquer),二者稍有區別。簡單來講就是將問題劃分為一個個簡單的小問題,減而治之,逐個求解,最終就能得到整個問題的解。 減治法的經典例子就是插入排序(insertion sort)。插入排序的過程可以歸結成下圖: 排序的過程中將序列分為兩部分:已排序部分(sorted)和未排序部分(unsorted)。每次排序都是從unsorted中拿出一個元素,通過一次順序查詢插入新的點可能的情況有:新點對凸包有“貢獻”,例如5/5→6/6,6/6→7/7;新點也有可能沒有“貢獻”,例如7/7→7/8;還有可能使原先有“貢獻”的點失效,極點數量減少,例如7/8→6/9。那麼如何對不同情況進行處理呢?
二、in-convex-polygon test
首先任選一點為基準點(藍色點),然後用二分法選取其餘點的“中點“(預處理已經為所有點排了序),然後判斷基準點到終點的有向直線與待定點的位置關係(to-left test
三、 support-line
整個構造演算法可以分成兩大部分:- 如何判斷凸包與新點的位置關係(in-convex-polygon test)
- 如何向凸包插入新點
新點位於原凸包外部,如何將新點插入得到新凸包?直覺判斷應該是如下連線方法:
將新點x插入原凸包的過程,本質上就是尋找兩個連線點s和t,將x和t、s分別連線得到新的凸包。注意t和s兩點將整個原凸包邊界分為兩部分:st和ts兩個有向段。構造新凸包就要保留遠端st、捨棄近端ts。取代近端ts的兩條線就是x和t的連線xt和xs,被稱為切線(tangent)或者support line。 t、s二點的查詢就成了問題的關鍵。 我們在凸包上任取一點v,按逆時針方向v點會有一個直接前驅點和直接後繼點。考察有向直線xv與點v直接前驅和直接後繼的位置關係(兩次to left test),記錄為一個pattern表。
結果無非是四種情況:v的直接前驅和直接後繼相對於有向直線xv的位置是RL,LR,LL,RR。例如上圖黃色點v,是R和L;藍色點v分別是L和R。實際上凸包邊界st上所有點的pattern都為RL,ts上所有點的pattern都為LR。關鍵點在於:點S的pattern是LL,點t的pattern為RR。 因此對凸包邊界每個點做兩次to left test,判斷其pattern就可找出s和t,花費時間成本為常數。