Skip to content

Instantly share code, notes, and snippets.

@DanElliottPalmer
Created March 19, 2013 22:35
Show Gist options
  • Save DanElliottPalmer/5200778 to your computer and use it in GitHub Desktop.
Save DanElliottPalmer/5200778 to your computer and use it in GitHub Desktop.
Device orientation with Euler angles
<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