获取安卓设备的欧拉偏航角

3

我正在尝试获取以欧拉角表示的安卓设备的偏航角。

明确一下,我不想要“方位角”(即相对于磁北极的角度),我想要安卓设备“z”轴的旋转角度,如此图片所示。

enter image description here

我认为这应该是一些汽车游戏中用来确定转向量的轴。

据我了解,我可以只使用加速度计值(不包括磁场),但我无法获得确定的值。(可能是由于我不理解旋转矩阵的工作原理)。

有人能指点我朝正确的方向吗?


这听起来像是陀螺仪 - http://developer.android.com/guide/topics/sensors/sensors_motion.html#sensors-motion-rotate 但我不清楚实际问题是什么。 - Morrison Chang
那么在图片中,90度的旋转将把手机从竖屏模式转换为横屏模式。这是您想要的旋转吗?如果是的话,那么我已经在https://dev59.com/D2gu5IYBdhLWcg3wpYnJ#15149421 中使用加速计回答了这个问题。 - Hoan Nguyen
我将发布一个答案,允许您确定 z 轴旋转与设备位置无关,明天再来看。同时,您应该阅读我的答案,了解 https://dev59.com/rY7ea4cB1Zd3GeqPFL2y#35390001 中 getOrientation 的详细答案,以便您能够理解我即将发布的答案。 - Hoan Nguyen
1个回答

2
如果您想独立于设备位置(即平面或非平面)计算设备绕z轴的旋转,则需要跟踪一些内容。如果应用程序支持纵向和横向,则情况更为复杂。我将在仅限于纵向的情况下给出答案。
这里的“平面”意味着俯仰角小于25度或大于155度,否则就不是平面。
当设备从平面到非平面或反之转换时,UI可能会出现一些不一致。
注册TYPE_GRAVITY和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])

  • 如果设备一开始就是平面的,请获取初始方位角= Math.atan2(R[1], R[4]),然后取与后续方位角的差值即可获得旋转。

  • 如果设备从平面到非平面转换,则不应该有问题,旋转就是上述非平面旋转。

  • 如果设备从非平面到平面转换,则需要获取初始方位角。如果设备竖立且只有绕z轴的旋转,则此初始方向应不会改变,可以将其设置为后置摄像头方向Math.atan2(-a [2],-a [5])。实际情况可能会稍微改变几度,因此您需要取平均值。

除了Math.atan2(a[6], a[7])之外的所有数学内容都在Android: Algorithms for SensorManager.getRotationMatrix and SensorManager.getOrientation()中解释了。
因此,让我解释一下如何找到设备非平面旋转的原理。
如上面的链接所解释的,您需要指定固定向量和变化向量,以计算它们之间的角度。在这种情况下,变化的向量是位于设备y轴上的向量,而固定向量是重力向量在设备xy平面上的投影。在上面的旋转矩阵中,最后一行是设备坐标系中的归一化重力向量,因此投影到设备xy平面上的向量为(a[6],a[7])。现在使用简单的三角函数可以得出Math.atan2(a[6], a[7])是设备y轴和重力投影之间的角度。(如果您看不到,请画个图)。

你好@Hoean Nguyen,感谢你的努力。我非常感激。我尝试理解这个和链接答案,但我可能缺少一些数学背景(或者缺少图像可能会阻碍我)。我想更多地了解事情是如何工作的,但同时我可能已经通过执行Math.atan2(gX, gY)解决了问题,其中gX是TYPE_GRAVITY的values [0],gY是values [1]。 - Andrea Baccega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接