半平面交

算法目的:求N 個半平面的交

定義:一個半平面指的是由滿足ax+by+c>0ax+by+c>=0 的點集組成的二維區域。一般來說在寫代碼的時候,我們可以把一個半平面想象成一個向量所在的直線右面的一片區域
半平面的交可能是一個封閉圖形也可能是沒有邊界的區域或者爲空

大概思路:先將所有的向量按照與x軸的夾角排序(此處的夾角在[ππ] 這個區間內),然後按順序將半平面插入,每次插入的時候從隊頭及隊尾彈出一些之前加入的、現在已經沒用的半平面。最後得到的就是這些半平面的交

算法步驟:1.先把所有的半平面用”向量的右側”這種方法表示出來。具體來說我們開一個結構體line{node a,b;double ang;};代表這個向量是從點a到點b的,與x軸夾角爲ang,半平面指的是向量右側
     2.把所有向量按照ang從小到大排序,ang相同的我們只保留限制條件最緊的那一個(其他的都沒用)
     3.維護一個半平面隊列q,隊列中的元素按照ang大小排序,並且全部都是有用的(沒有一個半平面被其他兩個半平面擋住)。再維護一個交點隊列p,其中p[i]爲q[i]和q[i+1]的交點
當出現這種情況時,我們需要把隊尾彈出
當出現以上這種情況時,我們需要把隊尾q[t]彈出,因爲他已經被q[t-1]和L[i]覆蓋
那麼如何檢驗這個事情呢?我們只需判斷p[t-1]是否在L[i]左側就行(圖中L[i]方向是向下的,所以p[t-1]在其左側)

這裏寫圖片描述
當出現這種情況時,我們需要把隊頭彈出
這時L[i]已經繞了半圈,有可能覆蓋掉隊頭了,判斷的方法和上面同理,只需判斷p[h]是否在L[i]左側就可以了

     4.這樣逐次將所有的半平面插入,看起來貌似得到了最終的結果,但是還有可能出現這樣的情況
這裏寫圖片描述
最後加入的兩個半平面是沒有用的
所以我們要將隊尾一些沒用的半平面刪掉
剩下的就都是關鍵半平面和關鍵交點了,半平面交也就求完了

算法複雜度:設半平面有O(N) 個,總時間複雜度是O(NlogN)

算法應用:可以用來求多邊形的核,半平面交點,半平面解析式,封閉區域面積、周長等等

一份樣例代碼可以參見 POJ1279題解

發佈了170 篇原創文章 · 獲贊 42 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章