美文网首页
OpenGL 中向量,矩阵的理解

OpenGL 中向量,矩阵的理解

作者: iOS_沧海一笑 | 来源:发表于2020-07-16 16:52 被阅读0次

什么是向量?

定义: 在 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 中向量,矩阵的理解

    什么是向量? 定义: 在 3D 笛卡尔坐标系, 基本上. 一个顶点就是XYZ 坐标空间上的一个位置. ⽽在空间中给...

  • OpenGL--向量和矩阵

    在我们OpenGL中涉及到图形变换的时候经常会运用到向量/矩阵的运算。今天我们就来了解下OpenGL中的向量、矩阵...

  • OpenGL笔记六:纹理常用API(一)

    前言 期待您移步上篇:OpenGL笔记五:综合实例理解-压栈、出栈、堆栈矩阵相乘、矩阵相乘、向量相乘 纹理 纹理只...

  • OpenGL中的向量、矩阵

    一、向量 1.概念 在3D笛卡尔坐标系,基本上一个顶点就是XYZ坐标空间上的一个位置,而在空间中给定的一个位置,恰...

  • OpenGL中的向量,矩阵

    一.向量 如图: 在3D笛卡尔坐标系中,A点在XYZ轴上对应的位置分别为OC,OD,OB,在X轴上,我们用X(蓝色...

  • OpenGL中的向量、矩阵

    向量 了解向量之前,先了解什么是标量 标量:只有大小,例如:1,12,13等 向量是有方向的标量,即不仅有大小,还...

  • OpenGL中向量、矩阵相关基础变化理解

    为什么要理解这些基础变化 根据我的观察,大家在学习OpenGL的时候有一个误区,就是认为如果不能精通那些3D图形数...

  • OpenGL 向量、矩阵

    向量 在坐标系上,一个顶点就是X,Y,Z坐标空间的一个位置。由一个单独的XYZ定义的这样就是向量。 单位向量 向量...

  • OpenGL向量、矩阵

    向量 在 3D 笛卡尔坐标系, 基本上一个顶点就是XYZ 坐标空间上的⼀个位置。而在空间中给定的一个位置恰是由一个...

  • OpenGL 向量/矩阵

    向量 什么是向量 在3D笛卡坐标系中,基本上,一个顶点就是XYZ坐标空间上的一个位置。而在空间中给定的一个位置,恰...

网友评论

      本文标题:OpenGL 中向量,矩阵的理解

      本文链接:https://www.haomeiwen.com/subject/vrpphktx.html