在安卓系统中如何计算相对方位,给定方位角、俯仰角和翻滚角?

4
当我在安卓应用中监听方向事件时,我会得到一个SensorEvent,其中包含了3个浮点数 - 方位角、俯仰角和横滚角,这些角度与现实世界的坐标轴有关。
现在假设我正在构建一个像迷宫一样的应用程序,但我不想强制用户将手机放置在地面上并使xy平面与地面平行。相反,我希望能够允许用户按照自己的意愿握着手机,躺下或者坐着,或者以一定的角度握着手机。换句话说,我需要根据用户的喜好来校准手机。
我该怎么做呢?
请注意,我认为我的答案与getRotationMatrix和getOrientation有关,但是我不确定如何使用!
请帮忙!我已经被困在这里几个小时了。
2个回答

3
对于迷宫风格的应用程序,您可能更关心加速度(重力)矢量而不是轴方向。在手机坐标系中,该矢量由三个加速计测量值的组合给出,而不是旋转角度。具体来说,只有xy读数应影响小球的运动。
如果您确实需要方向,则3个角度读数表示3个欧拉角。但是,我怀疑您可能并不真正需要角度本身,而是由getRotationMatrix() API返回的旋转矩阵R。一旦您拥有了这个矩阵,那么它基本上就是您正在寻找的校准。当您想要将世界坐标中的向量转换为设备坐标时,应将其乘以此矩阵的逆矩阵(在这种特殊情况下,inv(R) = transpose(R))。
因此,按照我在文档中找到的示例,如果您想将世界重力向量g([0 0 g])转换为设备坐标,请将其乘以inv(R): g = inv(R) * g (请注意,这应该会给您与读取加速度计相同的结果)
此处可能使用的API:矩阵类的invertM()multiplyMV()方法。

加速度计和方向传感器之间到底有什么区别?如果我关心的是手机的旋转,为什么我需要加速度计?游戏需要根据用户倾斜手机而不是加速度来反应。我相信你说的是对的,但我无法理解! - Gallal
@Gallal - 首先,即使我也可能会错(有时候...);-)。现在,我假设你正在尝试实现一个迷宫风格的游戏。在这个游戏中,重力矢量分量决定了球的运动。当你把手机向某个方向倾斜(不需要真的移动它-“加速”),设备坐标中的重力就在x和y方向上有一些非零分量。这些分量是由x和y加速度计测量的。z方向的运动受到游戏板的限制。球就是无法在z方向上移动。 - ysap
我现在已经得到了R和I,使用getRotationMatrix(R, I, mGravity, mGeomagnetic)方法。当调用此方法并获取未来参考的R时,手机的位置处于所需的位置(即当用户点击“校准”时)。从这一点开始,我不断地获得Sensor.TYPE_MAGNETIC_FIELD类型的SensorEvent(s)。我该如何处理新事件?@ysap,非常感谢您的帮助。就像我说的,我已经被困在这个问题上好几天了;我对“空间”关键思维并不是很擅长! - Gallal
@Gallal - 如果我理解您的问题,那么您想要实现的是设备的“重置”位置,作为进一步旋转的参考。所以,当用户点击 校准 时,您会存储结果 R 矩阵(称其为 Ri)。然后,您需要从游戏时间中您的设备进一步读取的数据中“减去”这个矩阵,该矩阵表示从世界坐标到初始设备方向的旋转。基本上,当前方向(Rc)到初始方向(Ri)的旋转矩阵 RR = inv(Ri) * Rc - ysap
在旋转矩阵数学中,“加法”旋转是旋转矩阵的乘积。因此,“减法”是与逆矩阵的乘积。 - ysap

0

我不知道有任何特定于Android的API,但你想做的只是将方位角减少一定量,对吧?所以你将“原点”从(0,0,0)移动到他们想要的任何位置。伪代码如下:

myGetRotationMatrix:
    return getRotationMatrix() - origin

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