1. 程式人生 > >OpenGL 矩陣的旋轉-平移-縮放

OpenGL 矩陣的旋轉-平移-縮放

1.  openGL的矩陣

openGL的矩陣是列優先排序的。就是說,矩陣的資料是存貯在一維陣列中,資料上傳到openGL處理的時候,會把一維資料的每一行當做列來處理。比如說,一個4*4的矩陣在陣列中的排列如下:

matrix44 = {
   m0,   m1,   m2,   m3,
   m4,   m5,   m6,   m7,
   m8,   m9,   m10,  m11,
   m12,  m13,  m14,  m15,
}

當被傳輸到openGL會當做下面這樣的矩陣來處理:


由圖可見,m0, m1, m2 表示了x軸, m4, m5, m6 表示了y軸, m8, m9, m10 表示了z軸, 而m12, m13, m14表示了平移量。而最後一行的,m3, m7, m11, m15是齊次座標。唯有m15等於1是為了,在做矩陣計算的時候,平移量影響到平移量本身,而不會影響到xyz軸的數值。

2.  單位矩陣

沒有任何旋轉,平移,縮放的矩陣用單位矩陣來表示。所有的旋轉,平移,縮放,都是在單位矩陣的基礎上進行的。如下:

{
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
};

可見單位矩陣的xyz軸都是單位向量平移向量為0

3.  矩陣乘法

旋轉,平移,縮放的資料變化是通過矩陣乘法把數值存貯在矩陣中的。簡單描述一下矩陣乘法的規則,就是左邊矩陣決定結果矩陣的行,右邊矩陣決定結果矩陣的列。那麼計算的過程是,左邊矩陣的行,元素對應乘以,右邊矩陣的列,得到的值在結果矩陣的位置就是,左邊矩陣的行右邊矩陣的列。

4. 矩陣按照某個向量平移

	matrix->m[12] += matrix->m[0] * tx + matrix->m[4] * ty + matrix->m[8]  * tz;
	matrix->m[13] += matrix->m[1] * tx + matrix->m[5] * ty + matrix->m[9]  * tz;
	matrix->m[14] += matrix->m[2] * tx + matrix->m[6] * ty + matrix->m[10] * tz;
	matrix->m[15] += matrix->m[3] * tx + matrix->m[7] * ty + matrix->m[11] * tz;

平移向量即是(tx, ty, tz),  我們做乘法的時候需要按照openGL處理矩陣的方式,所以m0, m4, m8 是第一行以此類推。我們把計算的數值存貯到矩陣的平移向量裡。這裡解釋一下平移演算法。openGL實際處理的矩陣乘以向量如下:

   m0,   m4,   m8,   m12,       tx
   m1,   m5,   m9,   m13,   *   ty 
   m2,   m6,   m10,  m14,       tz
   m3,   m7,   m11,  m15,       1

(m0, m1, m2)  和 (m4, m5, m6) 和 (m8, m9, m10) 是x, y, z三個軸的單位向量,那麼變換後的向量可以寫成, v = tx(m0, m1, m2) + ty(m4, m5, m6) + tz(m8, m9, m10) , 可以看成 在單位向量上進行tx, ty, tz的平移。

根據向量的乘法展開就是, (txm0, txm1, txm2) + ( tym4,  tym5,  tym6) +  (tzm8, tzm9, tzm10)

根據向量加法展開就是, (txm0 + tym4 +tzm8, txm1 + tym5 + tzm9, txm2 + tym6 + tzm10)

這就是矩陣乘以向量法則計算的結果

5. 矩陣在某個向量上縮放

	matrix->m[0]  *= sx;
	matrix->m[1]  *= sx;
	matrix->m[2]  *= sx;

	matrix->m[4]  *= sy;
	matrix->m[5]  *= sy;
	matrix->m[6]  *= sy;

	matrix->m[8]  *= sz;
	matrix->m[9]  *= sz;
	matrix->m[10] *= sz;

就是把矩陣中x, y, z向量乘以對應的縮放比例即可。

6. 矩陣在某個向量上旋轉

在任意向量上旋轉有些複雜,只說明一下特殊的情況,按照xyz軸旋轉。在數學上,我們知道點(x, y)旋轉一個a弧度後的座標是:(x * cosa - y * sina, x * sina + y * cosa), 所以我們可以得出

單位矩陣在Z軸上旋轉a弧度後的一個矩陣為:

{
	cosa,    sina, 0.0f, 0.0f,
	-sina,   cosa, 0.0f, 0.0f,
	0.0f,    0.0f, 1.0f, 0.0f,
	0.0f,    0.0f, 0.0f, 1.0f,
};

同理單位矩陣在X軸上旋轉a弧度後的矩陣:
{
	1.0f,    0.0f, 0.0f, 0.0f,
	0.0f,    cosa, sina, 0.0f,
	0.0f,   -sina, cosa, 0.0f,
	0.0f,    0.0f, 0.0f, 1.0f,
};

同理單位矩陣在Y軸上旋轉a弧度後的矩陣:
{
       cosa, 0.0f,   -sina,  0.0f,
       0.0f, 1.0f,    0.0f,  0.0f,
       sina, 0.0f,    ccosa, 0.0f,
       0.0f, 0.0f,    0.0f,  1.0f,
}

最後把需要旋轉的矩陣乘以單位矩陣的旋轉矩陣,就會把旋轉的數值儲存到結果矩陣中了。