NSAffineTransform中的矩阵乘法顺序错误

时间:2014-03-31 08:01:28

标签: ios objective-c cocoa matrix quartz-2d

在我看来,NSAffineTransform等translateXBy:yBy:rotateByDegrees:scaleBy:等操作会使用错误的顺序并添加所需的转换矩阵而不是附加它。因此,如果您使用以下内容:

NSAffineTransform* T = [NSAffineTransform new];
[T translateXBy: dx1 yBy: dy1]; // T1
[T rotateByDegrees: angle];     // T2
[T translateXBy: dx2 yBy: dy2]; // T3

, - 与

相同
NSAffineTransform* T  = [NSAffineTransform new];

NSAffineTransform* T1 = [NSAffineTransform new];
[T1 translateXBy: dx1 yBy: dy1]; // T1

NSAffineTransform* T2 = [NSAffineTransform new];
[T2 rotateByDegrees: angle];     // T2

NSAffineTransform* T3 = [NSAffineTransform new];
[T3 translateXBy: dx2 yBy: dy2]; // T3

[T prependTransform: T1];
[T prependTransform: T2];
[T prependTransform: T3];

根据Apple的Quartz 2D Programming Guide生成一个给定的结果点,Quartz将其坐标表示为变换矩阵上的行向量:

                        m11 m12 0
[x' y' 1] = [x y 1] * [ m21 m22 0 ]
                        tx  ty  1

所以,在这种情况下:

v'= v * T = v * T3 * T2 * T1

虽然正确的结果应该是:

v' = v * T1 * T2 * T3

转换以相反的顺序应用。

旧Apple的文档在 prependTransform:

中有以下一行
  

将aTransform的矩阵与接收器矩阵连接起来。执行aTransform矩阵和接收器矩阵的乘法运算,并用结果替换接收器矩阵。这具有在接收器转换后应用aTransform的效果。

虽然new one包含以下内容:

  

这种类型的操作与在aTransform中应用转换后接收器中的转换相同。

使用prependTransform:及其文档是正确的,如果Quartz使用了左乘法变换而不是现在使用的右乘法变换。

有人可以对此发表评论吗?我是否遗漏了某些内容,或者它是实施中的已知错误?

0 个答案:

没有答案