我正在开发一款类似于相机应用的应用,相机预览中心有一条线,显示设备相对于地平线的倾斜度。
我只使用加速度计,因为我的用例是半固定设备(用户可能会移动并倾斜它并且线路会更新,但如果设备有点静止,他们应该只能期待公平读数)
这是我到目前为止所得到的:
public void onSensorChanged(SensorEvent event) {
switch( event.sensor.getType() ){
case Sensor.TYPE_ACCELEROMETER:
float[] acc = event.values.clone(); // [accX, accY, accZ]
double gravityNormalized = Math.sqrt(acc[0]*acc[0] + acc[1]*acc[1] + acc[2]*acc[2]);
double[] accNormalized = new double[3];
accNormalized[0] = acc[0]/gravityNormalized;
accNormalized[1] = acc[1]/gravityNormalized;
accNormalized[2] = acc[2]/gravityNormalized;
double[] tiltDegrees = new double[3];
tiltDegrees[0] = Math.toDegrees(Math.asin(accNormalized[0]));
tiltDegrees[1] = Math.toDegrees(Math.asin(accNormalized[1]));
tiltDegrees[2] = Math.toDegrees(Math.asin(accNormalized[2]));
Log.d(TAG, "tiltDegrees: " + Arrays.toString(tiltDegrees) + ", accNormalized: " + Arrays.toString(accNormalized) + ", acc: " + Arrays.toString(acc) );
((ImageView) findViewById(R.id.levelLine)).setRotation((int)tiltDegrees[0]);
break;
}
}
只要轮换适中,它似乎运作得相当好。当我开始接近设备的90度旋转(纵向方向与地平线)时,线路停止旋转,因此不再与地平线对齐,而是略微倾斜(我说大约5-10度)。此外,如果我继续将设备旋转超过90度,则当设备旋转135度-135度时,线条会越来越远离地平线并变为垂直线。
我在这里做错了吗?是否有更好的方法让设备倾斜?
进一步在开发中,我需要准确地“向前/向后”倾斜(即,在纵向方向上电话向前/向后倾斜多少度)。我想我可以使用我现在正在做的相同方法但是在tiltDegrees[1]
而不是tiltDegrees[0]
?
我有点奇怪,有一个TYPE_ROTATION_VECTOR
与世界框架(北/南/东/西)相关但没有设备框架TYPE_DEVICE_VECTOR
或类似的东西很容易获得设备沿X,Y和Z轴的旋转(例如,与完美的纵向模式相关)。