デバイスの位置 (フラットかフラットでないか) とは無関係に、デバイスの z 軸を中心とした回転を計算する場合は、いくつかのことを追跡する必要があります。アプリがポートレートとランドスケープの両方をサポートしている場合は、さらに複雑になります。アクティビティがポートレートのみに制限されている場合に回答します。
ここでフラットとは、ピッチが 25 度未満または 155 度を超えることを意味し、それ以外の場合はフラットではありません。
デバイスがフラットから非フラットへ、またはその逆に移行している場合、UI に一貫性がない可能性があります。
TYPE_GRAVITY
and TYPE_MAGNETIC_FIELD
(フラットに必要) に 登録し、以下の計算を行います。
getRotationMatrix
a[0] a[1] a[2]
a[3] a[4] a[5]
a[6] a[7] a[8]
計算するpitch = Math.asin(-R[7])
- を使用
pitch
してデバイスの平坦度を決定します (平坦度を決定するために 45 未満と 135 を超える値を使用できると思います。azymuth
値が正しいかどうかを実験して確認する必要があります)
デバイスがフラットでない場合、回転は Math.atan2(a[6], a[7]) です。
デバイスが最初に平らな場合は、最初に取得し、次に回転を取得するためazymuth = Math.atan2(R[1], R[4])
に差を取ります。azymuths
デバイスがフラットから非フラットに移行する場合、回転は単に上の非フラットの回転であることに問題はありません。
デバイスが非フラットからフラットに移行する場合は、初期値を取得する必要がありますazymuth
。このイニシャルazymuth
は、背面カメラの方向 Math.atan2(-a[2], -a[5]) に設定できます。デバイスが直立していて、z 軸を中心とした回転のみがある場合、この方向は変更されません。実際には、おそらく数度変化するので、平均を取る必要があります。
Math.atan2(a[6], a[7]) を除くすべての数学はAndroid で説明されています: SensorManager.getRotationMatrix と SensorManager.getOrientation() の
アルゴリズム平らな。
上記のリンクで説明したように、固定ベクトルと変化するベクトルを指定して、それらの間の角度を計算する必要があります。この場合、変化するベクトルはデバイスの y 軸にあるベクトルであり、固定ベクトルはデバイスの xy 平面への重力ベクトルの投影です。最後の行の上の回転行列は、デバイス座標で正規化された重力ベクトルであるため、デバイスの xy 平面への投影は (a[6], a[7]) です。Math.atan2(a[6], a[7]) がデバイスの y 軸と重力投影の間の角度であることを確認するのは単純な三角法です。(見えない場合は絵を描いてください)。