title: Calculate compass heading from DeviceOrientation Event API
body: <p>For an augmented reality web app for smartphones I'm trying to calculate the compass heading when the user is holding the device in their hand, with the screen in a vertical plane and the top of the screen pointing upwards.</p>
  
  <p>I have taken the suggested formula from <a href="http://dev.w3.org/geo/api/spec-source-orientation" rel="noreferrer">http://dev.w3.org/geo/api/spec-source-orientation</a> (see Worked Example) and implemented the following function:</p>
  
  <pre><code>function compassHeading(alpha, beta, gamma) {
      var a1, a2, b1, b2;
      if ( beta !== 0 || gamma !== 0 ) {
          a1 = -Math.cos(alpha) * Math.sin(gamma);
          a2 = Math.sin(alpha) * Math.sin(beta) * Math.cos(gamma);
          b1 = -Math.sin(alpha) * Math.sin(gamma);
          b2 = Math.cos(alpha) * Math.sin(beta) * Math.cos(gamma);
          return Math.atan((a1 - a2) / (b1 + b2)).toDeg();
      }
      else {
          return 0;
      }
  }
  </code></pre>
  
  <p>while .toDeg() is a Number object extension courtesy <a href="http://www.movable-type.co.uk/scripts/latlong.html" rel="noreferrer">http://www.movable-type.co.uk/scripts/latlong.html</a></p>
  
  <pre><code>/** Converts radians to numeric (signed) degrees */
  if (typeof Number.prototype.toDeg == 'undefined') {
      Number.prototype.toDeg = function() {
          return this * 180 / Math.PI;
      };
  }  
  </code></pre>
  
  <p>However, the problem is that the calculated compass heading value jumps from about -75 to 80 even if the device (Google Galaxy Nexus) is mounted to hold a static position. This seems to happen in both Google Chrome BETA and FF BETA 23.</p>
  
  <p>Does somebody see an error in my approach or know a more reliable way to calculate the compass heading?</p>