在Android应用中重新映射坐标系

4

我正在开发一款简单的Android应用程序,其中需要识别北方。

因此,我实现了SensorEventListener,并使用了类似于以下内容的代码:

@Override
public void onSensorChanged(SensorEvent event) {
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
    {
        SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
        SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, orientationVals);
        SensorManager.getOrientation(mRotationMatrix, orientationVals);

        orientationVals[0] = (float) Math.toDegrees(orientationVals[0]);
        orientationVals[1] = (float) Math.toDegrees(orientationVals[1]);
        orientationVals[2] = (float) Math.toDegrees(orientationVals[2]);

        tv.setText(" Yaw: "+ orientationVals[0] +"\n Pitch: "+ orientationVals[1]+"\n Roll: "+ orientationVals[2]);
    }

}

问题在于代码行

SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, orientationVals);

似乎不起作用,因为无论是否有这行代码,Yaw(方位角)的值都取决于手机头部的朝向(让其放在背面)。

我期望的是,使用我的重新映射,Yaw会根据手机后面(即后置摄像头)的朝向而改变。

为什么我的重新映射不起作用?

2个回答

3
不确定您是否解决了此问题,但您的代码行:
SensorManager.remapCoordinateSystem(mRotationMatrix,SensorManager.AXIS_X,SensorManager.AXIS_Z,orientationVals);
重新映射mRotationMatrix中的值,并将结果放入orientationVals中。这是正确的(除了对重映射坐标数组的令人困惑的变量名称之外)。
但是,您随后通过调用以下内容直接覆盖了此映射:
SensorManager.getOrientation(mRotationMatrix,orientationVals);
这将使用mRotationMatrix中的值计算基于那些(旧的、未重新映射的)值的方向,并将其存储在orientationVals中。
因此,您上面的代码只是获取mRotationMatrix的方向,其轴没有被重新映射,这可能解释了您的问题。
类似以下内容的东西可能会解决您的问题:
float[] remapCoords = new float[16];
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapCoords);
SensorManager.getOrientation(remapCoords, orientationVals);

假设您的轴重新映射是您实际想要/正确的,但这是另一个问题。
我应该注意到引用文章,虽然非常出色,但并没有明确提到重新映射坐标系必须在每次计算旋转矩阵时调用,而不仅仅是在显示更改时(即onCreate、onSurfaceChanged等),这对某些人来说可能是显而易见的,但对其他人来说可能不是。

0

我用了这个:

/* Compensate device orientation */
            float[] remappedRotationMatrix = new float[9];
            switch (getWindowManager().getDefaultDisplay()
                    .getRotation()) {
            case Surface.ROTATION_0:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_X, SensorManager.AXIS_Y,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_90:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_Y,
                        SensorManager.AXIS_MINUS_X,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_180:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_MINUS_X,
                        SensorManager.AXIS_MINUS_Y,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_270:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_MINUS_Y,
                        SensorManager.AXIS_X, remappedRotationMatrix);
                break;
            }

            /* Calculate Orientation */
            float results[] = new float[3];
            SensorManager.getOrientation(remappedRotationMatrix,
                    results);

请告诉我它是否有效,因为我仍然在使用那个解决方案时遇到问题。这是我自己从这里编写的代码。我是基于这篇官方文章编写的。

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