Android 官方对 pitch 的正负是这样定义的(用一个特定握持姿势来说明):
-
先把设备屏幕朝上、平行于地面放着,并且让底边靠近你、顶边远离你。
-
这时 pitch≈0。
-
如果你把顶边朝地面压下去,pitch 变 正;
-
如果你把顶边抬起来、远离地面,pitch 变 负。
所以你说的“手机平放 pitch≈0;竖直立起来(顶边朝上)pitch≈-90°”——如果你是从“平放屏幕朝上”开始,把顶边抬起来立到垂直,那就是“顶边远离地面”,pitch 走向负值并接近 -90°,完全符合官方描述。 反过来,如果你把手机以另一种方式竖起来(比如顶边朝下,或者你从另一侧去翻),也可能接近 +90°。±90 的区别主要来自你是把“顶边”往地面压还是往上抬。
Y 轴怎么定义?
在 Android 传感器框架里(设备处于默认朝向时):
-
X:指向屏幕右侧
-
Y:指向屏幕上方(朝顶边/听筒方向)
-
Z:从屏幕朝外(朝你)
所以问“Y 是不是手机底部到顶部的线?”——对(在默认竖屏设备上就是底边→顶边方向)。
Y 轴会不会“随平躺/直立而移动”?
-
轴是“固定在手机上的”:你把手机拿起来转动、平放/直立,X/Y/Z 会跟着手机一起在空间里转动(因为它们本来就是设备坐标)。
-
但 轴的定义不会因为屏幕旋转(portrait/landscape)就互换:也就是说,你把 UI 旋到横屏,传感器坐标轴不会自动改成“横屏的右/上”,它仍然是按设备默认朝向定义的那套轴。
Roll 的正负怎么直观理解?
官方同样用“屏幕朝上、底边靠近你”的姿势定义 roll 正负:
-
左边缘向地面倾斜 → roll 为正
-
右边缘向地面倾斜 → roll 为负
关于 Android的传感器TYPE_ROTATION_VECTOR,它表示world——>device 对 TYPE_ROTATION_VECTOR 来说,Android 的 world(参考系)基本是:
- Z:向上(天空)
- Y:指向磁北(magnetic north)
- X:由右手系确定(大致指向东) 所以 Android 的 world→device 四元数是:把这个“ENU(磁北)”参考系旋到设备坐标系。
安卓的device坐标系
- 屏幕x右/
- y上/
- z出屏
colmap的camera坐标系
- X右
- Y下
- Z前
对于鸿蒙设备的传感器
ROTATION_VECTOR 它同样使用ENU作为世界坐标系,但它返回的是device——>world