Ios 反转CMRotationMatrix的一个轴的旋转

Ios 反转CMRotationMatrix的一个轴的旋转,ios,core-motion,rotational-matrices,Ios,Core Motion,Rotational Matrices,请容忍我,我的矩阵数学真的很糟糕。我有一个层,我想保持“静止”,重力在参考姿态,而手机旋转到其他姿态。我有一个motionManager工作得很好,在当前姿态上使用multiplybyinverseofattude,并使用CMRotationMatrix将生成的增量作为旋转应用到我的图层上(对俯仰、滚动和偏航进行单独的CATTransferorm3dRotates,在轴附近造成了相当大的古怪)。它的基本灵感来自于代码 在我将旋转应用到我的图层之前,我使用另一个变换来应用m34透视技巧 [atti

请容忍我,我的矩阵数学真的很糟糕。我有一个层,我想保持“静止”,重力在参考姿态,而手机旋转到其他姿态。我有一个motionManager工作得很好,在当前姿态上使用multiplybyinverseofattude,并使用CMRotationMatrix将生成的增量作为旋转应用到我的图层上(对俯仰、滚动和偏航进行单独的CATTransferorm3dRotates,在轴附近造成了相当大的古怪)。它的基本灵感来自于代码

在我将旋转应用到我的图层之前,我使用另一个变换来应用m34透视技巧

[attitude multiplyByInverseOfAttitude:referenceAttitude];

CATransform3D t = CATransform3DIdentity;
CMRotationMatrix r = attitude.rotationMatrix;
t.m11=r.m11;    t.m12=r.m12;    t.m13=r.m13;    t.m14=0;
t.m21=r.m21;    t.m22=r.m22;    t.m23=r.m23;    t.m24=0;
t.m31=r.m31;    t.m32=r.m32;    t.m33=r.m33;    t.m34=0;
t.m41=0;        t.m42=0;        t.m43=0;        t.m44=1;

CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -650;
t = CATransform3DConcat(t, perspectiveTransform);

myUIImageView.layer.transform = t;
结果很漂亮,就像你期望的那样,当我移动手机时,图层在重力作用下保持静止,除了一个轴,y轴;将手机平放并滚动,该层沿手机所在方向滚动两倍,而不是保持静止


我不知道为什么这一个轴移动错误,而另一个在应用multiplyByInverseOfAttitude后正确移动。当对俯仰、偏航和横摇使用单独的CATTransferorM3dRotates时,我可以通过将横摇向量乘以-1轻松纠正问题,但我不知道如何将其应用于旋转矩阵。很明显,这个问题只有在你把透视法引入到方程中时才可见,所以也许我做得不对。反转我的m34值可以修复横滚,但在球场上也会产生同样的问题。我需要弄清楚为什么这个轴上的旋转是向后的,通过我的矩阵反转这个轴上的旋转,或者以某种方式更正透视图。

您必须考虑以下几点:

  • 在您的情况下,
    CMRotationMatrix
    需要进行转置(),这意味着交换列和行
  • 您不需要将转换设置为
    CATTransferorM3DidEntity
    ,因为您将覆盖每个值,因此可以从空矩阵开始。如果要使用
    CATTransferM3DidEntity
    可以省略设置0和1,因为它们已经定义。(
    CATTransferrM3DidEntity
    是一个身份矩阵,请参见)
  • 若要更正围绕Y轴的旋转,需要将向量与[1 0 0;0-1 0 0;0 0 1 0;0 0 0 1]相乘
  • 对代码进行以下更改:

    CMRotationMatrix r = attitude.rotationMatrix;
    CATransform3D t;
    t.m11=r.m11;    t.m12=r.m21;    t.m13=r.m31;    t.m14=0;
    t.m21=r.m12;    t.m22=r.m22;    t.m23=r.m32;    t.m24=0;
    t.m31=r.m13;    t.m32=r.m23;    t.m33=r.m33;    t.m34=0;
    t.m41=0;        t.m42=0;        t.m43=0;        t.m44=1;
    
    CATransform3D perspectiveTransform = CATransform3DIdentity;
    perspectiveTransform.m34 = 1.0 / -650;
    t = CATransform3DConcat(t, perspectiveTransform);
    t = CATransform3DConcat(t, CATransform3DMakeScale(1.0, -1.0, 1.0));
    
    或者,通过将t设置为
    CATTransferorM3DidEntity
    只需将0和1省略即可:

    ...
    CATransform3D t = CATransform3DIdentity;
    t.m11=r.m11;    t.m12=r.m21;    t.m13=r.m31;
    t.m21=r.m12;    t.m22=r.m22;    t.m23=r.m32;
    t.m31=r.m13;    t.m32=r.m23;    t.m33=r.m33;
    ....
    

    谢谢你,马库斯,那代码工作得很好。当我旋转手机时,该层似乎在所有轴上都保持静止。尽管如此,结果还是引出了另一个问题。我希望通过使用矩阵数学,我可以避免在轴上出现任何奇怪的行为,但是确实发生了一些奇怪的事情。当我把手机调高,经过图层的“顶部边缘”时,图层不会继续平稳旋转。更确切地说,当我接近轴时,层绕轴旋转,所以我不能直接通过它的边缘。这是我正在做的旋转类型的标准特征吗?