directx數學基礎

2021-04-12 20:32:14 字數 4118 閱讀 1018

向量(也叫向量,英文叫vector)

向量就是包含大小(長度)和方向的乙個量。向量有2維的,也有3維甚至4維的。在dx的所有結構體中,有乙個結構體是用來表示3維向量的,它就是d3dvector,這個結構體很簡單,只有三個成員:x、y、z。一般來說,如果不涉及到向量運算的話,用這個結構體來定義乙個向量就可以了。我們可以它來表示方向以及頂點在3d世界中的位置等。如果你要對那些向量進行一些運算的話,使用d3dvector就很不方便了,因為在d3dvector這個結構體中沒有過載任何的運算子,如果想要做乙個加法運算,就得分別對結構體中的每乙個成員進行運算了。嘿嘿,不用怕,在dx裡面有個叫d3dx的東東(包含d3dx.h標頭檔案),它裡面定義了很多方便我們進行數學計算的函式和結構。其中就有d3dxvector2,d3dxvector3,d3dxvector4這三個結構體。看它們的名字就應該知道它們的作用了吧。對於2維和4維的結構體這裡就不講了,其實它們也很簡單,和d3dxvector3差不多。不過要說明一點的是d3dxvector3是從d3dvector派生過來的,說明它和d3dvector一樣,有x、y、z這三個成員,除此之外,d3dxvector3還過載了小部分算術運算子,這樣我們就可以像對待整型那樣對d3dxvector3的物件進行加減乘除以及判斷是否相等的運算了。同時,由於d3dxvector3是從d3dvector派生過來的,所以兩者的物件可以互相賦值,在這兩種型別中隨便轉換。

還是簡單說一下向量的數**算吧。向量的加減法很簡單,就是分別把兩個向量的各個分量作加減運算。向量的乘除法也很簡單,它只能對乙個數值進行乘除法,運算的結果就是向量中的各個分量分別對那個數值進行乘除法後得出的結果。向量的模就是向量的長度,就是各個分量的平方的和的開方。向量的標準化就是使得向量的模為1,這對在3d世界中實現光照是很有用的。對於向量的運算,還有兩個「乘法」,那就是點乘和叉乘了。點乘的結果就是兩個向量的模相乘,然後再與這兩個向量的夾角的余弦值相乘。或者說是兩個向量的各個分量分別相乘的結果的和。很明顯,點乘的結果就是乙個數,這個數對我們分析這兩個向量的特點很有幫助。如果點乘的結果為0,那麼這兩個向量互相垂直;如果結果大於0,那麼這兩個向量的夾角小於90度;如果結果小於0,那麼這兩個向量的夾角大於90度。對於叉乘,它的運算公式令人頭暈,我就不說了,大家看下面的公式自己領悟吧……

//v3 = v1 x v2

v3.x = v1.y*v2.z – v1.z*v2.y

v3.y = v1.z*v2.x – v1.x*v2.z

v3.z = v1.x*v2.y – v1.y*v2.x

是不是很難記啊,如果暫時記不了就算了。其實我們主要還是要知道叉乘的意義。和點乘的結果不一樣,叉乘的結果是乙個新的向量,這個新的向量與原來兩個向量都垂直,至於它的方向嘛,不知大家是否還記得左手定則。來,伸出你的左手,按照第乙個向量(v1)指向第二個向量(v2)彎曲你的手掌,這時你的拇指所指向的方向就是新向量(v3)的方向了。通過叉乘,我們很容易就得到某個平面(由兩個向量決定的)的法線了。

終於寫完了上面的文字,描述數學問題可真是費勁,自己又不願意畫圖,辛苦大家了。如果你覺得上面的文字很枯燥,那也沒關係。因為上面的不是重點,下面介紹的函式才是希望大家要記住的。

d3dx中有很多很有用的函式,它們可以幫助我們實現上面所講的所有運算。不過下面我只說和d3dxvector3有關的函式:

計算點乘:float d3dxvec3dot(

const d3dxvector3* pv1,

const d3dxvector3* pv2)

計算叉乘:d3dxvector3* d3dxvec3cross(

d3dxvector3* pout,

const d3dxvector3* pv1,

const d3dxvector3* pv2)

計算模:float d3dxvec3length(

const d3dxvector3* pv)

標準化向量:d3dxvector3* d3dxvec3normalize(

d3dxvector3* pout,

const d3dxvector3 pv)

對於d3dxvector3的加減乘除運算,上面已經講了,用+ - * / 就行了。

矩陣與矩陣運算

