CGAffineTransform:如何计算乘法CGAffineTransform?

nsunt 发布于 2019-08-14 cgaffinetransform 最后更新 2019-08-14 08:39 1 浏览

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

已邀请:

uut

赞同来自:

在这些矩阵变换中,对幕后发生的事情有一点了解总是很好。 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
Note that matrix operations are not commutative—the order in which you concatenate matrices is important. That is, the result of multiplying matrix t1 by matrix t2 does not necessarily equal the result of multiplying matrix t2 by matrix 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

eos_et

赞同来自:

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};
您可以通过此结构获取参数。转换总是覆盖,换句话说,它们不会叠加,请注意这一点。