OpenGL-17-矩阵

694 阅读4分钟

一、认识矩阵

  • 假设在空间有⼀个点,使⽤ xyz 描述它的位置。此时让其围绕任意位置旋转⼀定⻆度后,我们需要知道这个点的新的位置,此时需要通过矩阵进⾏计算。
  • 因为新的位置的x 不单纯与原来的x 还和旋转的参数有关,甚⾄于y和z坐标有关。
  • 矩阵只有⼀⾏或者⼀列都是合理的. 只有⼀⾏或者⼀列数字可以称为向量. 也可以称为矩阵。
  • OpenGL中的矩阵,是以列为主的排序。 在其他编程标准中,许多矩阵库定义⼀个矩阵时,是使⽤⼆维数组。 在OpenGL的约定⾥,可以使用一维数组和二维数组,但是更多倾向使⽤ ⼀维数组。这样做的原因是: OpenGL 使⽤的是 Column-Major(以列为主)矩阵排序的约定

向量: 请看上一篇文章向量

**矩阵:**我们来看下百度给的定义:

**方阵:**⾏数和列数相同的矩阵。例如2 x 2、3 x 3、4 x 4矩阵。

**行矩阵、列矩阵:**根据不同编程定义不同,是一个优先顺序

**单元矩阵:**对角线元素都为1,其他元素都为0的矩阵。也可以看做是1。

矩阵在OpenGL中的初始化方法:

//三维矩阵声明
typedef float M3DMatrix33f[9];

//四维矩阵的声明
typedef float M3DMatrix44f[16];

单元矩阵初始化的三种方法:

//单元矩阵初始化⽅式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
}


//单元矩阵初始化⽅式3
void m3dLoadIdentity44f(M3DMatrix44f m);

⼀个4 x 4矩阵是如何在3D空间中表示⼀个位置和⽅向的?

  • 如下图。列向量进⾏了特别的标注:矩阵的最后⼀⾏都为0,只有最后⼀个元素为1
  • 如果将⼀个对象所有的顶点向量 乘以这个矩阵,就能让整个对象变换到空间中给定的位置和⽅向

二、矩阵的使用

1、矩阵转置

沿着对角线翻折,使 行矩阵变列矩阵 或者 列矩阵变行矩阵。

2、标量 x 矩阵

3、向量 x 矩阵

  • 向量也可以看做是一个1 x n矩阵,或者n x 1矩阵。同样要满足 前矩阵的列 = 后矩阵的行 才可以相乘。否则没有意义。
  • 比如:1 x 3代表向量 和 3 x 3代表矩阵。向量 x 矩阵 是可以的。矩阵 x 向量是没有意义的。

如此,我们可以得出:

  • ⾏向量左乘矩阵时,结果是⾏向量;
  • 列向量右乘矩阵时,结果是列向量;
  • ⾏向量右乘矩阵时,结果是⽆意义;
  • 列向量左乘矩阵时,结果是⽆意义;
  • 结果向量中的每个元素都是原向量与矩阵中单独⾏或列的点积;
  • 矩阵和向量乘法满⾜对向量加法的分配律,对于向量v、w 和 矩阵M , (v + w)M = vM + wM;

4、矩阵 x 矩阵

  • 前矩阵的列 = 后矩阵的行 才可以相乘

  • 1.在满足相乘法则的情况下,[任意矩阵M]乘以[⽅阵S],不管从哪边乘,都得到与原矩阵⼤⼩相同的矩阵。当然,前提是假定乘法有意义。如果S是单位 矩阵,结果就是原矩阵M,即:MI = IM = M 。 ·
  • 2.矩阵乘法不满⾜交换律,即:AB != BA
  • 3.矩阵乘法满⾜结合律,即:(AB)C = A(BC)。假定ABC的维数使得其乘法有意义,要注意如果(AB)C有意义,那么A(BC)就 ⼀定有意义。
  • 4.矩阵乘法也满⾜与标量或向量的结合律,即:(kA)B = k(AB) = A(kB); (vA)B = v(AB);
  • 5.矩阵积的转置相当于先转置矩阵然后以相反的顺序乘法,即:(AB)T = BT AT

5、OpenGL中的矩阵左乘

线性代数中,矩阵相乘坐标计算是 从左向右的顺序(右乘),如下:

变换后顶点向量 = V_local x M_model x M_view x M_pro (M*V*P) 变换后顶点向量 = 顶点 x 模型矩阵 x 观察矩阵 x 投影矩阵

但是,在OpenGL中是相反的顺序(左乘),如下:

变换顶点向量 = M_pro x M_view x M_model x V_local (P*V*M) 变换顶点向量 = 投影矩阵 x 视图变换矩阵 x 模型矩阵 x 顶点

    1. 从栈顶获取栈顶矩阵 复制到 mTemp这个临时变量中
    1. 将栈顶矩阵 mTemp 左乘 mMatrix
    1. 将结果放回栈顶空间⾥

我们代码段中矩阵的先手顺序: