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