什麼是矩陣?這個概念還真不好解釋,不過學過線性代數的人肯定都知道矩陣長什麼樣,那我在這裡就不解釋了。在d3d中,定義矩陣的結構體是d3dmatrix:

typedef struct _d3dmatrix ;

float m[4][4];

};} d3dmatrix;

看這個結構的樣子,你就應該很清楚怎麼使用它來定義乙個矩陣了吧。在這裡我順便說一下c++中union的特性吧。像上面定義的結構體所示,在union裡面有兩個部分,乙個是結構體,另乙個是二維陣列,它有16個元素。在union中,所有的成員都是共用乙個記憶體塊的,這是什麼意思呢?繼續看上面的**,結構體中的成員_11和成員m陣列的第乙個元素是共用乙個記憶體空間,即它們的值是一樣的,你對_11賦值的同時也對m[0][0]進行了賦值,_11和m[0][0]的值是一樣的。這樣有什麼好處呢?比如你定義了乙個矩陣變數d3dmatrix mat;你想訪問矩陣中第三行第四列的元素,可以這樣做:mat._34;另外也可以這樣:mat.m[2][3](陣列是從位置0開始儲存的哦)。看起來使用後者比較麻煩,不過當你把中括號裡面的數換成i和j,使用mat.m[i][j]來訪問矩陣中的元素,你就應該知道它的好處了吧。

實際上直接使用d3dmatrix的情況不多,因為在d3dx中有個更好的結構體,那就是d3dxmatrix。和d3dxvector3相似,d3dxmatrix是從d3dmatrix繼承過來的,它過載了很多運算子,使得矩陣的運算很簡單。矩陣的運算方法我不打算多說了,下面只介紹和矩陣性質有關的三個函式。

產生乙個單位矩陣:d3dxmatrix *d3dxmatrixidentity(

d3dxmatrix *pout);//返回結果

求轉置矩陣:d3dxmatrix *d3dxmatrixtranspose(

d3dxmatrix *pout,//返回的結果

const d3dxmatrix *pm );//目標矩陣

求逆矩陣:d3dxmatrix *d3dxmatrixinverse(

d3dxmatrix *pout,//返回的結果

float *pdeterminant,//設為0

const d3dxmatrix *pm );//目標矩陣

至於什麼是單位矩陣,什麼是轉置矩陣,什麼是逆矩陣我就不說了,可以看一下線性代數的書,一看就明白了。簡單的加減乘除法可以使用d3dxmatrix結構體裡面過載的運算子。兩個矩陣相乘也可以用函式來實現,這將在接下來的矩陣變換中講到。

矩陣變換

矩陣的基本變換有三種:平移,旋轉和縮放。

平移:d3dxmatrix *d3dxmatrixtranslation(

d3dxmatrix* pout,//返回的結果

float x, //x軸上的平移量

float y, //y軸上的平移量

float z) //z軸上的平移量

繞x軸旋**

d3dxmatrix *d3dxmatrixrotationx(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞y軸旋**

d3dxmatrix *d3dxmatrixrotationy(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞z軸旋**

d3dxmatrix *d3dxmatrixrotationz(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞指定軸旋**

d3dxmatrix *d3dxmatrixrotationaxis(

d3dxmatrix *pout,//返回的結果

const d3dxvector3 *pv,//指定軸的向量

float angle//旋轉的弧度

);縮放:

d3dxmatrix *d3dxmatrixscaling(

d3dxmatrix* pout, //返回的結果

float sx, //x軸上縮放的量

float sy, //y軸上縮放的量

float sz //z軸上縮放的量

);

DirectX學習 數學基礎 1

向量的基本運用 建立3d向量 typedef struct d3dxvector3 public d3dvector d3dxvector3 const float d3dxvector3 const d3dvector d3dxvector3 const d3dxfloat16 d3dxvecto...

DirectX學習 數學基礎 2

矩陣的基本運用 矩陣的作用是對點和向量進行變換 例如平移之類的操作 directx使用4x4矩陣,因為通常在把向量和點擴充套件一維變成乙個4d向量 最後一維分別為0或1,0是向量,1是點 因為最後一維為0則,平移矩陣對向量影響為0,聯絡平移矩陣的特點容易得出該結論。建立並使用4 4矩陣 includ...

DirectX基礎學習系列5 融合技術

7.1融合方程 1概念融合技術將當前光柵化畫素的顏色與以前已光柵化並處於同乙個位置的畫素顏色進行合成,即將當前要進行光柵化的三角形單元與已寫入後台的畫素進行融合 2需要遵循的原則 1 先繪製不需要融合的物體 2 需要融合的物品按照攝像機的深度值進行排序 3融合方程 color rgbsrc ksrc...