Android SensorManager extraño cómo volver a correlacionar el sistema de coordenadas

Demos de API -> Gráficos ->Brújula

Solo funciona correctamente, hasta que no cambie la orientación natural del dispositivo. En la mayoría de los teléfonos es el retrato y la mayoría de las tabletas de 10 pulgadas son el paisaje. Si cambias de lo necesario deberás rotarlo con 90 grados. Me gustaría ver una solución 3D para ese sistema.

100% seguro de usarremapCoordinateSystem () método.

Me gustaría ver cómo (código) si pudiera ver una explicación de cómo se calculan esos ejes (matemática teórica) sería bueno.

He intentado entender, pero olvidé todo álgebra lineal.

aquí dice por qué debemos usar, pero no dice cómo!

float R[] = new float[9];
// X  (product of Y and Z) and roughly points East
// Y: points to Magnetic NORTH and tangential to ground
// Z: points to SKY and perpendicular to ground
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);

Parece que esas coordenadas están en esta posición: - el dispositivo dice en una tabla (los ejes x, y y están en la tabla)

Solo y solo si

getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_0

La pregunta es cómo completar este código: - esas ramas de casos

switch (mScreenRotation) {
    case Surface.ROTATION_0:
    Log.v("SurfaceRemap", "0 degree");
    axisX = SensorManager.AXIS_X;// is this valid?
    axisY = SensorManager.AXIS_Y;// is this valid?
    break;

    case Surface.ROTATION_90:
    Log.v("SurfaceRemap", "90 degree");
    // examples says remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);
    axisX = SensorManager.AXIS_Y;
    axisY = SensorManager.AXIS_MINUS_X;
    break;

    case Surface.ROTATION_180:
    Log.v("SurfaceRemap", "180 degree");
    break;

    case Surface.ROTATION_270:
    Log.v("SurfaceRemap", "270 degree");
    break;

    default:
    Log.v("SurfaceRemap", "don't know the mScreenRotation value: "+mScreenRotation+" you should never seen this message!");
    break;
}


boolean remapped = SensorManager.remapCoordinateSystem(R, axisX, axisY, R);

float orientation[] = new float[3];

SensorManager.getOrientation(R, orientation);// All three angles above are in radians and positive in the counter-clockwise direction.
inclination = SensorManager.getInclination(I);

Edit: escribí una pequeña aplicación de prueba, donde en la pantalla muestra la rotación de la pantalla: 0, 90, 270 grados (no se puede hacer 180 ahora)

Parece que si la rotación 0 no cambia (axisX = SensorManager.AXIS_X;axisY = SensorManager.AXIS_Y;) que el grado 90 debe ser:

axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;

que la documentación de Google dice valores equivocados! La pregunta es ¿dónde?

getRotationMatrix devuelve esto:

X se define como el producto vectorial Y.Z (Es tangencial al suelo en la ubicación actual del dispositivo y aproximadamente apunta al Este).

Y es tangencial al suelo en la ubicación actual del dispositivo y apunta hacia el Polo Norte magnético.

Z apunta hacia el cielo y es perpendicular al suelo.

¡Vea el teléfono de arriba! Quiero hacerlo a la derecha desde la izquierda, con la cámara de atrás al suelo.

getOrientation devuelve esto:

X se define como el producto vectorial Y.Z (es tangencial al suelo en la ubicación actual del dispositivo y aproximadamente al oeste).

Y es tangencial al suelo en la ubicación actual del dispositivo y apunta hacia el Polo Norte magnético.

Z apunta hacia el centro de la Tierra y es perpendicular al suelo.

values[0]: azimut, rotación alrededor del eje Z.

values[1]: paso, rotación alrededor del eje X.

values[2]: Roll, rotación alrededor del eje Y.

¿Cómo debe ser el teléfono?

Finalmente me gustaría tener valores de ángulos como aviones. Mi teléfono (yo) hacia el Norte: (guiñada es azimut)

              if ScreenRotation = 0 degree
Pitch axis = -orientationAxisX  =  rotationAxisX
Roll axis  =  orientationAxisY  =  rotationAxisY 
Yaw axis   =  orientationAxisZ  = -rotationAxisZ

Respuestas a la pregunta(5)

Su respuesta a la pregunta