Calcular o cabeçalho da bússola a partir da API de eventos do DeviceOrientation

Para um aplicativo da web de realidade aumentada para smartphones, estou tentando calcular o rumo da bússola quando o usuário está segurando o dispositivo na mão, com a tela em um plano vertical e a parte superior da tela apontando para cima.

Tomei a fórmula sugerida dehttp://dev.w3.org/geo/api/spec-source-orientation (veja o exemplo trabalhado) e implementou a seguinte função:

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;
    }
}

enquanto .toDeg () é uma cortesia de extensão de objeto de númerohttp://www.movable-type.co.uk/scripts/latlong.html

/** Converts radians to numeric (signed) degrees */
if (typeof Number.prototype.toDeg == 'undefined') {
    Number.prototype.toDeg = function() {
        return this * 180 / Math.PI;
    };
}  

No entanto, o problema é que o valor do cabeçalho da bússola calculada salta de cerca de -75 a 80, mesmo se o dispositivo (Google Galaxy Nexus) estiver montado para manter uma posição estática. Isso parece acontecer tanto no Google Chrome BETA quanto no FF BETA 23.

Alguém vê um erro na minha abordagem ou conhece uma maneira mais confiável de calcular o rumo da bússola?

questionAnswers(3)

yourAnswerToTheQuestion