5、坐标系与三轴:手机加速度传感器的X、Y、Z轴定义

加速度传感器到底在测什么?说白了,它测的是「力」。但这个力不是我们推东西的力,而是作用在手机上的加速度力。嗯,这里有个关键点——它测的是相对于自由落体的加速度。手机静止放在桌上时,它测到的是地球引力,约9.8 m/s²。

那这个力是怎么被分解成X、Y、Z三个方向的呢?我刚开始接触这个时也绕了一阵子。今天我们就把它彻底讲清楚。

5.1 手机加速度传感器的坐标系定义

Android官方文档里有一套标准定义。我个人习惯把它记成「手机平放,屏幕朝上」的基准姿态。你想想看,手机平躺在桌上时:

  • X轴:水平向右。也就是手机的宽度方向,从左边指向右边。
  • Y轴:水平向前。也就是手机的长度方向,从底部指向顶部。
  • Z轴:垂直向上。垂直于屏幕,从手机背面指向正面。

这个坐标系是固定在手机上的。也就是说,不管你手机怎么转,这个坐标系跟着手机一起转。这一点非常重要,我在项目中遇到过不少新手在这里栽跟头。

核心要点:手机加速度传感器的坐标系是「设备坐标系」,不是「世界坐标系」。它跟着手机走,不跟着地球走。

5.2 静止状态下的三轴读数

当手机静止时,加速度传感器测到的是地球引力。这个引力矢量始终指向地心,大小为9.8 m/s²(我们通常用g表示,1g ≈ 9.8 m/s²)。

那这个引力在三个轴上的分量是多少?这完全取决于手机的摆放姿态。我给大家列几个典型场景:

手机姿态 X轴读数 Y轴读数 Z轴读数 说明
平放,屏幕朝上 0 0 +9.8 Z轴正方向与引力方向相反
平放,屏幕朝下 0 0 -9.8 Z轴正方向与引力方向相同
竖屏,屏幕正对脸 0 +9.8 0 Y轴正方向指向天空
横屏,屏幕正对脸 +9.8 0 0 X轴正方向指向天空

小技巧:你可以用这个特性来判断手机的姿态。比如,Z轴读数接近+9.8,说明手机基本平放。Y轴读数接近+9.8,说明手机是竖屏状态。我在做体感游戏时,就用这个原理来检测手机是横着拿还是竖着拿。

5.3 为什么Z轴静止时是+9.8而不是-9.8?

这个问题我当年也困惑过。你想想看,引力明明是向下拉的,为什么传感器读出来是正的?

原因在于:加速度传感器测的是「支撑力」,不是「引力」。手机放在桌上时,桌面给手机一个向上的支撑力,这个力正好抵消引力。传感器检测到这个向上的力,所以Z轴读数是正的。

如果手机做自由落体运动,支撑力消失,三个轴的读数都会变成0。这就是所谓的「失重」状态。我曾经在电梯里测试过——电梯开始下降的瞬间,Z轴读数会短暂小于9.8,感觉就像手机变轻了。

5.4 坐标系与传感器数据的关系

在Android代码中,我们通过SensorEvent.values数组获取三轴数据:

// values[0] = X轴加速度(单位:m/s²)
// values[1] = Y轴加速度(单位:m/s²)
// values[2] = Z轴加速度(单位:m/s²)

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        
        // 计算总加速度大小
        double magnitude = Math.sqrt(x*x + y*y + z*z);
        
        // 如果接近9.8,说明手机基本静止
        if (Math.abs(magnitude - 9.8) < 0.5) {
            // 手机处于静止或匀速运动状态
        }
    }
}

注意:不同手机的传感器可能有微小差异。我遇到过一些国产手机,静止时Z轴读数在9.75到9.85之间波动,这很正常。不要死磕精确的9.8,给一个±0.2的容差范围会更稳妥。

5.5 坐标系在应用中的实际意义

理解了坐标系,很多功能就能做了:

  • 屏幕旋转:通过X、Y轴的读数判断手机是横屏还是竖屏
  • 计步器:分析Z轴的变化规律,检测走路时的上下震动
  • 体感游戏:根据三轴数据模拟手机的姿态和运动
  • 防抖算法:通过三轴数据判断手机是否在抖动

我个人觉得,坐标系是整个加速度传感器知识体系的地基。地基没打牢,后面做啥都容易出问题。我曾经有个项目,做手机拍照防抖,就是因为坐标系理解错了,导致防抖方向完全反了——手机往左抖,画面往右移得更厉害。嗯,那次调试花了我整整两天。

5.6 坐标系与传感器数据可视化

下面这张图展示了手机平放时,三轴与引力方向的关系。我特意把坐标系画出来,方便你对照理解:

手机(屏幕朝上) X Y Z (向外) 引力 g (向下) 图例: X轴(红色) Y轴(绿色) Z轴(橙色,向外) 引力方向(紫色虚线) 手机平放时,Z轴正方向向上,引力方向向下,所以Z轴读数为 +9.8 m/s²

5.7 坐标系变换:从设备坐标系到世界坐标系

有时候我们需要把设备坐标系的数据转换到世界坐标系。比如做AR应用时,需要知道手机相对于地面的姿态。这时候就要用到SensorManager.getRotationMatrix()SensorManager.getOrientation()

这个转换过程涉及一些线性代数知识。我建议你先把这个基础坐标系吃透,后面学变换矩阵时会轻松很多。嗯,这里先不展开,我们后面有专门章节讲这个。

一句话总结:X轴向右,Y轴向上,Z轴向外。静止时Z轴读数为+9.8,因为传感器测的是支撑力而不是引力。记住这个,后面所有加速度传感器的应用都建立在这个基础上。


公众号:蓝海资料掘金营,微信deep3321