title: Android SensorManager strange how to remapCoordinateSystem
body: <p>API Demos -> Graphics -> <a href="http://gitorious.org/freebroid/development/source/62e92d7a2a3fd2798901ec2e7c452ff0e4067163:samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java" rel="noreferrer">Compass</a></p>
  
  <p>It works properly only, until you don't change the device natural orientation.
  In most phones is the portrait and most 10 inch tablets are the landscape. If you change than need to rotate this with 90 degree. I would like to see a 3D fix for that system. </p>
  
  <p><strong>100% sure need to use <a href="http://developer.android.com/reference/android/hardware/SensorManager.html#remapCoordinateSystem%28float%5B%5D,%20int,%20int,%20float%5B%5D%29" rel="noreferrer">remapCoordinateSystem()</a> method.</strong></p>
  
  <p>I would like to see how ( code ) if I could see an explanation with how is calculated those axes mapping ( theoretical math ) it would be nice.</p>
  
  <p>I have tryed to understand, but I forgot all linear algebra.</p>
  
  <p><a href="http://android-developers.blogspot.ro/2010/09/one-screen-turn-deserves-another.html" rel="noreferrer">Here</a> it says why must we use, but doesn't telling how!</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>It seems those coordinates are to this position: - the device say in a table (x, and y axes are on table)</p>
  
  <p><img src="https://i.stack.imgur.com/v21Fb.png" alt="device orientation"></p>
  
  <p>Only and only if </p>
  
  <pre><code>getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_0
  </code></pre>
  
  <p>The question is how to complete this code: - those case branches</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>Edit:
  I wrote a little test application, where on the screen it display the screen rotation: 0, 90, 270 degrees ( can't make 180 now)</p>
  
  <p>It seems, if Rotation 0 is unchanged (<code>axisX = SensorManager.AXIS_X;axisY = SensorManager.AXIS_Y;</code>) than the 90 degree should be: </p>
  
  <pre><code>axisX = SensorManager.AXIS_MINUS_Y;
  axisY = SensorManager.AXIS_X;
  </code></pre>
  
  <p>than the Google documentation says somewhere wrong values! Question is where?!</p>
  
  <p><a href="http://developer.android.com/reference/android/hardware/SensorManager.html#getRotationMatrix%28float%5B%5D,%20float%5B%5D,%20float%5B%5D,%20float%5B%5D%29" rel="noreferrer">getRotationMatrix</a> return this:</p>
  
  <p><img src="https://i.stack.imgur.com/t9B2z.png" alt="enter image description here"></p>
  
  <blockquote>
    <p>X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East). </p>
    
    <p>Y is tangential to the ground at the device's current location and points towards the magnetic North Pole. </p>
    
    <p>Z points towards the sky and is perpendicular to the ground.</p>
  </blockquote>
  
  <p>See the phone above! I want to to to right from left, with back camera to ground.</p>
  
  <p><a href="http://developer.android.com/reference/android/hardware/SensorManager.html#getOrientation%28float%5B%5D,%20float%5B%5D%29" rel="noreferrer">getOrientation</a> return this:</p>
  
  <p><img src="https://i.stack.imgur.com/nI9lD.gif" alt="enter image description here"></p>
  
  <blockquote>
    <p>X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points West). </p>
    
    <p>Y is tangential to the ground at the device's current location and points towards the 
    magnetic North Pole. </p>
    
    <p>Z points towards the center of the Earth and is perpendicular to the ground.</p>
    
    <p><code>values[0]</code>: azimuth, rotation around the Z axis. </p>
    
    <p><code>values[1]</code>: pitch, rotation around the X axis. </p>
    
    <p><code>values[2]</code>: roll, rotation around the Y axis.</p>
  </blockquote>
  
  <p>How should be the phone?</p>
  
  <p>Finally I would like to have values of angles like aircrafts. My phone (me) heading to North:  (yaw is azimuth)</p>
  
  <p><img src="https://i.stack.imgur.com/mOg9o.png" alt="enter image description here"></p>
  
  <pre><code>              if ScreenRotation = 0 degree
  Pitch axis = -orientationAxisX  =  rotationAxisX
  Roll axis  =  orientationAxisY  =  rotationAxisY 
  Yaw axis   =  orientationAxisZ  = -rotationAxisZ
  </code></pre>