計算幾何常用演算法 ACM

2021-07-10 17:35:16 字數 4723 閱讀 5058

複製自:

1. 向量減法

設二維向量 p = (x1,y1) ,q = (x2,y2)

則向量減法定義為: p - q = ( x1 - x2 , y1 - y2 )

顯然有性質 p - q = - ( q - p )

如不加說明,下面所有的點都看作向量,兩點的減法就是向量相減;

2.向量叉積

設向量p = (x1,y1) ,q = (x2,y2)

則向量叉積定義為: p × q = x1*y2 - x2*y1 得到的是乙個標量

顯然有性質 p × q = - ( q × p ) p × ( - q ) = - ( p × q )

如不加說明,下面所有的點都看作向量,點的乘法看作向量叉積;

叉乘的重要性質:

> 若 p × q > 0 , 則p 在q的順時針方向

> 若 p × q < 0 , 則p 在q的逆時針方向

> 若 p × q = 0 , 則p 與q共線,但可能同向也可能反向

設點為q,線段為p1p2 ,判斷點q在該線段上的依據是:

( q - p1 ) × ( p2 - p1 ) = 0 且 q 在以 p1,p2為對角頂點的矩形內

4.判斷兩線段是否相交

我們分兩步確定兩條線段是否相交:

(1). 快速排斥試驗

設以線段 p1p2 為對角線的矩形為r, 設以線段 q1q2 為對角線的矩形為t,如果

r和t不相交,顯然兩線段不會相交;

(2). 跨立試驗

如果兩線段相交,則兩線段必然相互跨立對方,如圖1所示.在圖1中,p1p2跨立

q1q2 ,則向量 ( p1 - q1 ) 和( p2 - q1 )位於向量( q2 - q1 ) 的兩側,即

( p1 - q1 ) × ( q2 - q1 ) * ( p2 - q1 ) × ( q2 - q1 ) < 0

上式可改寫成

( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) > 0

當( p1 - q1 ) × ( q2 - q1 ) = 0 時,說明( p1 - q1 ) 和 ( q2 - q1 )共線,

所以判斷p1p2跨立q1q2的依據是:

( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) ≥ 0

同理判斷q1q2跨立p1p2的依據是:

( q1 - p1 ) × ( p2 - p1 ) * ( p2 - p1 ) × ( q2 - p1 ) ≥ 0

至此已經完全解決判斷線段是否相交的問題.

5.判斷線段和直線是否相交

如果線段 p1p2和直線q1q2相交,則p1p2跨立q1q2,即:

( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) ≥ 0

6.判斷矩形是否包含點

只要判斷該點的橫座標和縱座標是否夾在矩形的左右邊和上下邊之間.

6.判斷線段、折線、多邊形是否在矩形中

因為矩形是個凸集,所以只要判斷所有端點是否都在矩形中就可以了.

7.判斷矩形是否在矩形中

只要比較左右邊界和上下邊界就可以了.

8.判斷圓是否在矩形中

圓在矩形中的充要條件是:圓心在矩形中且圓的半徑小於等於圓心到矩形四邊的距

離的最小值.

9.判斷點是否在多邊形中

以點p為端點,向左方作射線l,由於多邊形是有界的,所以射線l的左端一定在多

邊形外,考慮沿著l從無窮遠處開始自左向右移動,遇到和多邊形的第乙個交點的

時候,進入到了多邊形的內部,遇到第二個交點的時候,離開了多邊形,……所

以很容易看出當l和多邊形的交點數目c是奇數的時候,p在多邊形內,是偶數的話

p在多邊形外.

但是有些特殊情況要加以考慮.如果l和多邊形的頂點相交,有些情況下交點只能

計算乙個,有些情況下交點不應被計算(自己畫個圖就明白了);如果l和多邊形

的一條邊重合,這條邊應該被忽略不計.為了統一起見,我們在計算射線l和多邊

形的交點的時候,1.對於多邊形的水平邊不作考慮;2.對於多邊形的頂點和l相

交的情況,如果該頂點是其所屬的邊上縱座標較大的頂點,則計數,否則忽略;

3.對於p在多邊形邊上的情形,直接可判斷p屬於多邊行.由此得出演算法的偽**

如下:1. count ← 0;

2. 以p為端點,作從右向左的射線l;

3. for 多邊形的每條邊s

4. do if p在邊s上

5. then return true;

6. if s不是水平的

7. then if s的乙個端點在l上且該端點是s兩端點中縱座標較大的端點

9. then count ← count+1

10. else if s和l相交

11. then count ← count+1;

12. if count mod 2 = 1

13. then return true

14. else return false;

其中做射線l的方法是:設p'的縱座標和p相同,橫座標為正無窮大(很大的乙個正

數),則p和p'就確定了射線l.這個演算法的複雜度為o(n).

10.判斷線段是否在多邊形內

線段在多邊形內的乙個必要條件是線段的兩個端點都在多邊形內;

