Android SensorManager estranho como remapearCoordinateSystem

Demonstrações da API -> Gráficos ->Bússola

Ele funciona corretamente apenas até você não alterar a orientação natural do dispositivo. Na maioria dos telefones, o retrato e a maioria dos tablets de 10 polegadas são a paisagem. Se você mudar, precisará girar isso em 90 graus. Eu gostaria de ver uma correção 3D para esse sistema.

100% de certeza de usarremapCoordinateSystem () método.

Eu gostaria de ver como (código) se eu pudesse ver uma explicação com como é calculado o mapeamento desses eixos (matemática teórica) seria legal.

Eu tentei entender, mas esqueci toda a álgebra linear.

Aqui diz porque devemos usar, mas não diz como!

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 essas coordenadas são para esta posição: - o dispositivo diz em uma tabela (os eixos xey estão na mesa)

Apenas e somente se

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

A questão é como concluir este código: - as ramificações de caso

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: Eu escrevi um pequeno aplicativo de teste, onde na tela ele exibe a rotação da tela: 0, 90, 270 graus (não pode fazer 180 agora)

Parece, se a rotação 0 está inalterada (axisX = SensorManager.AXIS_X;axisY = SensorManager.AXIS_Y;) do que os 90 graus devem ser:

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

do que a documentação do Google diz em algum lugar valores errados! A questão é onde ?!

getRotationMatrix devolva isto:

X é definido como o produto vetorial Y.Z (é tangencial ao solo na localização atual do dispositivo e, aproximadamente, aponta para o leste).

Y é tangencial ao solo na localização atual do dispositivo e aponta para o pólo norte magnético.

Z aponta para o céu e é perpendicular ao solo.

Veja o telefone acima! Eu quero para a direita da esquerda, com a câmera de volta ao chão.

getOrientation devolva isto:

X é definido como o produto vetorial Y.Z (é tangencial ao solo na localização atual do dispositivo e, aproximadamente, aponta para Oeste).

Y é tangencial ao solo na localização atual do dispositivo e aponta para o pólo norte magnético.

Z aponta para o centro da Terra e é perpendicular ao solo.

values[0]: azimute, rotação ao redor do eixo Z.

values[1]: pitch, rotação ao redor do eixo X.

values[2]: roll, rotação ao redor do eixo Y.

Como deve ser o telefone?

Finalmente gostaria de ter valores de ângulos como aeronaves. Meu telefone (eu) indo para o norte: (o yaw é azimute)

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

questionAnswers(5)

yourAnswerToTheQuestion