使用 CATransform3D 旋转和平移 CALayer 的正确顺序是什么

What's the proper order to rotate and translate an CALayer with CATransform3D

我有一个 CALayer,我想同时平移和旋转它。我有以下代码可以实际工作:

    // layer 1:
    // translate: (△x, △y, △z) = (length/2, 0, length/2)
    // rotate around y: 90 degree
    CATransform3D transformLayer1 = CATransform3DIdentity;
    transformLayer1 = CATransform3DTranslate(transformLayer1, length/2, 0, length/2   );
    transformLayer1 = CATransform3DRotate(transformLayer1, M_PI_2, 0, 1, 0);
    self.layer1.transform = transformLayer1;

我在测试中发现如果改变平移和旋转的顺序,变换结果会不一样,比如代码改成这样:

    CATransform3D transformLayer1 = CATransform3DIdentity;

    // do rotation firstly, and then translation
    transformLayer1 = CATransform3DRotate(transformLayer1, M_PI_2, 0, 1, 0);
    transformLayer1 = CATransform3DTranslate(transformLayer1, length/2, 0, length/2   );
    
    self.layer1.transform = transformLayer1;

在调试中,我在每一步都打印了变换矩阵的值。结果显示m43的值不同。有谁能解释为什么会这样?或者如何理解 CATransform3DTranslate() 和 CATransform3DRotate() 的 Core Animation 函数?

正确的顺序取决于你想要什么...但是矩阵乘法是 not commutative 这意味着 A*B != B*A 其中 A 和 B 是矩阵。

但是如果我没记错代码的话,我认为你想首先应用的矩阵应该在最右边,所以如果你有 ROT 和 TRANS 矩阵,并且你想进行旋转,那么变换,使其成为 TRANS*ROT(上次我用矩阵做任何事情是很久以前的事了,所以我可能把它倒过来了)

使用 concat function 进行乘法运算,而不是根据上一个矩阵创建下一个矩阵,这样更容易看出左右乘法的情况(也许 swift 是足够聪明,可以重载 * 运算符来执行此操作,但我不确定)