OpenGL 中的向量、矩阵

283 阅读3分钟

向量

在了解向量之前,我们先的了解什么是标量

  • 标量:标量就是我们经常说的数字,他只有大小。例如2,5,12。

  • 向量:向量我们可以理解为是带有方向的标量,它不仅有大小,他有方向。

单位向量

单位向量是长度为1的向量,向量的长度可以通过下列公式计算

如果⼀个向量不是单位向量,⽽我们把它缩放到1.这个过程叫做标准化.将⼀个向量进⾏标准化就是将它的缩为1;也叫做单位化向量;单位化的计算公式如下:

单位化的计算公式
那么在OpenGL中如何定义一个向量呢? 通过 math3d 库.math3d 库有两个数据类型,一个是个三维向量一个是四维向量。

//三维向量/四维向量的声明
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
};

向量点乘

  • 向量可以进⾏加减计算.但是向量⾥有⼀个在开发中使⽤价值⾮常⾼的操作,叫做“点乘(dot product)” 。点乘只能发⽣在2个向量之间进⾏
  • 两个(三维向量)单元向量之间进⾏点乘运算将得到⼀个标量(不是三维向量,是⼀个标量). 它表示两个向量之间的夹⻆。得到的结果是[-1,1]范围值,这个值其实就是夹⻆的cos值(余弦值)

math3d 库中提供了关于点乘的API

//1.m3dDotProduct3 函数获得2个向量之间的点乘结果即余弦值;
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
 
//2.m3dGetAngleBetweenVector3 即可获取2个向量之间夹⻆的弧度值;
 float m3dGetAngleBetweenVector3(const M3DVector3f u,const 
M3DVector3f v);

向量叉乘

  • 2个向量之间叉乘就可以得到另外⼀个向量,新的向量会与原来2个向量定义的平⾯垂直. 同时进⾏叉乘,不必为单位向量;

math3d 库中提供了关于叉乘的API

//1.m3dCrossProduct3 函数获得2个向量之间的叉乘结果得到⼀个新的向量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const 
M3DVector3f v); 

矩阵 Matrix

单位矩阵

  • 主对角线上数据都是1,其余元素都是0,即为单元矩阵
  • 向量 X 单元矩阵 = 向量 X 1,不会发生任何变化
  • 向量与单元矩阵相乘的前提是:向量的列数 == 单元矩阵的行数

矩阵分类

  • 行优先矩阵:一行一行读取
  • 列优先矩阵:一列一列读取
  • 两者的关系为:行优先矩阵经过转置 即可的到列优先矩阵
  • OpenGL 为列优先矩阵

矩阵的点乘

  • 矩阵可以进行点乘的前提:两个矩阵的行列数相等
  • 矩阵A · 矩阵B = 矩阵C
  • 规则:矩阵A的第一个元素与矩阵B的第一个元素的乘积 = 矩阵C的第一个元素

矩阵叉乘

  • 矩阵可以进行叉乘的前提:第一个矩阵的列数 = 第二个矩阵的行数

  • 矩阵A X 矩阵B = 矩阵C

  • 规则:矩阵A第一行与矩阵B第一列对应元素乘积的综合 = 矩阵C的第一个元素