I'm using code from here and here to determine which way the phone is facing when looking through the camera.
After initialization, the code seems very fluid and consistent. The problem is that it seems no matter which way my device is pointing when I load the code, that becomes 90 degrees (actually 89.7ish). This is an obvious issue because now I can't simply say dir < 45 && dir > 315 = "south"
.
Is this due to my specific hardware/software? (Pixel XL, Chrome mobile) or am I doing something wrong in the code?
update: I experience the same behavior with complex compasses like this one from ArcGIS and this Marine Compass demo.
Here is the full code:
function compassHeading(alpha, beta, gamma) {
// Convert degrees to radians
var alphaRad = alpha * (Math.PI / 180);
var betaRad = beta * (Math.PI / 180);
var gammaRad = gamma * (Math.PI / 180);
// Calculate equation components
var cA = Math.cos(alphaRad);
var sA = Math.sin(alphaRad);
var cB = Math.cos(betaRad);
var sB = Math.sin(betaRad);
var cG = Math.cos(gammaRad);
var sG = Math.sin(gammaRad);
// Calculate A, B, C rotation components
var rA = - cA * sG - sA * sB * cG;
var rB = - sA * sG + cA * sB * cG;
var rC = - cB * cG;
// Calculate compass heading
var compassHeading = Math.atan(rA / rB);
// Convert from half unit circle to whole unit circle
if(rB < 0) {
compassHeading += Math.PI;
}else if(rA < 0) {
compassHeading += 2 * Math.PI;
}
// Convert radians to degrees
compassHeading *= 180 / Math.PI;
return compassHeading;
}
document.addEventListener("DOMContentLoaded", function(event) {
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', function(eventData) {
let tiltLR = eventData.gamma;
let tiltFB = eventData.beta;
let dir = eventData.alpha;
deviceOrientationHandler(tiltLR, tiltFB, dir);
}, false);
}
function deviceOrientationHandler(tiltLR, tiltFB, dir) {
document.getElementById("tiltLR").innerHTML = 'tiltLR: ' + Math.ceil(tiltLR);
document.getElementById("tiltFB").innerHTML = 'tiltFB: ' + Math.ceil(tiltFB);
let heading = compassHeading(dir, tiltFB, tiltLR);
if (heading >= 0 && heading < 90) {
document.getElementById("direction").innerHTML = 'direction: S (' + heading + ')';
} else if (heading >= 90 && heading < 180) {
document.getElementById("direction").innerHTML = 'direction: W (' + heading + ')';
} else if (heading >= 180 && heading < 270) {
document.getElementById("direction").innerHTML = 'direction: N (' + heading + ')';
} else if (heading >= 270 && heading <= 360) {
document.getElementById("direction").innerHTML = 'direction: E (' + heading + ')';
} else {
document.getElementById("direction").innerHTML = 'direction: ? (' + heading + ')';
}
}
});