CGAffineTransform 连接两个矩阵与将一个矩阵应用于另一个矩阵
CGAffineTransform concatenating two matrices vs applying one to the other
在下面的例子中,为什么第一个矩阵等于第三个而不是第二个?
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)
为了避免与名称混淆,我将您的变量从 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
的文档中所见:
A new affine transformation matrix. That is, t’ = t1*t2.
在 r1
变量的示例代码中,这是 scale * translate
。
这部分看起来很清楚。
至于translatedBy
和scaledBy
函数需要查看Objective-C头文件中CGAffineTransformTranslate
和CGAffineTransformScale
对应的函数。
对于 CGAffineTransformTranslate
你看到评论:
Translate t by (tx, ty) and return the result:
t' = [ 1 0 0 1 tx ty ] * t
对于 CGAffineTransformScale
你会看到:
Scale t by (sx, sy) and return the result:
t' = [ sx 0 0 sy 0 0 ] * t
这个信息告诉我们 let r = t.translatedBy(t2)
等同于 t' = t2 * t
。当然 scaledBy
和 rotatedBy
是相似的。
这意味着您代码中的这一行:
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
。像英语一样阅读第二两行会导致矩阵以相反顺序连接的想法。
在下面的例子中,为什么第一个矩阵等于第三个而不是第二个?
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)
为了避免与名称混淆,我将您的变量从 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
的文档中所见:
A new affine transformation matrix. That is, t’ = t1*t2.
在 r1
变量的示例代码中,这是 scale * translate
。
这部分看起来很清楚。
至于translatedBy
和scaledBy
函数需要查看Objective-C头文件中CGAffineTransformTranslate
和CGAffineTransformScale
对应的函数。
对于 CGAffineTransformTranslate
你看到评论:
Translate t by (tx, ty) and return the result: t' = [ 1 0 0 1 tx ty ] * t
对于 CGAffineTransformScale
你会看到:
Scale t by (sx, sy) and return the result: t' = [ sx 0 0 sy 0 0 ] * t
这个信息告诉我们 let r = t.translatedBy(t2)
等同于 t' = t2 * t
。当然 scaledBy
和 rotatedBy
是相似的。
这意味着您代码中的这一行:
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
。像英语一样阅读第二两行会导致矩阵以相反顺序连接的想法。