GLKit的GLKMatrix“专栏”如何?
前提A.
当在线性存储器中讨论“列主要”矩阵时,一个接一个地指定列,使得存储器中的前4个条目对应于矩阵中的第一列。 另一方面,“行主要”矩阵被理解为一个接一个地指定行,使得存储器中的前4个条目指定矩阵的第一行。
GLKMatrix4
看起来像这样:
union _GLKMatrix4 { struct { float m00, m01, m02, m03; float m10, m11, m12, m13; float m20, m21, m22, m23; float m30, m31, m32, m33; }; float m[16]; } typedef union _GLKMatrix4 GLKMatrix4;
关于m
成员的文档说:
按列顺序排列的矩阵元素的一维数组。
前提B
GLKMatrix4中的“行”是一组4个水平声明的浮点数( [m00, m01, m02, m03]
将是第一个“行”)。 因此,这些条目可以解释为mRowCol( m12
将是第1行第2列的条目)。
如果我们根据声明的顺序查看这些GLKMatrix结构成员的布局,我们会看到:
[m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, ...]
前4个条目清楚地表示矩阵的第一行 ,而不是第一列。
结论
m
实际上不是专栏,而且文档是错误的。
现在,我应该注意到我实际上并不相信结论,但这两个前提似乎很合理。 真的,我最不信任前提B,但将“行”定义为垂直并将“列”定义为水平似乎很奇怪。 有人可以解释一下吗?
声明有点令人困惑,但矩阵按列主要顺序排列。 结构中的四行表示矩阵中的列,m0 *为列0,m3 *为列3.这很容易validation,只需创建转换矩阵并检查转换组件的值m30,m31和m32。
我猜你的混淆来自这样一个事实,即结构在行中放置了浮点数,当它们实际上代表列时。
这来自OpenGL规范 –
混淆点就是这样:正如其他人所指出的那样,我们使用指示列的第一个索引来索引列主矩阵,而不是行 :
-
m00
指的是列= 0,行= 0 , -
m01
指的是列= 0,行= 1 , -
m02
指列= 0,行= 2 ,
MATLAB可能已经做了很多工作来间接地造成这种混乱,而MATLAB确实使用了列主要用于它的内部数据表示 ,它仍然使用x(row,col)
的行主索引约定。 我不确定他们为什么这样做。
另请注意,默认情况下,OpenGL使用列向量 – 即您希望将矩阵乘以它转换的向量,如着色器中的(MATRIX*VECTOR)
。 与(VECTOR*MATRIX)
对比,这是行主矩阵的用法。
查看我在C中的行主要列与列主要矩阵的文章可能会有所帮助 。
在代码中布置矩阵时,列专业是反直觉的
我越是看这个,我认为在C代码专栏中工作就越错,因为需要精神上转置你正在做的事情。 当您在代码中布置矩阵时,您受到我们语言的从左到右的限制,要逐行写出矩阵:
float a[4] = { 1, 2, 3, 4 };
所以,很自然地看起来你是按行,矩阵指定的
1 2 3 4
但是,如果您使用的是列主要规范,那么您实际上已经指定了矩阵
1 3 2 4
这是违反直觉的。 如果我们有一个垂直(或“列主要”语言),那么在代码中指定列主矩阵会更容易。
对于Direct3D来说,所有这一切都是另一回事吗? 我不知道,你告诉我。
真的,为什么OpenGL会使用列主要矩阵呢?
深入挖掘 ,似乎这样做的原因是为了能够通过向量“乘法”矩阵作为(MATRIX*VECTOR)
– 即能够使用列(主要) 向量,如 :
列主要矩阵乘法
┌ 2 8 1 1 ┐ ┌ 2 ┐ │ 2 1 7 2 │ │ 2 │ │ 2 6 5 1 │ │ 2 │ └ 1 9 0 0 ┘ └ 1 ┘
将此与必须使用行向量进行对比:
行主矩阵乘法
[ 2 2 2 1 ] ┌ 2 8 1 1 ┐ │ 2 1 7 2 │ │ 2 6 5 1 │ └ 1 9 0 0 ┘
如果矩阵被指定为行主要,那么你应该“使用”行向量并通过它们正在变换的向量预乘多个矩阵 。
使用行主矩阵时“应该”使用行向量的原因是一致的数据表示 :毕竟,行向量只是1行,4列矩阵。
前提B中的问题是您假设GLKMatrix4中的“行”是一组4个水平声明的浮点数([m00,m01,m02,m03]将是第一个“行”)。
我们可以通过检查以下代码中的column
值来validation:
GLKMatrix3 matrix = {1, 2, 3, 4, 5, 6, 7, 8, 9}; GLKVector3 column = GLKMatrix3GetColumn(m, 0);
注意:为简单起见,我使用了GLKMatrix3
,但同样适用于GLKMatrix4
。