如果線段和多邊形的某條邊內交(兩線段內交是指兩線段相交且交點不在兩線段的

端點),因為多邊形的邊的左右兩側分屬多邊形內外不同部分,所以線段一定會有

一部分在多邊形外.於是我們得到線段在多邊形內的第二個必要條件:線段和多邊

形的所有邊都不內交;

線段和多邊形交於線段的兩端點並不會影響線段是否在多邊形內;但是如果多邊形

的某個頂點和線段相交,還必須判斷兩相鄰交點之間的線段是否包含與多邊形內部.

因此我們可以先求出所有和線段相交的多邊形的頂點,然後按照x-y座標排序,這樣

則該線段一定在多邊形內.證明如下:

命題1:

如果線段和多邊形的兩相鄰交點p1 ,p2的中點p' 也在多邊形內,則p1, p2之間的

所有點都在多邊形內.

證明:假設p1,p2之間含有不在多邊形內的點,不妨設該點為q,在p1, p'之間,因為多邊

形是閉合曲線,所以其內外部之間有界,而p1屬於多邊行內部,q屬於多邊性外部,

p'屬於多邊性內部,p1-q-p'完全連續,所以p1q和qp'一定跨越多邊形的邊界,因此

在p1,p'之間至少還有兩個該線段和多邊形的交點,這和p1p2是相鄰兩交點矛盾,故

命題成立.證畢

由命題1直接可得出推論:

推論2:

設多邊形和線段pq的交點依次為p1,p2,……pn,其中pi和pi+1是相鄰兩交點,線段

pq在多邊形內的充要條件是:p,q在多邊形內且對於i =1, 2,……, n-1,pi ,pi+1

的中點也在多邊形內.

在實際程式設計中,沒有必要計算所有的交點,首先應判斷線段和多邊形的邊是否內交

,倘若線段和多邊形的某條邊內交則線段一定在多邊形外;如果線段和多邊形的每

一條邊都不內交,則線段和多邊形的交點一定是線段的端點或者多邊形的頂點,只

至此我們得出演算法如下:

1. if 線端pq的端點不都在多邊形內

2. then return false;

3. 點集pointset初始化為空;

4. for 多邊形的每條邊s

5. do if 線段的某個端點在s上

6. then 將該端點加入pointset;

8. then 將該端點加入pointset;

9. else if s和線段pq相交 // 這時候可以肯定是內交

10. then return false;

11. 將pointset中的點按照x-y座標排序,x座標小的排在前面,

對於x座標相同的點,y座標小的排在前面;

12. for pointset中每兩個相鄰點 pointset[i] , pointset[ i+1]

13. do if pointset[i] , pointset[ i+1] 的中點不在多邊形中

14. then return false;

15. return true;

這個演算法的複雜度也是o(n).其中的排序因為交點數目肯定遠小於多邊形的頂點數

目n,所以最多是常數級的複雜度,幾乎可以忽略不計.

11.判斷折線在多邊形內

只要判斷折線的每條線段是否都在多邊形內即可.設折線有m條線段,多邊形有n個

頂點,則複雜度為o(m*n).

12.判斷多邊形是否在多邊形內

只要判斷多邊形的每條邊是否都在多邊形內即可.判斷乙個有m個頂點的多邊形是

否在乙個有n個頂點的多邊形內複雜度為o(m*n).

13.判斷矩形是否在多邊形內

將矩形轉化為多邊形,然後再判斷是否在多邊形內.

14.判斷圓是否在多邊形內

只要計算圓心到多邊形的每條邊的最短距離,如果該距離大於等於圓半徑則該圓在

多邊形內.計算圓心到多邊形每條邊最短距離的演算法在後文闡述.

15.判斷點是否在圓內

計算圓心到該點的距離,如果小於等於半徑則該點在圓內.

16.判斷線段、折線、矩形、多邊形是否在圓內

因為圓是凸集,所以只要判斷是否每個頂點都在圓內即可.

17.判斷圓是否在圓內

設兩圓為o1,o2,半徑分別為r1, r2,要判斷o2是否在o1內.先比較r1,r2的大小

,如果r1

ACM 計算幾何

1.找凸包的最小寬度 include using namespace std double eps 1e 10 考慮誤差的加法運算 double add double a,double b struct p p double x,double y x x y y p operator p p p o...

計算幾何常用演算法介紹

計算幾何常用演算法介紹 1.向量減法 設二維向量 p x1,y1 q x2,y2 則向量減法定義為 p q x1 x2 y1 y2 顯然有性質 p q q p 如不加說明,下面所有的點都看作向量,兩點的減法就是向量相減 2.向量叉積 設向量p x1,y1 q x2,y2 則向量叉積定義為 p q x...

C 常用計算幾何演算法

從網上轉來的幾何演算法,對點線的基本演算法,有興趣的可以學習下。include include include include define max a,b a b a b define min a,b a b b a define sign x x eps?1 x eps?1 0 using na...