1. 向量減法
設二維向量 p = (x1,y1) ,q = (x2,y2)
則向量減法定義為: p - q = ( x1 - x2 , y1 - y2 )
顯然有性質 p - q = - ( q - p )
如不加說明,下面所有的點都看作向量,兩點的減法就是向量相減;
2.向量叉積
4.判斷兩線段是否相交
( 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相交 本文來gis公園
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.判斷線段是否在多邊形內
本文來gis公園
gis公園www.gispark.com
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的大小,如果r1gis公園www.gispark.com
如果po不平行於x軸和y軸,則po的斜率存在且不為0,如圖4(c)所示。這時直線po斜率為
k = ( p.y - o.y )/ ( p.x - o.x )
直線po的方程為:
y = k * ( x - p.x) + p.y
設圓方程為:
(x - o.x ) ^2 + ( y - o.y ) ^2 = r ^2,
聯立兩方程組可以解出直線po和圓的交點,取其中離p點較近的交點即可。
21.計算兩條共線的線段的交點
對於兩條共線的線段,它們之間的位置關係有圖5所示的幾種情況。圖5(a)中兩條線段沒有交點;圖5 (b) 和 (d) 中兩條線段有無窮焦點;圖5 (c)中兩條線段有乙個交點。設line1是兩條線段中較長的一條,line2是較短的一條,如果line1包含了line2的兩個端點,則是圖5(d)的情況,兩線段有無窮交點;如果line1只包含line2的乙個端點,那麼如果line1的某個端點等於被line1包含的line2的那個端點,則是圖5(c)的情況,這時兩線段只有乙個交點,否則就是圖5(c)的情況,兩線段也是有無窮的交點;如果line1不包含line2的任何端點,則是圖5(a)的情況,這時兩線段沒有交點。
22.計算線段或直線與線段的交點
設一條線段為l0 = p1p2,另一條線段或直線為l1 = q1q2 ,要計算的就是l0和l1的交點。
內容來自gis公園
1.首先判斷l0和l1是否相交(方法已在前文討論過),如果不相交則沒有交點,否則說明l0和l1一定有交點,下面就將l0和l1都看作直線來考慮。
2.如果p1和p2橫座標相同,即l0平行於y軸
a)若l1也平行於y軸,
i.若p1的縱座標和q1的縱座標相同,說明l0和l1共線,假如l1是直線的話他們有無窮的交點,假如l1是線段的話可用"計算兩條共線線段的交點"的演算法求他們的交點(該方法在前文已討論過);
ii.否則說明l0和l1平行,他們沒有交點;
b)若l1不平行於y軸,則交點橫座標為p1的橫座標,代入到l1的直線方程中可以計算出交點縱座標;
3.如果p1和p2橫座標不同,但是q1和q2橫座標相同,即l1平行於y軸,則交點橫座標為q1的橫座標,代入到l0的直線方程中可以計算出交點縱座標;
4.如果p1和p2縱座標相同,即l0平行於x軸
a)若l1也平行於x軸,
i.若p1的橫座標和q1的橫座標相同,說明l0和l1共線,假如l1是直線的話他們有無窮的交點,假如l1是線段的話可用"計算兩條共線線段的交點"的演算法求他們的交點(該方法在前文已討論過);
ii.否則說明l0和l1平行,他們沒有交點;
b)若l1不平行於x軸,則交點縱座標為p1的縱座標,代入到l1的直線方程中可以計算出交點橫座標;
5.如果p1和p2縱座標不同,但是q1和q2縱座標相同,即l1平行於x軸,則交點縱座標為q1的縱座標,代入到l0的直線方程中可以計算出交點橫座標;
6.剩下的情況就是l1和l0的斜率均存在且不為0的情況
a)計算出l0的斜率k0,l1的斜率k1 ;
b)如果k1 = k2
i.如果q1在l0上,則說明l0和l1共線,假如l1是直線的話有無窮交點,假如l1是線段的話可用"計算兩條共線線段的交點"的演算法求他們的交點(該方法在前文已討論過);
ii.如果q1不在l0上,則說明l0和l1平行,他們沒有交點。
c)聯立兩直線的方程組可以解出交點來
說明:這個演算法並不複雜,但是要分情況討論清楚,尤其是當兩條線段共線的情況需要單獨考慮,所以在前文將求兩條共線線段的演算法單獨寫出來。另外,一開始就先利用向量叉乘判斷線段與線段(或直線)是否相交,如果結果是相交,那麼在後面就可以將線段全部看作直線來考慮。
內容來自gis公園
23.求線段或直線與折線、矩形、多邊形的交點分別求與每條邊的交點即可。
24.求線段或直線與圓的交點
設圓心為o,圓半徑為r,直線(或線段)l上的兩點為p1,p2。
1.如果l是線段且p1,p2都包含在圓o內,則沒有交點;否則進行下一步
2.如果l平行於y軸,
a)計算圓心到l的距離dis
b)如果dis > r 則l和圓沒有交點;
c)利用勾股定理,可以求出兩交點座標,如圖6(a)所示;但要注意考慮l和圓的相切情況
3.如果l平行於x軸,做法與l平行於y軸的情況類似;
4.如果l既不平行x軸也不平行y軸,可以求出l的斜率k,然後列出l的點斜式方程,和圓方程聯立即可求解出l和圓的兩個交點;
5.如果l是線段,對於2,3,4中求出的交點還要分別判斷是否屬於該線段的範圍內。
計算幾何常用演算法介紹
計算幾何常用演算法介紹 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...
計算幾何常用演算法 ACM
複製自 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 ...
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...