问题
I'm making AR Mobile Web App, and my current goal is to show some events on the camera screen. For example, if there is fire in direction north from me, I want to point phone to north, and fire logo should be visible there.
My problem is - how can I get the absolute compass data?
I've tried this JavaScript code:
function compassHeading(alpha, beta, gamma) {
var dataContainerMotion = document.getElementById('dataContainerMotion');
// 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;
}
window.addEventListener('deviceorientation', function(evt) {
heading = compassHeading(alpha, beta, gamma);
dataContainerMotion.innerHTML = heading;
}, false);
But variable absolute shows false, and I can't get absolute value. Compass is calibrated according to the positioning of the phone on initialization of the page - not according to actual position of the North on the Earth.
I would appreciate any kind of help - I'm stuck here and I can't go further without getting the compass data.
回答1:
You have not mentioned the mobile device you have tested with. There are some major "problems" you have to consider:
- Alpha on iOS (iPhone, iPad) devices has the value = 0 from where you start/activate the deviceorientation event. If the phone is currently heading to East then Alpha is 0 at East. If your phone is heading to W then Alpha is 0 at West, etc.
- There is no way to access the implemented hardware compass in Android devices (by Javascript). Some browsers (versions) handle the calculated values alpha, beta and gamma different, so you might have to add/distract a specific angle value. This is also mentioned in the MDN Web Docs
- Chrome (50+) supports the event "ondeviceorientationabsolute" that might your work easier (at least for Chrome)
Solution for iOS devices:
window.addEventListener('deviceorientation', function(event) {
if (event.webkitCompassHeading) {
// You may consider adding/distracting landscape/portrait mode value here
alpha = event.webkitCompassHeading;
if (alpha < 0) { alpha += 360; }
if (alpha > 360) { alpha -= 360; }
}
}
Solution for Android devices:
Use alpha/beta/gamma values (as you did). There are already many good solutions around. The "best" (imho) can be found here represented by the TILT compass: mentioned here or directly on GitHub
Considering your code (I haven't checked in detail) is that it won't working properly on iOS devices and probably not even on all Android devices. So all over use a construct like Frosty Z mention in the link posted above.
Sadly there is no 100% reliable code around covering all types of devices and browsers. I still hope something written here might help.
来源:https://stackoverflow.com/questions/49696561/access-compass-data-in-mobile-web-html5