我一直在阅读有关使用矩阵转换Vector3的一些阅读,并且正在努力深入研究数学和编码本身而不是使用现有代码。无论出于何种原因,我的学校课程从未包含过矩阵,所以我填补了我的知识空白。值得庆幸的是,我认为我只需要一些简单的事情。
上下文是我正在为RoboCup 3D league编程机器人。我在C#编码,但它必须在Mono上运行。理想情况下,我不会使用任何现有的图形库(WinForms / WPF / XNA),因为我真正需要的只是一个整齐的矩阵变换子集。
具体来说,我需要平移和x / y / z旋转,以及将多个变换组合成单个矩阵的方法。然后,这将应用于我自己的Vector3
类型,以生成已转换的Vector3
。
我已经阅读了不同的建议。例如,some使用4x3矩阵建模转换,others使用4x4矩阵。
此外,一些例子表明你需要向量矩阵的第四个值。当该值包含在输出中时,该值会发生什么?
[1 0 0 0] [x y z 1] * [0 1 0 0] = [a b c d] [0 0 1 0] [2 4 6 1]
我缺少的部分是:
由于我大多只想让它运行,任何伪代码都会很棒。有关哪些矩阵值执行哪些转换的信息在很多页面上都有明确定义,因此除非您非常热衷,否则无需在此讨论:)
答案 0 :(得分:7)
3 x 3矩阵可以编码转换,例如旋转和反射,但不能转换。为此,您需要添加第四个元素,并以homogenous coordinates表示您的向量。可以将非方形矩阵用于某些目的,但如果您希望能够以任何顺序组合它们,它们应该是正方形的(因为如果第一个中的列数等于,则只能乘以两个矩阵)第二个中的行数。
因此,为了您的目的,您应该使用4x4矩阵和4元素同质向量,添加值为1的第四个 w 坐标。
将变换应用于一堆向量只是乘法的问题。
传统上,向量表示为columns,矩阵位于左侧。您在上面将它们表示为rows并在右侧相乘。两者都有效,但转换矩阵需要在两种情况之间进行转换。您显示的矩阵在底部具有平移值,这对于您的乘法顺序是正确的。
转换矢量后,需要通过 w 坐标进行划分,将 x,y 和 z 缩放回常规3维空间。
在C-ish伪代码中,使用行向量约定:
Vector transform (Vector v, Matrix m)
{
Vector result;
for ( int i = 0; i < 4; ++i )
result[i] = v[0] * m[0][i] + v[1] * m[1][i] + v[2] + m[2][i] + v[3] * m[3][i];
result[0] = result[0]/result[3];
result[1] = result[1]/result[3];
result[2] = result[2]/result[3];
return result;
}
可以通过依次将每个矩阵相乘来组成一系列变换。请注意,矩阵乘法不可交换,因此乘法的顺序很重要。反过来,这意味着您是将左侧的行向量乘以右侧的列也很重要。如果乘以 A x B x C ,则使用与执行转换 C 相同的列向量,然后 B ,最后 A 。对于行向量,首先是 A ,然后是 B ,然后是 C 。因此,在构建,编写和应用转换时保持一致性非常重要。
同样,在伪代码中应该与上面的transform
一致:
Matrix compose (Matrix first, Matrix second)
{
Matrix result;
for ( int i = 0; i < 4; ++i )
for ( int j = 0; j < 4; ++j )
result[i][j] = first[i][0] * second[0][j]
+ first[i][1] * second[1][j]
+ first[i][2] * second[2][j]
+ first[i][3] * second[3][j];
return result;
}