CGAffineTransform:如何计算乘法CGAffineTransform?

时间:2016-02-16 10:12:55

标签: ios cgaffinetransform

我需要从原点(250,250)到原点(352,315)的变换视图,宽度/高度从(100.0,100.0)变为(68,68)。 我知道我可以将几个CGAffineTransform函数组合在一起,例如缩放,旋转,平移。 但我不知道如何计算这些变换的顺序,以及它们的确切参数。 我已经尝试了几次,但无法将视图移动到正确的位置。

任何人都可以提供帮助吗?

2 个答案:

答案 0 :(得分:9)

在这些矩阵变换中,对幕后发生的事情有一点了解。

Apple文档有关于变换的great documentation,所以让我们使用它。

翻译矩阵如下所示:

|  1   0   0  |
|  0   1   0  |
|  tx  ty  1  |

其中(tx, ty)是您的翻译向量。

缩放矩阵如下所示:

|  sx  0   0  |
|  0   sy  0  |
|  0   0   1  |

其中sxsy是X轴和Y轴的比例因子。

您希望使用CGAffineTransformConcat连接这些矩阵,但根据its doc

  

请注意,矩阵运算不是可交换的 - 您的顺序   连接矩阵很重要。也就是乘法的结果   矩阵t2的矩阵t1不一定等于结果   将矩阵t2乘以矩阵t1。

您必须在缩放视图之前翻译视图,否则您的翻译向量将根据sxsy系数进行缩放。

让我们轻松展示:

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

答案 1 :(得分:0)

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

您可以通过此结构获取参数。转换总是覆盖,换句话说,它们不会叠加,请注意这一点。