在XNA中,和向量類似,矩陣也被定義成一個結構體,使其在計算的時候速度有所保證。XNA中只定義了一個4X4的矩陣。這可能和其他的一些三維數學或三維平台不太一樣。雖然這在系統運行時可能會造成記憶體的浪費,但只有一種矩陣,可以大大減少開發的難度。而且4X4矩陣能夠儲存物體的位置,旋轉,位移,縮放等資訊。(以上絕大部分來至於我自己的猜想)
在看矩陣的結構時,在開頭的時候就能看到矩陣的一些複寫的操作符。從函數個數上來看,矩陣的定義似乎比向量要簡單一些。但矩陣中每個函數裡面的演算法要比向量複雜的多。幸好XNA給我們封裝了大多數矩陣運算的功能,讓我們不用關心那麼複雜的演算法。如果你要是能理解那些演算法的話,也就最好不過了。那樣的話,你就能夠瞭解三維繫統在啟動並執行時候,背後都是進行的哪些運算,什麼時候該用什麼運算效率是最高的。還有系統效能的瓶頸在什麼地方,需要以後怎麼改進。恩,我覺得還是很有必要研究一下底層的三維數學的。
下面代碼為XNA矩陣中複寫的一些操作符。
public static Matrix operator -(Matrix matrix1);
public static Matrix operator -(Matrix matrix1, Matrix matrix2);
public static bool operator !=(Matrix matrix1, Matrix matrix2);
public static Matrix operator *(float scaleFactor, Matrix matrix);
public static Matrix operator *(Matrix matrix, float scaleFactor);
public static Matrix operator *(Matrix matrix1, Matrix matrix2);
public static Matrix operator /(Matrix matrix1, float divider);
public static Matrix operator /(Matrix matrix1, Matrix matrix2);
public static Matrix operator +(Matrix matrix1, Matrix matrix2);
public static bool operator ==(Matrix matrix1, Matrix matrix2);
下面的代碼,是一些屬性,得到和設定矩陣在前後左右上下方向的分向量。
public Vector3 Backward { get; set; }
public Vector3 Down { get; set; }
public Vector3 Forward { get; set; }
public Vector3 Left { get; set; }
public Vector3 Right { get; set; }
public Vector3 Translation { get; set; }
public Vector3 Up { get; set; }
這些分向量代表什麼意義呢?這個問題很難解釋清楚。首先先先直觀的解釋,最直觀的方法就是再XNA程式中聲明一個矩陣,分別看每個屬性的值。首先嗎在XNA中定義下面的矩陣。
11,12,13,14
21,22,23,24
31,32,33,34
41,42,43,44
當我們跟蹤代碼時,擷取每一個屬性的值如下:
Forward:-31,-32,-33
Backward:31,32,33
Left:-11,-12,-13
Right:11,12,13
Up:21,22,23
Down:-21,-22,-23
Translation:41,42,43
我們知道,在XNA中使用的座標系是右手座標系,座標系如:
從圖上看,Forward是不是就相當於Z軸的反方向?Backward就相當於Z軸正方向,Right和Left就相當於X軸的正負方向,Up,Down就相當於Y軸的正負方向。由此可以推斷出4X4矩陣在第一行的前三個值,即11,12,13值是在X軸上的分量,第二行前三個值即21,22,23為Y軸方向上的值,第三行前三個值31,32,33為Z軸方向上的值。這樣一來4X4矩陣的幾何意義似乎有些明了了。但具體這些代表有什麼用,到現在還不清楚。我覺得既然XNA把11,12,13三個值定義成Right,一定有其一定的道理和用法。現在不能上網,所以查資料比較麻煩,以後知道時再接著解釋。
除此之外,XNA還提供了一些其他的很有用的靜態函數,這些靜態函數為建立矩陣提供了很大的方便,隱藏了矩陣背後的複雜性。但為了瞭解本質,我們還是要把這些方法一一的來看。看建立完矩陣之後,裡面的值都是什麼樣子的。
旋轉
Matrix myMatrix = Matrix.CreateFromAxisAngle(Vector3.Right,MathHelper .Pi/6);
上面代碼的意思是圍繞X正軸旋轉30°,系統運行,讓我們看一下得到的矩陣值,如下:
1 |
0 |
0 |
0 |
0 |
0.866 |
0.5 |
0 |
0 |
-0.5 |
0.866 |
0 |
0 |
0 |
0 |
1 |
讓我們對應一下在X軸上旋轉矩陣的公式。
繞X軸的三維旋轉矩陣
下面是繞Y軸的例子:
Matrix myMatrix = Matrix.CreateFromAxisAngle(Vector3.Up,MathHelper .Pi/6);
0.866 |
0 |
-0.5 |
0 |
0.5 |
1 |
0 |
0 |
0.5 |
0 |
0.866 |
0 |
0 |
0 |
0 |
1 |
繞y軸的三維旋轉矩陣
下面是繞Z軸的例子
Matrix myMatrix = Matrix.CreateFromAxisAngle(Vector3.Backward,MathHelper .Pi/6);
0.866 |
0.5 |
0 |
0 |
-0.5 |
0.866 |
0 |
0 |
0.5 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
繞Z軸旋轉矩陣公式
下面看一下沿著任意軸旋轉的執行個體。
Matrix myMatrix = Matrix.CreateFromAxisAngle(new Vector3(1,2,3),MathHelper .Pi/6);
1 |
1.7679 |
-0.598 |
0 |
-1.2320 |
1.4019 |
1.3038 |
0 |
1.4019 |
3,3038 |
2.07179 |
0 |
0 |
0 |
0 |
1 |
沿著任意矩陣旋轉。
這些公式怎麼來的,有複雜的數學推算。太難了,不過XNA已經幫我們封裝好了,我們直接就可以用,不用管背後複雜的公式和晦澀的公式推導。不過要是感興趣的話,看看還是不錯的。
而且XNA還提供給了一些快捷的旋轉操作,例如繞X軸旋轉,繞Y軸旋轉等。定義如下:
public static Matrix CreateRotationX(float radians);
public static Matrix CreateRotationY(float radians);
public static Matrix CreateRotationZ(float radians);
縮放
Matrix myMatrix = Matrix.CreateScale(2, 3, 4);
分別沿x,y,z軸擴大2,3,4倍。
2 |
0 |
0 |
0 |
0 |
3 |
0 |
0 |
0 |
0 |
4 |
0 |
0 |
0 |
0 |
1 |
公式如下:
平移
Matrix myMatrix = Matrix.CreateTranslation(2, 3, 4);
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
2 |
3 |
4 |
1 |
可見平移主要用到了第四組向量。