CGAffineTransform连接两个矩阵而不是将一个矩阵应用于另一个矩阵

时间:2018-03-14 23:11:49

标签: swift cgaffinetransform

在下面的这个例子中,为什么第一个矩阵等于第三个矩阵,而不是第二个?

let t1 = CGAffineTransform(scaleX: 2, y: 2)
    .concatenating(CGAffineTransform(translationX: 50, y: 50))

let t2 = CGAffineTransform(scaleX: 2, y: 2).translatedBy(x: 50, y: 50)

let t3 = CGAffineTransform(translationX: 50, y: 50).scaledBy(x: 2, y: 2)

1 个答案:

答案 0 :(得分:1)

为避免与名称混淆,我将您的变量从tN重命名为rN

let r1 = CGAffineTransform(scaleX: 2, y: 2)
    .concatenating(CGAffineTransform(translationX: 50, y: 50))

let r2 = CGAffineTransform(scaleX: 2, y: 2).translatedBy(x: 50, y: 50)

let r3 = CGAffineTransform(translationX: 50, y: 50).scaledBy(x: 2, y: 2)

这确实看起来倒退了。除了concatenating函数之外,这些方法的文档并没有真正清楚地表明任何数学。

正如您在concatenating的文档中看到的那样:

  

新的仿射变换矩阵。也就是说,t'= t1 * t2。

r1变量的示例代码中,这是scale * translate

这部分似乎很清楚。

对于translatedByscaledBy函数,您需要查看Objective {C头文件,以查找CGAffineTransformTranslateCGAffineTransformScale的相应函数。

对于CGAffineTransformTranslate,您会看到评论:

  

翻译t(tx,ty)并返回结果:        吨' = [1 0 0 1 tx ty] * t

对于CGAffineTransformScale,您会看到:

  

按(sx,sy)缩放t并返回结果:        吨' = [sx 0 0 sy 0 0] * t

此信息告诉我们let r = t.translatedBy(t2)等同于t' = t2 * t。当然scaledByrotatedBy是相似的。

这意味着代码中的这一行:

let r3 = CGAffineTransform(translationX: 50, y: 50).scaledBy(x: 2, y: 2)

与:

相同
let r3 = CGAffineTransform(scaleX: 2, y: 2).concatenating(CGAffineTransform(translationX: 50, y: 50))

而不是:

let r3 = CGAffineTransform(translationX: 50, y: 50).concatenating(CGAffineTransform(scaleX: 2, y: 2))

这就是为什么在您的示例代码中,r1等于r3。阅读像英语这样的第二行,会导致矩阵以相反的顺序连接起来。