为什么2D变换需要3x3矩阵?

21

我想进行一些二维绘图,因此想要实现一些矩阵变换。由于我的数学背景有限,我正在尝试理解如何在C#(或任何其他面向对象的语言)中进行这样的操作。

我所读到的都是解释说我们需要使用3x3矩阵才能处理平移。因为你不能通过乘法来进行平移。但正是通过矩阵的乘积,我们才能创建变换。因此,我们使用类似以下的内容:

{ x1, x2, tx }
{ y1, y2, ty }
{ 0,  0,  1  }
我理解第三列的意义,但为什么我们需要第三行呢?在单位矩阵及旋转、缩放矩阵中,最后一行都是相同的。难道还有我没用到需要它的操作吗?是因为某些语言(如Java)使用“正方形维度”数组更有效吗?如果是这样,在C#中我可以使用3列2行(因为嵌套数组也能或更好地工作)。
例如,对于旋转+平移,我的矩阵如下:
{ cos(rot)*x1, (-sin(rot))*x2, tx }
{ sin(rot)*y1, cos(rot)*y2,    ty }
{ 0,           0,              1  }

不需要最后一行。


2
从http://en.wikipedia.org/wiki/Translation_(geometry)开始阅读,然后跟随其中一个链接到http://en.wikipedia.org/wiki/Homogeneous_coordinates。 - High Performance Mark
1
@HighPerformanceMark,我在这里试图解释我不理解这些概念的哪一点。是的,这是我开始阅读的前两篇文献。 - Mr.Pe
2个回答

35

我们通过矩阵的乘法来创建变换,这就是为什么我们需要方阵的原因。

就是为什么我们需要方阵。

假设我们按照您的建议使用2x3矩阵进行变换。

那么旋转将会是:

( x1, x2, 0 )
( y1, y2, 0 )

一种翻译是:

( 1, 0, tx )
( 0, 1, ty )

我们可以通过将矩阵乘以表示点的列向量来执行旋转或平移:

    ( x )
M   ( y )
    ( 0 )

为了获得正确的答案。

然而——我们该如何进行变换的组合呢?对于你提到的“对于旋转+平移,我有这样一个矩阵”的例子,你是如何得到那个矩阵的?当然,在这种情况下,你可以直接写出来,但一般情况呢?好吧,你知道答案:

 

这就是通过我们创建的矩阵的乘法来实现变换的方法。

因此,将两个变换矩阵相乘以得到另一个变换矩阵是可行的。而且矩阵乘法规则表明:

( . . . ) ( . . . )
( . . . ) ( . . . ) = ???

这不是一个有效的矩阵乘法。我们需要可以相乘的矩阵才能使变换可组合。因此,我们需要那一行额外的元素。


现在,我在这里表述的方式与标准数学表达完全相反。在标准表达中,旋转和平移的熟悉变换只是投影平面上齐次坐标变换的全部威力的特殊情况 - 但我认为这样做足以说明为什么我们需要那一行额外的元素 - 使矩阵变为方阵,从而能够与类似的矩阵相乘。


哦,那正是我之前没有看到的!谢谢你,AakashM。感谢你花时间发现了我的思维漏洞。 - Mr.Pe
实际计算翻译(tx,ty)的过程如下:[x y 1] x [1 0 0; 0 1 0; tx ty 1] = [x+tx y+ty 1] - Gerard

9
答案是齐次坐标。为了将旋转和平移结合成一个操作,需要比模型要求多一个维度。对于平面事物,这个维度是3个分量,对于空间事物,这个维度是4个分量。运算符接受3个分量,并返回3个分量,需要3x3矩阵。

但在二维中,{0,0,1} 行的目的是什么?我们可以在没有它的情况下计算平移和线性变换。(如果我理解正确的话) - Mr.Pe
正如我所说,第三行是生成三个分量结果所必需的。第三个分量可能并不总是等于 1,在其他仿射变换中第三行也不一定是 [ 0 0 1 ] - John Alexiou
我没有考虑到我们需要这个矩阵操作;那是一个我没有预料到的“数学约束”。(对于我的迟缓感到抱歉) - Mr.Pe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接