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 坐标系与传感器数据可视化
下面这张图展示了手机平放时,三轴与引力方向的关系。我特意把坐标系画出来,方便你对照理解:
5.7 坐标系变换:从设备坐标系到世界坐标系
有时候我们需要把设备坐标系的数据转换到世界坐标系。比如做AR应用时,需要知道手机相对于地面的姿态。这时候就要用到SensorManager.getRotationMatrix()和SensorManager.getOrientation()。
这个转换过程涉及一些线性代数知识。我建议你先把这个基础坐标系吃透,后面学变换矩阵时会轻松很多。嗯,这里先不展开,我们后面有专门章节讲这个。
一句话总结:X轴向右,Y轴向上,Z轴向外。静止时Z轴读数为+9.8,因为传感器测的是支撑力而不是引力。记住这个,后面所有加速度传感器的应用都建立在这个基础上。
公众号:蓝海资料掘金营,微信deep3321