The steps you need to determine the compass heading according to the worked example provided in the specification* are as follows:
- Convert returned DeviceOrientation
alpha
, beta
and gamma
values from degrees to radians as alphaRad
, betaRad
, gammaRad
.
- Compute rotationA (
rA
) and rotationB (rB
) components per the worked example in the specification using alphaRad
, betaRad
and gammaRad
(as shown in the example code below).
- Compute
compassHeading = Math.atan(rA / rB)
.
- Convert returned half unit circle headings to whole unit circle headings in the range [0-360) degrees.
- Convert
compassHeading
from radians back to degrees (optional).
Here is the worked example from the specification implemented in JavaScript:
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;
}
window.addEventListener('deviceorientation', function(evt) {
var heading = null;
if(evt.absolute === true && evt.alpha !== null) {
heading = compassHeading(evt.alpha, evt.beta, evt.gamma);
}
// Do something with 'heading'...
}, false);
You can also view a demo of the code provided above.
As of the time of writing (17th Feb 2014) this currently works in:
- Google Chrome for Android
- Opera Mobile for Android
- Firefox Beta for Android
Other browsers do not yet conform to the DeviceOrientation calibration described in the DeviceOrientation Event specification and/or do not provide absolute
DeviceOrientation data values making it impossible to determine compassHeading
with non-complete data.
* Determining the compass heading of the horizontal component of a vector which is orthogonal to the device's screen and pointing out of the back of the screen.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…