Created
March 19, 2013 22:35
-
-
Save DanElliottPalmer/5200778 to your computer and use it in GitHub Desktop.
Device orientation with Euler angles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="label">Heading: <strong id="lblHeading">0</strong></div> | |
<div class="label">Attitude: <strong id="lblAttitude">0</strong></div> | |
<div class="label">Bank: <strong id="lblBank">0</strong></div> | |
<script type="text/javascript"> | |
var lblHeading = document.getElementById("lblHeading"), | |
lblAttitude = document.getElementById("lblAttitude"), | |
lblBank = document.getElementById("lblBank"); | |
window.addEventListener("deviceorientation", function(e){ | |
//Defaults | |
var objOrientation = { | |
"HEADING": 0, | |
"ATTITUDE": 0, | |
"BANK": 0 | |
}; | |
/** | |
* Pass the alpha, beta and gamma to our Euler function. | |
* Alpha - z rotation - heading | |
* Beta - x rotation - attitude | |
* Gamma - y rotation - bank | |
*/ | |
objOrientation = eulerAngles(e.alpha, e.beta, e.gamma); | |
lblHeading.innerHTML = Math.round(objOrientation.HEADING); | |
lblAttitude.innerHTML = Math.round(objOrientation.ATTITUDE); | |
lblBank.innerHTML = Math.round(objOrientation.BANK); | |
}, false); | |
function degToRad(deg){ | |
return deg*(Math.PI/180); | |
} | |
function radToDeg(rad){ | |
return rad*(180/Math.PI); | |
} | |
function eulerAngles(heading,attitude,bank){ | |
//Convert everything to radians | |
heading = degToRad(heading); | |
attitude = degToRad(attitude); | |
bank = degToRad(bank); | |
//Cos and sin | |
var ch = Math.cos(heading), | |
sh = Math.sin(heading), | |
ca = Math.cos(attitude), | |
sa = Math.sin(attitude), | |
cb = Math.cos(bank), | |
sb = Math.sin(bank); | |
//Create matrix | |
var matrix = [ | |
[ ch*ca , -ch*sa*cb + sh*sb , ch*sa*sb + sh*cb ], | |
[ sa , ca*cb , -ca*sb ], | |
[ -sh*ca , sh*sa*cb + ch*sb , -sh*sa*sb + ch*cb ] | |
]; | |
//Singularity fix | |
//http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm | |
//North pole | |
if( matrix[1][0]>0.998 ){ | |
heading = Math.atan2( matrix[0][2], matrix[2][2] ); | |
attitude = Math.PI/2; | |
bank = 0; | |
//South pole | |
} else if( matrix[1][0]<-0.998 ){ | |
heading = Math.atan2( matrix[0][2], matrix[2][2] ); | |
attitude = -Math.PI/2; | |
bank = 0; | |
} else { | |
heading = Math.atan2( -matrix[2][0], matrix[0][0] ); | |
attitude = Math.asin( matrix[1][0] ); | |
bank = Math.atan2( -matrix[1][2], matrix[1][1] ); | |
} | |
//Turn radians back to degrees and return | |
return { | |
"HEADING": radToDeg( heading ), | |
"ATTITUDE": radToDeg( attitude ), | |
"BANK": radToDeg( bank ) | |
}; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment