D3D編程必備的數(shù)學(xué)知識(shí)(5)
平面
D3DX平面
在代碼中描述一個(gè)平面:僅僅需要一個(gè)法向量n和常數(shù)d就可以了。因此我們就使用一個(gè)4D向量(我們記錄成(n, d))來實(shí)現(xiàn)它。D3DX庫中用如下的結(jié)構(gòu)來定義一個(gè)平面:
typedef struct D3DXPLANE
{
#ifdef __cplusplus
public:
D3DXPLANE() {}
D3DXPLANE( CONST FLOAT* );
D3DXPLANE( CONST D3DXFLOAT16* );
D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d );
// casting
operator FLOAT* ();
operator CONST FLOAT* () const;
// unary operators
D3DXPLANE operator + () const;
D3DXPLANE operator - () const;
// binary operators
BOOL operator == ( CONST D3DXPLANE& ) const;
BOOL operator != ( CONST D3DXPLANE& ) const;
#endif //__cplusplus
FLOAT a, b, c, d;
} D3DXPLANE, *LPD3DXPLANE;
對(duì)照等式(8)可知:這里a, b和c是平面法向量n的成員,d就是那個(gè)常數(shù)。
點(diǎn)和平面的空間關(guān)系
我們判定點(diǎn)和平面的關(guān)系主要是利用等式(8)來實(shí)現(xiàn)。例如,假設(shè)平面(n, d),我們能判定點(diǎn)p和平面的關(guān)系:
假如n·p + d = 0,那么點(diǎn)p與平面共面。
假如n·p + d >0,那么點(diǎn)p在平面的前面且在平面的正半空間里。
假如n·p + d <0,那么點(diǎn)p在平面的背面且在平面的負(fù)半空間里。
下邊的D3DX函數(shù)就是利用n·p + d 來判定點(diǎn)和平面的關(guān)系的函數(shù):
FLOAT D3DXPlaneDotCoord(
CONST D3DXPLANE *pP, // 平面
CONST D3DXVECTOR3 *pV // 點(diǎn)
);
// 測(cè)試點(diǎn)相對(duì)于平面的位置 D3DXPLANE p(0.0f, 1.0f, 0.0f, 0.0f); D3DXVECTOR3 v(3.0f, 5.0f, 2.0f); float x = D3DXPlaneDotCoord( &p, &v );
if( x approximately equals 0.0f ) // v在平面.上 if( x > 0 ) // v在正半空間 if( x < 0 ) // v在負(fù)半空間 |
創(chuàng)建平面
我們能通過兩種方法創(chuàng)建平面。
第一種方法,直接用指定法線和點(diǎn)創(chuàng)建平面。假設(shè)法線n和在平面上的已知點(diǎn)p0,我們就能求出d:
n·p0+ d = 0
n·p0 = -d
-n·p0 = d
D3DX庫提供如下函數(shù)來完成創(chuàng)建平面的任務(wù):
D3DXPLANE *D3DXPlaneFromPointNormal( D3DXPLANE* pOut, // Result. CONST D3DXVECTOR3* pPoint, // Point on the plane. CONST D3DXVECTOR3* pNormal // The normal of the plane. ); |
第二種方法,我們能通過在平面上的3個(gè)點(diǎn)創(chuàng)立一個(gè)平面。
假如有點(diǎn)p0, p1, p2,那么我們就能得到平面上的兩個(gè)向量:
u = p1 - p0
v = p2 - p0
因此我們能通過把平面上的兩個(gè)向量進(jìn)行叉乘得到平面的法線。回憶左手坐標(biāo)系。
n = u × v
Then, -(n · p0) = d.
D3DX庫提供如下函數(shù)來完成通過同一平面上的3個(gè)點(diǎn)確定一個(gè)平面:
D3DXPLANE *D3DXPlaneFromPoints( D3DXPLANE* pOut, // Result. CONST D3DXVECTOR3* pV1, // Point 1 on the plane. CONST D3DXVECTOR3* pV2, // Point 2 on the plane. CONST D3DXVECTOR3* pV3 // Point 3 on the plane. ); |
變換平面
我們能夠通過如下處理來變換一個(gè)面(n, d),就象一個(gè)4D向量通過乘以它所期望的變換矩陣的逆矩陣一樣來達(dá)到變換目的。注意平面的法向量必須首先被標(biāo)準(zhǔn)化。
我們能用下面的D3DX函數(shù)來完成操作:
D3DXPLANE *D3DXPlaneTransform( D3DXPLANE *pOut, // Result CONST D3DXPLANE *pP, // Input plane. CONST D3DXMATRIX *pM // Transformation matrix. ); |
示例代碼:
D3DXMATRIX T(...); // Init. T to a desired transformation. D3DXMATRIX inverseOfT; D3DXMATRIX inverseTransposeOfT; D3DXMatrixInverse( &inverseOfT, 0, &T ); D3DXMatrixTranspose( &inverseTransposeOfT, &inverseOfT ); D3DXPLANE p(...); // Init. Plane. D3DXPlaneNormalize( &p, &p ); // make sure normal is normalized. D3DXPlaneTransform( &p, &p, &inverseTransposeOfT ); |
射線(可選的)
設(shè)想在游戲中的一個(gè)玩家,正用他的槍射擊敵人。我們?cè)趺磁袛嘧訌検欠駨囊粋€(gè)位置擊中另一個(gè)位置的目標(biāo)?一個(gè)方法是用一條射線模擬子彈,用一個(gè)球體模型模擬敵人。(球體模型只是一個(gè)球體,它緊緊的圍繞一個(gè)物體,從而粗略地表示它的大小。球體模型將在第11章中做更詳細(xì)的介紹。)那么通過計(jì)算我們就能夠判定是否射中球體。在這部分我們學(xué)習(xí)射線的數(shù)學(xué)模型。
射線
一條射線能用一個(gè)起點(diǎn)和方向來描述。射線的參數(shù)方程是:
線/面相交
假設(shè)一條射線p(t) = p0 + tu 和 一個(gè)平面n·p + d = 0,我們想知道射線是否與平面相交,以及相交的交點(diǎn)信息(如果相交的話)。照這樣做,我們把射線代入平面方程并且求滿足平面方程的參數(shù)t,解答出來的參數(shù)就是相交的點(diǎn)。
把等式(9)代入平面方程:
posted on 2008-03-12 14:03 lovedday 閱讀(1463) 評(píng)論(0) 編輯 收藏 引用