向量幾何在遊戲程式設計中的使用3

2022-07-01 20:51:14 字數 4658 閱讀 2291

<3>2-d邊界碰撞檢測

一、使用向量進行障礙檢測的原理

在遊戲中進行障礙碰撞檢測,基本思路是這樣的:給定乙個障礙範圍,判斷物體在這次移動後會不會進入這個範圍,如果會,就發生碰撞,否則不發生碰撞。在實際操作中,是用物體的邊界來判斷還是其他部位判斷完全取決於程式設計者。這時候,就可以從這個部位沿著速度的方向引出一條速度向量線,判斷一下這條線段(從檢測部位到速度向量終點)和障礙邊界線有沒有交點,如果有,這個交點就是碰撞點。

上面物體a,在通過速度向量移動之後將到達b位置。但是,這次移動將不會順利進行,因為我們發現,碰撞發生了。碰撞點就在那個紅色區域中,也就是速度向量和邊界線的交點。 我們接下來的工作就是要計算這個交點,這是乙個解線性方程組的過程,那麼我們將要用到一樣工具...

二、乙個解線性方程組的有力工具---克蘭姆(cramer)法則

首先要說明一下的是,這個法則是有侷限性的,它必須在乙個線性方程組的係數行列式非零的時候才能夠使用。別緊張,我會好好談談它們的。首先讓我來敘述一下這個法則(我會試著讓你感覺到這不是一堂數學課):

如果線性方程組:

a11*x1 + a12*x2 + ... + a1n*xn = b1

a21*x1 + a22*x2 + ... + a2n*xn = b2

...................................

an1*x1 + an2*x2 + ... + ann*xn = bn

的係數矩陣 a =

__               __

| a11 a12 ... a1n |

| a21 a22 ... a2n |

| ....................... |

| an1 an2 ... ann |

--               -- 

的行列式 |a| != 0 

線性方程組有解,且解是唯一的,並且解可以表示為:

x1 = d1/d , x2 = d2/d , ... , xn = dn/d (這就是/a/=d為什麼不能為零的原因)

這裡d就是行列式/a/的值,dn(n=1,2,3...)是用線性方程組的常數項b1,b2,...,bn替換係數矩陣中的第n列的值得到的矩陣的行列式的值,即:

| b1 a12 ... a1n |

d1 = | b2 a22 ... a2n |

| ..................... |

| bn an2 ... ann |

| a11 b1 ... a1n |

d2 = | a21 b2 ... a2n |

| ..................... |

| an1 bn ... ann | 

...| a11 a12 ...b1 |

dn = | a21 a22 ... b2 |

| ..................... |

| an1 an2 ... bn |

別去點選關閉視窗按鈕!我現在就舉個例子,由於我們現在暫時只討論2-d遊戲(3-d以後會循序漸進的談到),就來個2-d線性方程組:

(1) 4.0*x1 + 2.0*x2 = 5.0

(2) 3.0*x1 + 3.0*x2 = 6.0

這裡有兩個方程,兩個未知量,則根據上面的cramer法則:

| 4.0 2.0 |

d = | 3.0 3.0 | = 4.0*3.0 - 2.0*3.0 = 6.0 (2階行列式的解法,'/'對角線相乘減去'/'對角線相乘)

| 5.0 2.0 |

d1 = | 6.0 3.0 | = 5.0*3.0 - 2.0*6.0 = 3.0

| 4.0 5.0 |

d2 = | 3.0 6.0 | = 4.0*6.0 - 5.0*3.0 = 9.0

則 x1 = d1/d = 3.0/6.0 = 0.5

x2 = d2/d = 9.0/6.0 = 1.5   

好了,現在就得到了方程組的唯一一組解。 

是不是已經掌握了用cramer法則解2-d線性方程組了?如果是的話,我們繼續。

三、深入研究

這裡的2-d障礙碰撞檢測的實質就是判斷兩條線段是否有交點,注意不是直線,是線段,兩直線有交點不一定直線上的線段也有交點。現在我們從向量的角度,寫出兩條線段的方程。

現在有v1v2兩條線段,則根據向量加法:

v1e=v1b+ s*v1

v2e=v2b+ t*v2

