向量与矩阵的应用场景和相关方法
向量
- 向量:(也称为欧几里得向量、几何向量、矢量),指具有大小(magnitude)和方向的量。在3D笛卡尔坐标系中,一个顶点就是一个(x,y,z)坐标;在空间中的一个位置由一个单独的想x,y,z定义,这样的xyz就是一个向量;
向量图.png
截屏2020-07-16下午11.54.46.png
在x轴上的向量(1,0,0),向量长度为1,我们把长度为1的向量成为单位向量; - math3d 库: 有2个数据类型,能够表示一个三维或者'四维'向量。
M3DVector3f
:可以表示一个三维向量(x,y,z)
M3DVector4f
:可以表示一个‘四维向量’(x,y,z,w), 其中w是缩放因子,通常为 1.0,在OpenGL 中 当w 不为1时,我们会通过乘以w的倒数,来转换为标准坐标向量;
//三维向量量/四维向量量的声明
typedef float M3DVetor3f[3];
typedef float M3DVetor4f[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
};
实质上就是一个存放float类型数据的一维数组。
- 向量中的点乘:单位向量1 * 单位向量2 = 值
这里需要注意的是单位向量;这里的值是一个[-1,1]范围的值,实际就是向量1和向量2夹角的cos值(余弦值);
单位化向量:(x/|xyz|, y/|xyz|, z/|xyz|)
;
点乘运算结果
math3d库中提供的点乘API:
//1.m3dDotProduct3 函数获得2个向量之间的点乘结果;
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
//2.m3dGetAngleBetweenVector3 即可获取2个向量之间夹⻆角的弧度值;
float m3dGetAngleBetweenVector3(const M3DVector3f u,const M3DVector3f v);
- 向量中的叉乘:向量1 * 向量2 = 向量3
叉乘中的向量不一定是单位向量,得到的向量3同向量1,2的平面垂直;
向量叉乘
math3d 库中提供了了关于叉乘的API
//1.m3dCrossProduct3 函数获得2个向量之间的叉乘结果得到一个新的向量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const M3DVector3f v);
矩阵
- 矩阵:是一个按照长方阵列排列的复数或实数集合。我们可以通过矩阵来对一组顶点数据进行批量变换运算。矩阵只有1行或者1列是合理的,这种矩阵也可以成为向量。
typedef float M3DMatrix33f[9]; //三维矩阵
typedef float M3DMatrix44f[16]; //四维矩阵
注意:OpenGL中使用一维数组来描述多维矩阵。
- 单元矩阵:
//单元矩阵初始化方式1
GLFloat m[] = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
}
//单元矩阵初始化方式2
M3DMatrix44f m = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
}
//单元矩阵初始化⽅方式3
void m3dLoadIdentity44f(M3DMatrix44f m);
单元矩阵 * 向量1 = 向量1 (此时的单元矩阵相当于1,1乘以任何数都为原值);
线性代数角度:
变换后顶点向量 = v_local * M_model * M_view * M_pro;
即:变换后顶点数量 = 顶点 x 模型矩阵 x 观察矩阵 x 投影矩阵

OpenGL角度:
变换顶点向量 = 投影矩阵 x 视图变换矩阵 x 模型矩阵 x 顶点

- 矩阵左乘
inline void MutMatrix(const M3DMatrix44f mMatrix) {
M3DMatrix44f mTemp;
m3dCopyMatrix44(mTemp, pStack[stackPointer]);
m3dMatrixMultiply44(pStack[stackPointer], mTemp, mMatrix);
}
大致流程:取出栈顶矩阵,然后跟传入的矩阵相乘,并将结果再放入栈顶;
顶点着色器:
attribute vec4 position;
attribute vec4 positionColor;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
varying lowp vec4 varyColor;
void main() {
varyColor = positionColor;
vec4 vPos;
vPos = projectionMatrix * modelViewMatrix *position;
gl_position = vPos;
}
行矩阵和列矩阵

OpenGL中的变换
变换 | 解释 |
---|---|
视图变换 | 指定观察者位置 |
模型变换 | 在场景中移动的物体 |
模型视图 | 描述视图/模型变换的二元性 |
投影 | 改变视景体大小和设置投影方式 |
视口 | 输出窗口大小 |
模型变换中的平移/旋转/缩放
void m3dTranslationMatrix44(M3DMatrix44f m, floata x, float y, float z);
m3dRotationMatrix44(m3dDegToRad(45.0), floata x, float y, float z);
void m3dScaleMatrix44(M3DMatrix44f m, floata xScale, float yScale, float zScale);
void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);
矩阵堆栈
- 常用API
//类型
GLMatrixStack::GLMatrixStack(int iStackDepth = 64);
//在堆栈顶部载⼊入⼀一个单元矩阵
void GLMatrixStack::LoadIdentity(void);
//在堆栈顶部载⼊入任何矩阵 //参数:4*4矩阵
void GLMatrixStack::LoadMatrix(const M3DMatrix44f m);
//矩阵乘以矩阵堆栈顶部矩阵,相乘结果存储到堆栈的顶部
void GLMatrixStack::MultMatrix(const M3DMatrix44f);
//获取矩阵堆栈顶部的值 GetMatrix 函数 //为了了适应GLShaderMananger的使⽤用,或者获取顶部矩阵的副本
const M3DMatrix44f & GLMatrixStack::GetMatrix(void);
void GLMatrixStack::GetMatrix(M3DMatrix44f mMatrix);
- 压栈与出栈
//将当前矩阵压⼊入堆栈(栈顶矩阵copy ⼀一份到栈顶) void GLMatrixStack::PushMatrix(void);
//将M3DMatrix44f 矩阵对象压⼊入当前矩阵堆栈
void PushMatrix(const M3DMatrix44f mMatrix);
//将GLFame 对象压⼊入矩阵对象
void PushMatrix(GLFame &frame);
//出栈(出栈指的是移除顶部的矩阵对象)
void GLMatrixStack::PopMatrix(void);
- 仿射变换
//Rotate 函数angle参数是传递的度数,⽽而不不是弧度
void MatrixStack::Rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
void MatrixStack::Translate(GLfloat x,GLfloat y,GLfloat z);
void MatrixStack::Scale(GLfloat x,GLfloat y,GLfloat z);
- 使用Camra和角色帧平移
class GLFrame {
protected:
M3DVector3f vOrigin; // Where am I?
M3DVector3f vForward; // Where am I going?
M3DVector3f vUp; // Which way is up?
}
- GLFrame
//将堆栈的顶部压⼊入任何矩阵
void GLMatrixStack::LoadMatrix(GLFrame &frame);
//矩阵乘以矩阵堆栈顶部的矩阵。相乘结果存储在堆栈的顶部 void GLMatrixStack::MultMatrix(GLFrame &frame);
//将当前的矩阵压栈
void GLMatrixStack::PushMatrix(GLFrame &frame);
- Camra管理
//GLFrame函数,这个函数⽤用来检索条件适合的观察者矩阵
void GetCameraMatrix(M3DMatrix44f m,bool bRotationOnly = flase);
网友评论