什么是向量?
image.png定义: 在 3D 笛卡尔坐标系, 基本上. 一个顶点就是XYZ 坐标空间上的一个位置. ⽽在空间中给定的一个位置恰恰是由一个单独的XYZ 定义的. 而这样的 XYZ 就是
向量; 向量是有大小,有方向的
。与标量
不同,标量只有大小,没有方向
。
-
单位向量:在 X轴上的向量 (1,0,0). 向量⻓度为1. 我们称为长度为1的向量为
image.png单位向量
. 向量的长度(向量的模)计算公式:
-
单位化向量:如果一个向量不是单位向量,而我们把它缩放到1,这个过程叫做标准化,将一个向量进行标准化就是将它的长度缩为1,也叫
单位化向量
。
OpenGL定义向量【math3d库】
- math3d库,有2个数据类型,能够表示一个三维或者四维向量:
M3DVector3f:可以表示一个三维向量(x, y, z)
M3DVector4f:可以表示一个四维向量(x, y, z, w)
在典型情况下,w坐标设为1.0。x,y,z值通过除以w,来进行缩放。而除以1.0则本质上不改变x,y,z值。
- 三维向量,四维向量使用代码声明:
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个向量之间进行;
2个(三维向量)单元向量之间进行点乘运算将得到一个标量
(不是三维向量,是一个标量,标量是只有大小,没有方向).它表示两个向量之间的夹⻆angle
.
向量进行点乘必须满足以下条件:
- 前提条件:2个向量必须为单位向量
- 动作:2个三维向量之间进行点乘
- 结果:返回一个 [ -1, 1 ] 范围的值,这个值其实就是夹角
angle
的cos
值(余弦值)
image.png如何单位化向量?
( 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);
向量叉乘
定义:向量之间的叉乘
(cross product)
也是在业务开发里非常有用的一个计算方式; 2个向量之间叉乘就可以得到另外一个向量,新的向量会与原来2个向量定义的平面垂直. 同时进行叉乘,不必为单位向量;
向量进行叉乘必须满足以下条件:
- 前提: 2个普通向量
- 动作: 向量与向量叉乘
- 结果: 向量(垂直于原来2个向量定义的平面的向量)
- math3d 库中提供了了关于叉乘的API
//1.m3dCrossProduct3 函数获得2个向量量之间的叉乘结果得到⼀一个新的向量量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const M3DVector3f v);
什么是矩阵 Matrix ?
假设, 在空间有一个点.使用 xyz 描述它的位置. 此时让其围绕任意位置旋转一定⻆度后. 我们需要知道这个点的新的位置. 此时需要通过矩阵进行计算; 为什么?因为新的位置的x 不单纯与原来的x还和旋转的参数有关. 甚至与y和z坐标有关;
矩阵只有一行或者一列都是合理的. 只有一行或者一列数字可以称为向量. 也可以称为矩阵;
//三维矩阵/四维矩阵的声明
typedef float M3DMatrix33f[9];
typedef float M3DMatrix44f[16];
在其他编程标准中, 许多矩阵库定义一个矩阵时,使⽤用二维数组;OpenGL的约定⾥里,更多倾向使用 一维数组; 这样做的原因是: OpenGL 使用的是 Column-Major(以列为主)
矩阵排序的约定;
一个4*4矩阵是如何在3D空间中表示一个位置和方向的列向量进行了特别的标注:矩阵的最后一行都为0,只有最后一个元素为1. 奥秘之处在于这 16 个值表示空间中一个特定的位置; 这4列中,每一列都是有4个元素组成的向量; 如果将一个对象所有的顶点向量 乘以这个矩阵,就能让整个对象变换到空间中给定的位置和方向;
image.png
- 单元矩阵的初始化方式
//单元矩阵初始化方式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
}
//单元矩阵初始化方式2
void m3dLoadIdentity44f(M3DMatrix44f m);
将一个向量 ✖ 单元矩阵 ,就相当于一个向量✖1. 不会发生任何改变;
image.png
image.png单元矩阵在 OpenGL 的维度,有以下公式:
变换顶点向量 = M_pro * M_view * M_model * V_local
变换顶点向量 = 投影矩阵 ✖ 视图变换矩阵 ✖ 模型矩阵 ✖ 顶点
-
矩阵左乘
- 从栈顶获取栈顶矩阵复制到 mTemp
- 将栈顶矩阵 mTemp 左乘 mMatrix
- 将结果放回栈顶空间里;
image.png
网友评论