ご容赦ください、私は行列計算が本当に苦手です。電話が他の姿勢に回転している間、referenceAttitude の重力で「静止」したままにしたいレイヤーがあります。現在の姿勢でmultiplyByInverseOfAttitudeを使用し、CMRotationMatrixを使用して結果のデルタを回転としてレイヤーに適用しています(ピッチ、ロール、ヨーに対して個別のCATransform3DRotatesを実行すると、軸の近くでかなりの奇抜さが生じました)。基本的には、この例のようなコードに触発されています。
これを別の変換と連結して、レイヤーに回転を適用する前に 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 軸を除いて、携帯電話を動かしてもレイヤーは重力で静止したままです。電話を平らに持って転がすと、レイヤーは静止したままではなく、電話がある方向に 2 倍回転します。
私は、multiplyByInverseOfAttitude を適用した後、この 1 つの軸が間違って移動し、他の軸が正しく移動する理由がわかりません。ピッチ、ヨー、ロールに個別の CATransform3DRotates を使用すると、ロール ベクトルに -1 を掛けることで問題を簡単に修正できましたが、それを回転行列に適用する方法がわかりません。問題は明らかに、方程式に視点を導入した場合にのみ表示されるため、おそらく私はそれを間違っています。m34 値を反転すると、ロールは修正されますが、ピッチで同じ問題が発生します。この軸の回転が後方にある理由を理解するか、マトリックスを介してその軸の回転を反転するか、何らかの方法で視点を修正する必要があります。