幾何算法詳解與例題分析

前言

畫乃我思所欲,非我見所得。

幾何算法常常出現在計算機圖形學,大規模集成電路設計等方面,常常需要分析平面內點、線段、直線的關係,而其算法呢大多用到了歸納,分治等算法的思想。

幾何算法舉例

1.判斷點是否在多邊形內部

判斷p是否在多邊形內部?

從p連一條到多邊形外部的點的直線

看與所有多邊形的邊相交幾次

若爲奇數

則在內部

如何找外部的點?

找一個點x值比多邊形的所有點x值都大

 

2.構造多邊形

平面內給n個點,怎麼構造一個多邊形

(1)

造一個圓包含多邊形的所有點

然後從圓心繞一圈按順序連接所有點

這就是個多邊形

(2)

選擇多邊形x,y都最小的那個點

然後整個圖就在1,2象限了

這樣從角度的小到大連接所有點,就是多邊形

 

3.凸包算法

尋找n個點的凸包

(1)

歸納

假設我們可以找到n-1個點的凸包

加入第n點

要麼在凸包中,不用操作,

檢測是否在凸包中

前面判斷點是否在多邊形中

O(n)

要麼不在凸包中

要拓展凸包

刪去原來在邊上,現在在裏面的點

遍歷

支撐線:vn 與 vi  vj 的直線分別於x軸角度是最大和最小

然後刪點

T(n) = T(n - 1) + O(n)

O(n*n)

(2)

優化

禮物包裹算法

從一個點一個一個往過包

就像紙包紅薯

先折一次,再折

就是第一個點,第二個點

第三個點

1,2向量與2,3向量角度最小

就是凸包

每個點需要與所有點計算角度

O(n * n)

(3)

優化

Graham掃描算法

選最右下角的點a

排序-每個點與a直線與x軸角度大小

從一個點往下找

排序後1,2點入棧

新加入3的與棧頂兩元素比較

若向量旋轉方向逆

就入棧

若順

就棧頂元素出棧

循環

3 與棧頂兩元素再比

這樣排序O(nlogn)

每個點回溯

總回溯不會超過O(n)

總O(nlogn)

 

4.找最近點對

給出平面內的n個點,找出距離最小的點

(1)

暴力搜索

n個點兩兩計算距離

N*(n-1)/2

(2)

分治

歸納

將原n個點找到x座標最中間的一個,以這個點的豎線分兩堆

假設我們已知n/2個點堆中的最小距離

推廣的n

左邊最小值d1, 右邊最小值d2

D= min(d1, d2)

計算豎線兩邊+-d範圍內的點兩兩最小值

因爲外面的不可能有跨界還小於d的

最壞情況

n個點都在中間區域內

。。。

Tn = 2T(n/2) + O(n^2)

還O(n^2)

 

優化

其實每個點找對面界中的點時

只用找[y - d, y + d]的點

有對面界的最小距離爲d

將中間區域的點按y排序(O(nlogn))

每個點只會與對面界的最多6個點檢查一遍

所以檢查時間爲常數O(n)

Tn = 2T(n/2) + O(nlogn)

O(n(logn)^2)

 

再優化

增強歸納

我們不但知道n/2堆的最小距離,我們還知道其中點y值的排序

這樣求中間的時候就可以直接合並

類似於歸併排序

Tn = 2T(n/2) + O(n)

O(nlogn)

 

 

5.求水平線與豎直線的交點

平面內有n條水平線,m條豎直線,求交點

 

(1)

暴力

兩兩求O(mn)

 

(2)

將所有線端點x值排序

O((m+n)log(m+n))

掃描線

設置一條豎線從平面左邊到平面右邊

 

(1)是左端點,就入隊,表示這條線有產生交點的希望

(2)是右端點,就這條直線出隊

(3)是豎線,就與隊列中的水平線比較,是否產生交點

 

掃描

檢查M+n個點

豎直線的話要檢查所有水平點

最壞(m+n)n

優化

維護有希望的水平線以y值排序的堆

這樣判斷是否相交就用豎直線的兩個端點二分查找

O(m+n)logn

 

總結

幾何算法的問題我們常常會說這肉眼看看不就出來了嗎,但幾何算法就是這樣,它是讓計算機解的方法。設計幾何算法時,要注意不要被腦子裏的慣式圖形所誤導,要考慮特殊情況。

 

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