OpenGL 中向量,矩阵的理解

什么是向量?

定义: 在 3D 笛卡尔坐标系, 基本上. 一个顶点就是XYZ 坐标空间上的一个位置. ⽽在空间中给定的一个位置恰恰是由一个单独的XYZ 定义的. 而这样的 XYZ 就是向量; 向量是有大小,有方向的。与标量不同,标量只有大小,没有方向

image.png
  • 单位向量:在 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 ] 范围的值,这个值其实就是夹角anglecos值(余弦值)

如何单位化向量?
( x / |xyz|, y / |xyz|, z / |xyz| );
使⽤一个非零向量除以它的模(向量的长度), 就可以得到方向相同的单位向量;

image.png
  • 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个向量定义的平面的向量)
image.png
  • 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(以列为主)矩阵排序的约定;

image.png

一个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

单元矩阵在 OpenGL 的维度,有以下公式:
变换顶点向量 = M_pro * M_view * M_model * V_local
变换顶点向量 = 投影矩阵 ✖ 视图变换矩阵 ✖ 模型矩阵 ✖ 顶点

image.png
  • 矩阵左乘

    1. 从栈顶获取栈顶矩阵复制到 mTemp
    2. 将栈顶矩阵 mTemp 左乘 mMatrix
    3. 将结果放回栈顶空间里;
image.png

image.png

你可能感兴趣的:(OpenGL 中向量,矩阵的理解)