// 三维向量/四维向量的声明
typedef float M3DVector3f[3];
typedef float M3DVector4f[4];
// 声明⼀个三维向量 M3DVector3f:类型 vVector:变量名
M3DVector3f vVector;
// 声明一个四维向量并初始化⼀个四维向量
M3DVector4f vVertex = {0,0,1,1};
// 声明一个三分量顶点数组,例如生成⼀个三角形
M3DVector3f vVerts[] = {
-0.5f,0.0f,0.0f,
0.5f,0.0f,0.0f,
0.0f,0.5f,0.0f};
// m3dDotProduct3 函数获得2个向量之间的点乘结果,即余弦值cosα
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
// m3dGetAngleBetweenVector3 即可获取2个向量之间夹角的弧度值 α = arccos余弦
float m3dGetAngleBetweenVector3(const M3DVector3f u,const M3DVector3f v);
// m3dCrossProduct3 函数获得2个向量之间的叉乘结果得到⼀个新的向量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const
M3DVector3f v);
// 三维矩阵/四维矩阵的声明
typedef float M3DMatrix33f[9];
typedef float M3DMatrix44f[16];
OpenGL 使⽤的是 Column-Major(以列为主)矩阵排序的约定;⾏优先矩阵(左)和列优先矩阵(右)如下图所示:
⾏优先矩阵与列优先矩阵互为转置矩阵;
矩阵的这16个值表示空间中⼀个特定的位置; 这4列中,每⼀列都是有4个元素组成的向量;(第一列:X轴方向,第二列:Y轴方向,第三列:Z轴方向,第四列:交换位置);
如果将⼀个对象所有的顶点向量乘以矩阵,就能让整个对象变换到空间中给定的位置和⽅向;
列向量进行了特别的标注:矩阵的最后⼀行都为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);
在线性代数中:
变换后顶点向量 = V_local * M_model * M_view * M_pro
变换后顶点向量 = 顶点 ✖ 模型矩阵 ✖ 观察矩阵 ✖ 投影矩阵
在OpenGL 的维度,如下列公式:
变换顶点向量 = M_pro * M_view * M_model * V_local
变换顶点向量 = 投影矩阵 ✖ 视图变换矩阵 ✖ 模型矩阵 ✖ 顶点
矩阵左乘的代码如下:
从栈顶获取栈顶矩阵复制到 mTemp;将栈顶矩阵 mTemp 左乘 mMatrix;将结果放回栈顶空间⾥;
inline void MultMatrix(const M3DMatrix44f mMatrix) {
// 矩阵左乘
M3DMatrix44f mTemp;
m3dCopyMatrix44(mTemp, pStack[stackPointer]);
m3dMatrixMultiply44(pStack[stackPointer], mTemp, mMatrix);
}
inline void MultMatrix(GLFrame& frame) {
M3DMatrix44f m;
frame.GetMatrix(m);
MultMatrix(m);
}
// 投影矩阵 projectionMatrix
modelViewMatrix.PushMatrix();
M3DMatrix44f pm;
projectionMatrix.GetMatrix(pm);
modelViewMatrix.MultMatrix(pm);
// 观察者矩阵 viewMatrix
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
// 模型变换矩阵 modelMatrix
M3DMatrix44f mObjectFrame;
viewFrame.GetCameraMatrix(mObjectFrame);
modelViewMatrix.MultMatrix(mObjectFrame);
A.dot(B)操作相当于数学向量运算中的点乘,也叫向量的内积、数量积;
对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量;
Mat矩阵的dot方法扩展了一维向量的点乘操作,把整个Mat矩阵扩展成一个行(列)向量,之后执行向量的点乘运算,仍然要求参与dot运算的两个Mat矩阵的行列数完全一致;
dot方法声明中显示返回值是double,所以A.dot(B)结果是一个double类型数据,不是Mat矩阵,不能把A.dot(B)结果赋值给Mat矩阵。
dot操作不对参与运算的矩阵A、B的数据类型做要求,CV_8UC1、CV_32FC1等,可以是任何Opencv定义的类型;
若参与dot运算的两个Mat矩阵是多通道的,则计算结果是所有通道单独计算各自.dot之后,再累计的和,结果仍是一个double类型数据。