在这些矩阵转换中,对幕后发生的事情有一点了解总是很好的。
Apple 文档有一个关于转换的 great documentation,所以让我们使用它。
一个平移矩阵看起来像:
| 1 0 0 |
| 0 1 0 |
| tx ty 1 |
(tx, ty) 是您的翻译向量。
缩放矩阵看起来像:
| sx 0 0 |
| 0 sy 0 |
| 0 0 1 |
其中sx和sy是X和Y轴的比例因子。
您想使用CGAffineTransformConcat 连接这些矩阵,但根据its doc:
请注意,矩阵运算不是可交换的——
连接矩阵很重要。也就是相乘的结果
矩阵 t1 乘以矩阵 t2 不一定等于
将矩阵 t2 与矩阵 t1 相乘。
您必须在缩放之前平移视图,否则您的平移向量将根据sx 和sy 系数进行缩放。
让我们轻松展示一下:
let scaleMatrix = CGAffineTransformMakeScale(0.68, 0.68)
let translateMatrix = CGAffineTransformMakeTranslation(102, 65)
let translateThenScaleMatrix = CGAffineTransformConcat(scaleMatrix, translateMatrix)
NSLog("translateThenScaleMatrix : \(translateThenScaleMatrix)")
// outputs : CGAffineTransform(a: 0.68, b: 0.0, c: 0.0, d: 0.68, tx: 102.0, ty: 65.0)
// the translation is the same
let scaleThenTranslateMatrix = CGAffineTransformConcat(translateMatrix, scaleMatrix)
NSLog("scaleThenTranslateMatrix : \(scaleThenTranslateMatrix)")
// outputs : CGAffineTransform(a: 0.68, b: 0.0, c: 0.0, d: 0.68, tx: 69.36, ty: 44.2)
// the translation has been scaled too
让我们用数学方法证明它。请注意,当您执行操作 A 然后执行操作 B 时,通过执行 matB*matA 计算相关矩阵,第一个操作在右侧。由于矩阵的乘法不可交换,所以它很重要。
// Translate then scaling :
| sx 0 0 | | 1 0 0 | | sx 0 0 |
| 0 sy 0 | . | 0 1 0 | = | 0 sy 0 |
| 0 0 1 | | tx ty 1 | | tx ty 1 |
// The resulting matrix has the same value for translation
// Scaling then translation :
| 1 0 0 | | sx 0 0 | | sx 0 0 |
| 0 1 0 | . | 0 sy 0 | = | 0 sy 0 |
| tx ty 1 | | 0 0 1 | | sx.tx sy.ty 1 |
// The translation values are affected by scaling coefficient