title: Android: Algorithms for SensorManager.getRotationMatrix and SensorManager.getOrientation()
body: <p>To get orientation as a from of euler angles (e.g., pitch, roll, azimuth) in Android, it is required to execute followings:</p>
  
  <ol>
  <li>SensorManager.getRotationMatrix(float[] R, float[] I, float[] gravity, float[] geomagnetic); <br/></li>
  <li>SensorManager.getOrientation(float[] R, float[] orientation); <br/></li>
  </ol>
  
  <p>In the first one, I realize that it uses a kind of TRIAD algorithms; Rotation matrix (R[]) is composed of gravity, geomagnetic X gravity, gravity X (geomagnetic X gravity) --- X is cross product. <br/> See codes below:</p>
  
  <pre><code>    float Ax = gravity[0];
      float Ay = gravity[1];
      float Az = gravity[2];
      final float Ex = geomagnetic[0];
      final float Ey = geomagnetic[1];
      final float Ez = geomagnetic[2];
      float Hx = Ey*Az - Ez*Ay;
      float Hy = Ez*Ax - Ex*Az;
      float Hz = Ex*Ay - Ey*Ax;
      final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
      if (normH &lt; 0.1f) {
          // device is close to free fall (or in space?), or close to
          // magnetic north pole. Typical values are  &gt; 100.
          return false;
      }
      final float invH = 1.0f / normH;
      Hx *= invH;
      Hy *= invH;
      Hz *= invH;
      final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
      Ax *= invA;
      Ay *= invA;
      Az *= invA;
      final float Mx = Ay*Hz - Az*Hy;
      final float My = Az*Hx - Ax*Hz;
      final float Mz = Ax*Hy - Ay*Hx;
      if (R != null) {
          if (R.length == 9) {
              R[0] = Hx;     R[1] = Hy;     R[2] = Hz;
              R[3] = Mx;     R[4] = My;     R[5] = Mz;
              R[6] = Ax;     R[7] = Ay;     R[8] = Az;
          } else if (R.length == 16) {
              R[0]  = Hx;    R[1]  = Hy;    R[2]  = Hz;   R[3]  = 0;
              R[4]  = Mx;    R[5]  = My;    R[6]  = Mz;   R[7]  = 0;
              R[8]  = Ax;    R[9]  = Ay;    R[10] = Az;   R[11] = 0;
              R[12] = 0;     R[13] = 0;     R[14] = 0;    R[15] = 1;
          }
      }
  </code></pre>
  
  <p>However, I cannot understand SensorManager.getOrientation(). </p>
  
  <pre><code> azimuth = (float)Math.atan2(R[1], R[4]);
   pitch = (float)Math.asin(-R[7]);
   roll = (float)Math.atan2(-R[6], R[8]);
  </code></pre>
  
  <p>What is the exact algorithms to get euler angles? </p>