v1bv2b分別是兩線段的一端。s,t是兩個引數,它們的範圍是[0.0,1.0],當s,t=0.0時,v1e=v1b,v2e=v2b;當s,t=1.0時,v1ev2e分別是兩線段的另一端。s,t取遍[0.0,1.0]則v1ev2e取遍兩線段的每一點。

那麼我們要判斷v1v2有沒有交點,就讓v1e=v2e,看解出的s,t是不是在範圍內就可以了:

v1e=v2e

=>v1b+ s*v1=v2b+ t*v2

=> s*v1- t*v2=v2b-v1b

寫成分量形式:

s*x_v1 - t*x_v2 = x_v2b - x_v1b

s*y_v1 - t*y_v2 = y_v2b - y_v1b

現在是兩個方程式,兩個未知數,則根據cramer法則:

| x_v1   -x_v2 |    | 4.0   -2.0 |

d = | y_v1   -y_v2 | = | 1.0   -3.0 | = -10.0

| x_v2b-x_v1b   -x_v2 |    | 5.0   -2.0 |

d1 = | y_v2b-y_v1b   -y_v2 | = | 2.0   -3.0 | = -11.0           

s = d1/d = -11.0/-10.0 = 1.1 > 1.0

現在s已經計算出來,沒有在[0.0,1.0]內,所以兩線段沒有交點,從圖上看很直觀。t沒有必要再計算了。所以是物體與障礙沒有發生碰撞。如果計算出的s,t都在[0.0,1.0]內,則把它們帶入原方程組,計算出v1e或者v2e,它的分量就是碰撞點的分量。

四、理論上的東西已經夠多的了,開始寫程式

我現在要寫乙個用於處理障礙碰撞檢測的函式,為了測試它,我還準備安排一些障礙:

這是乙個凸多邊形,我讓乙個質點在初始位置(10,8),然後給它乙個隨機速度,這個隨機速度的兩個分速度在區間[1.0,4.0]內,同時檢測是否與邊界發生碰撞。當碰撞發生時,就讓它回到初始位置,重新給乙個隨機速度。

//

首先我要記下凸多邊形的邊界座標

float poly[2][8] = , //

所有點的x分量,最後乙個點和第乙個點重合

//所有點的y分量

} ;//

定義一些變數

float x , y ; //

這是質點的位置變數

float vx , vy ; //

質點的速度向量分量

//好,開始編寫碰撞檢測函式

bool collisiontest()

//for( int i = 0 ; i < 8-1 ; ++i )

//沒有發生碰撞,返回false

return

false;}

//end of function

//現在對函式做測試

//初始化質點

x = 10.0f , y = 8.0f

;vx = vy = (float)(rand()%4+1

) ;

//進入主迴圈中

//假設現在已經在主迴圈中

if( collisiontest() )

//質點移動

x+=vx ;

y+=vy ;

向量幾何在遊戲程式設計中的使用1

1 簡單的2 d追蹤 andre lamothe說 向量幾何是遊戲程式設計師最好的朋友 一點不假,向量幾何在遊戲程式設計中的地位不容忽視,因為在遊戲程式設計師的眼中,顯示螢幕就是乙個座標 系,運動物體的軌跡就是物體在這個座標系曲線運動結果,而描述這些曲線運動的,就是向量。使用向量可以很好的模擬物理現...

向量幾何在遊戲程式設計中的使用1

1 簡單的2 d追蹤 andre lamothe說 向量幾何是遊戲程式設計師最好的朋友 一點不假,向量幾何在遊戲程式設計中的地位不容忽視,因為在遊戲程式設計師的眼中,顯示螢幕就是乙個座標 系,運動物體的軌跡就是物體在這個座標系曲線運動結果,而描述這些曲線運動的,就是向量。使用向量可以很好的模擬物理現...

向量幾何在遊戲程式設計中的使用1

andre lamothe說 向量幾何是遊戲程式設計師最好的朋友 一點不假,向量幾何在遊戲程式設計中的地位不容忽視,因為在遊戲程式設計師的眼中,顯示螢幕就是乙個座標系,運動物體的軌跡就是物體在這個座標系曲線運動結果,而描述這些曲線運動的,就是向量。使用向量可以很好的模擬物理現象以及基本的ai。現在,...