矩阵
假设,在空间上有一个点,使用xyz描述它的位置,此时让其围绕任意位置旋转一定角度后,我们需要知道这个点的新的位置,此时需要通过矩阵进行计算。为什么呢?
因为新的位置的x不单纯与原来的x海河旋转的参数有关,甚至与y和z坐标有关。
![](https://img.haomeiwen.com/i1398407/af9bf22f8caf3470.jpg)
矩阵只有一行或者一列都是合理的,只有一行或者一列数字的可以称为向量,也可以称为矩阵。
代码参考
//三维矩阵/四维矩阵的声明
typedef float M3DMatrix33f[9];
typedef float M3DMatrix44f[16];
在其他的变成标准中,许多矩阵定义一个矩阵时,使用的是二维数组;OpenGL的约定里,更倾向使用一个一维数组;这样做的原因是:OpenGL使用的是Column-Major(以列为主)矩阵排序的约定。这个在数学中叫做转置矩阵。
行优先矩阵
从左到右一行一行的读取。
![](https://img.haomeiwen.com/i1398407/2c195911a9c5bd1f.jpg)
列优先矩阵
从上往下一列一列读取。
![](https://img.haomeiwen.com/i1398407/f8a67b1c2d69d5b0.jpg)
矩阵表示位置和方向
![](https://img.haomeiwen.com/i1398407/1063bb79b4abcb09.jpg)
一个4*4的矩阵是如何在3D空间中表示一个位置和方向的呢?
奥秘之出在于这16个值表示空间中一个特定的位置;这4列中,每以列都是有4个元素组成的向量。
如果将一个对象所有的顶点向量乘以这个矩阵,就能让整个对象变换到空间中给定的位置和方向。
列向量进行了特别的标注:矩阵的最后一行都为0,只有最后一个元素为1。
单元矩阵
初始化
//单元矩阵初始化方式1
GLFloat m[] = {
1,0,0,0, //X Column
0,1,0,0, //Y Column
0,0,1,0, //Z Column
0,0,0,1 // Translation
}
//单元矩阵初始化方式2
M3DMatrix44f m = {
1,0,0,0, //X Column
0,1,0,0, //Y Column
0,0,1,0, //Z Column
0,0,0,1 // Translation
}
//单元矩阵初始化⽅方式3
void m3dLoadIdentity44f(M3DMatrix44f m);
将一个向量乘以单元矩阵,就相当于一个向量乘1,不会发生任何改变。
![](https://img.haomeiwen.com/i1398407/d711ffff58d678c5.jpg)
在线性代数中,为了方便书写,所以坐标的计算,都是从左往右的顺序,如下列公式:
变换后顶点向量 = V_local * M_model * M_view * M_pro
变换后顶点向量 = 顶点 x 模型矩阵 x 观察矩阵 x 投影矩阵
![](https://img.haomeiwen.com/i1398407/edb8237b16ddf1c3.jpg)
在OpenGL的角度上来看,如下列公式:
变换顶点向量 = M_pro * M_view * M_model * V_local
变化顶点向量 = 投影矩阵 x 视图变换矩阵 x 模型矩阵 x 顶点
![](https://img.haomeiwen.com/i1398407/39dca8a559c2e2b2.jpg)
矩阵的点乘
- 矩阵可以进行点乘的前提:两个矩阵的行列数相等。
- 矩阵A · 矩阵B = 矩阵C。
- 规则: 矩阵A的第一个元素与矩阵B的第一个元素的乘积 = 矩阵C的第一个元素。
![](https://img.haomeiwen.com/i1398407/b53d295990e0a67c.jpg)
矩阵的叉乘
- 矩阵可以进行叉乘的前提:第一个矩阵的列数 = 第二个矩阵的行数。
- 矩阵A X 矩阵B = 矩阵C。
- 规则:矩阵A第一行与矩阵B第一列对应元素乘积的综合 = 矩阵C的第一个元素。
![](https://img.haomeiwen.com/i1398407/2ec1755b72b28269.jpg)
OpenGL中的矩阵
inline void MultMatrix(const M3DMatrix44f mMatrix) {
M3DMatrix44d mTemp;
m3dCopyMatrix44(mTemp, pStack[stackPointer]);
m3dMatrixMultiply44(pStack[stackPointer], mTemp, mMatrix);
}
- 从栈顶获取栈顶矩阵,复制到mTemp。
- 将栈顶矩阵mTemp左乘mMatrix。
- 将结果放回栈顶空间里。
示例代码:
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrame cameraFrame;
GLFrame viewFrame;
// 投影矩阵:projectionMatrix
modelViewMatrix.PushMatrix();
M3DMatrix44f pm;
projectionMatrix.GetMatrix(pm);
modelViewMatrix.MultMatrix(pm);
// 观察者(视图变换)矩阵:viewMatrix
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
// 模型变换矩阵
M3DMatrix44f mObjectFrame;
viewFrame.GetMatrix(mObjectFrame);
modelViewMatrix.MultMatrix(mObjectFrame);
网友评论