usaco Computational Geometry 計算幾何

目錄

 [隱藏

[編輯]知識準備

  • 圖論
  • 最短路

[編輯]操作

這個模塊討論幾個計算某些幾何問題的算法,這些算法大多基於下列兩個操作:叉積和反正切。

[編輯]叉積

u和v的叉積被表示成u x v。兩個三維的向量u,v的叉積是下列行列式(i,j,k爲x,y,z軸上單位向量):

| i  j  k  |
| Ux Uy Uz |
| Vx Vy Vz |

即:

(Uy*Vz-Vy*Uz)i + (Uz*Vx-Ux*Vz)j + (Ux*Vy-Uy*Vx)k

Geom6.gif

z分量爲0時,上面式子就化爲2維的兩向量叉積了。結果只有z分量。

即:

| Ux Uy |
| Vx Vy |
Ux*Vy-Uy*Vx

(注意!二維的叉積較爲猥瑣。。其實叉積最早就是定義在三維空間內的,當z=0時的特殊情形纔是二維向量積。“二維向量”表達式求出的是一個超出平面的向量。。這個向量的方向我們不關心,但有時又要利用它。。。(例如求多邊形面積)故上式不甚嚴格)

叉積有3個特點:

  • 兩個向量的叉積是一個與這兩個向量同時垂直的向量。
  • 叉積的大小等於下面3個量的乘積:
    • u的大小
    • v的大小
    • u,v夾角的正弦。

當然與u,v同時垂直的向量有兩個方向,叉積的方向取決於u在v的右邊還是在v的左邊。

Geom7.gif

[編輯]點積

點積的值由以下三個值確定:

  • u的大小
  • v的大小
  • u,v夾角的餘弦。

在u,v非零的前提下,點積如果爲負,則u,v形成的角大於90度;如果爲零,那麼u,v垂直;如果爲正,那麼u,v形成的角小於90度。

[編輯]反正切

反正切函數對於一個給定的正切值,返回一個在-pi/2到pi/2之間的角(即-90度至+90度)。C中另外有一個函數atan2,給出y分量和x分量(注意順序!),計算向量與x正半軸的夾角,在-pi到pi之間。它的優點就是不需擔心被0除,也不需爲了處理x爲負的情況而寫代碼修改角。atan2函數幾乎比普通的atan函數更簡單,因爲只需調用一次。

[編輯]全面考慮問題

這些幾何問題大多都產生很多特殊情況。注意這些特殊情況並且要保證自己的程序能處理所有的情況

浮點運算也會帶來新問題。浮點運算很難精確,因爲注意:計算機只能計算有限的精度。特別地,要通過判斷兩個值的差是否在一個很小的範圍內來判斷是否相等。

[編輯]計算幾何算法

這裏是一些能幫助你計算幾何問題的東西。

[編輯]三角形面積

爲了計算由點(A,B,C)構成的三角形的面積,先選取一個頂點(例如A),再向剩餘兩個頂點作向量(令u=b-a, v=c-a)。三角形(A,B,C)的面積即爲u,v叉積長度的一半。

設兩邊長爲a,b,夾角爲A,面積S即 S=1/2*a*b*sinA

Geom1.gif

另一個求三角形面積的變通方法就是用海倫公式。如果三角形三邊長爲a,b,c,令s=(a+b+c)/2,那麼三角形面積就是:

   sqrt(s*(s-a)*(s-b)*(s-c))

[編輯]兩條線段平行嗎?

爲了判斷兩條線段是否平行,分別沿兩條線段建立向量,判斷叉積是否(幾乎爲)零。

[編輯]多邊形面積

由點(x1,y1)...(xn,yn)組成的多邊形的面積等於下列行列式的值:

 1   | x1 x2 ... xn |
---  |              |
 2   | y1 y2 ... yn |

也等於下面的式子的值:

1/2*abs(x1y2 + x2y3 + ... + xny1 - y1x2 - y2x3 - ... - ynx1)

就是選取原點作標準 連接原點和個頂點 並且兩兩個地計算叉積並加起來

[編輯]點到直線的距離

點P到直線AB的距離也可以由叉積給出,準確的說,d(P,AB) = |(P - A) x (B - A)| / | B - A| 。

點P到由點A,B和C確定的平面的距離,令n = (B - A) x (C - A),那麼d(P,ABC) = (P-A) · n / |n|。

[編輯]點在直線上

如果點到直線的距離是0,那麼點在直線上。

[編輯]點都在直線的同側

只講兩個點的情況。如果要確定點C和D是否在直線AB同側,計算(B - A) x (C - A)和(B - A) x (D - A)的z分量。如果同號(或如果積爲正),那麼點C,D在直線AB同側。

[編輯]點在線段上

爲了求出點C是否在線段AB上,先判斷點C是否在直線AB上,再判斷線段AB的長度是否等於線段AC長度與線段BC長度之和。

[編輯]點在三角形內

要確定點A是否在三角形內,首先選擇一個三角形內部的點B(重心就很不錯)。接下來,判斷點A,B是否都在三邊所在的三條直線的同側。

Geom3.gif

[編輯]點在凸多邊形內

方法同上

Geom4.gif

[編輯]四點(或更多)共面

如果要確定一組點是否共面,任選3個點。如果對於任意點D,有((B - A) x (C - A)) · (D - A) = ~0,那麼這些點共面。

[編輯]兩條直線相交

平面內兩條直線相交當且僅當直線不平行。

空間內,兩直線AB,CD相交則AB,CD不平行,且點A,B,C,D共面。

[編輯]兩條線段相交

平面內,兩條線段相交當且僅當A,B在直線CD異側且C,D在直線AB異側。

Geom5.gif

注意兩個判斷都是必須的,例如第三種情況第一個判斷爲true,但第二個判斷說明線段AB,CD不相交。在空間中,計算下面方程組,其中i,j未知:

Ax + (Bx - Ax) i = Cx + (Dx - Cx) j

Ay + (By - Ay) i = Cy + (Dy - Cy) j

Az + (Bz - Az) i = Cz + (Dz - Cz) j

如果方程組有解(i,j)滿足0<=i<=1,0<=j<=1,那麼兩線段相交於點(Ax + (Bx - Ax)i, Ay + (By - Ay)i, Az + (Bz - Az) i)

[編輯]兩直線的交點

在平面內的兩條直線AB,CD,求交點最直接的方法就是解下列的二元一次方程組:

Ax + (Bx - Ax)i = Cx + (Dx - Cx) j

Ay + (By - Ay)i = Cy + (Dy - Cy) j

交點是:

(Ax + (Bx - Ax) i, Ay + (By - Ay) i)

空間內,解同樣的方程組來判斷交點,交點是:

(Ax + (Bx - Ax)i, Ay + (By - Ay)i, Az + (Bz - Az)i)

[編輯]判斷平面內多邊形的凹凸性

要判斷平面內一多邊形是否爲凸,沿着順時針方向掃一遍。對於每三個點(A,B,C),計算叉積(B - A) x (C - A)。如果叉積的z分量均爲負,多邊形則爲凸多邊形。

[編輯]點在凹多邊形內

要確定點是否在凹多邊形內,任選一點作射線,計算相交次數。如果與多邊形相交於一點或一邊,則換一個方向,否則,點在多邊形內當且僅當射線與點相交次數爲奇數。

Geom8.gif

這個方法也可以擴展到三維(或更高),但此時應相交於面(再判斷),不是在點上或邊上。

[編輯]幾何方法

這些幾何方法介紹了一些技巧,可以用來優化時間和求得更精確的解。

[編輯]蒙特卡洛方法(Monte Carlo)

第一個方法是建立在隨機化之上的。它不去直接計算某件事的概率,而是以一個隨機事件來模擬,求得事件發生的頻率。如果次數足夠,頻率和概率的差別會很小。

這對於確定某些東西來說是很有用的,例如計算某個圖形的面積。它不去直接計算面積,而是建立一個已知大小的區域,每次向該區域扔一個“飛鏢”,並計算擊中區域內圖形的頻率。如果計算足夠精確,就可以得到實際面積的一個足夠好的近似值。

這個方法要得到一個足夠小的相對誤差(誤差於實際值之商),需要大量成功發生的事件。如果發生的概率很小,結果就不好了。

[編輯]分割技術

分割技術可用來優化時間。這需要把平面分割成小塊(通常是分成小格,但有時也會用角度或其它方法),並將元素放入合適的區域中。當檢查圖案的某部分時,只有有該圖案的格子會被檢查到。所以,時間可以大大地優化,比如,要確定到定點的距離小於某個值的元素(此時圖案是個圓),或求是否相交(此時圖案爲直線)。

Geom9.gif

[編輯]轉化爲圖

有時看起來像幾何問題的問題實際上卻是一個圖的問題。因爲輸入是平面內的點,並不代表問題是幾何問題。

[編輯]例子

[編輯]Point Moving

給定一組線段和點A,B,能否在不穿過線段的情況下從A移動到B?

線段將平面分割成不同部分,檢查A,B是否在一個部分。

[編輯]Bicycle Routing

給出有起點和終點的一組建築物,找出從建築物A到B不穿過任何建築物的最短路線。

題解:圖論問題。以建築物的起點和終點爲點,兩點之間在不徑直穿過任何建築物時連一條邊,邊權爲兩點之間的距離。這樣就把原問題轉化成了最短路問題。

[編輯]Maximizing Line Intersections

給出平面內一組點,找到能被一條直線能相交到的最多線段。

題解:很顯然,直線必須經過兩個交點。這樣,枚舉每對交點,計算此時直線的交點數。可用分割法優化。

[編輯]Polygon Classification

給出一組直線所確定的多邊形,判斷多邊形是否是簡單的(任意兩條不相鄰的線段不會相交)和凸的.

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