Skip to content

Instantly share code, notes, and snippets.

@stephanbogner
Created July 19, 2017 07:39
Show Gist options
  • Save stephanbogner/6d00641372a1c7467e320299add37f93 to your computer and use it in GitHub Desktop.
Save stephanbogner/6d00641372a1c7467e320299add37f93 to your computer and use it in GitHub Desktop.
Snippets writing apps with gyroscope and GPS
function getAngleBetweenVectorAndPlane(vector, plane) {
var angle = Math.asin(Math.abs(plane.x * vector.x + plane.y * vector.y + plane.z * vector.z) / (Math.sqrt(Math.pow(plane.x, 2) + Math.pow(plane.y, 2) + Math.pow(plane.z, 2)) * Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2) + Math.pow(vector.z, 2))));
// http://www.vitutor.com/geometry/distance/line_plane.html
var direction = -vector.z / Math.abs(vector.z); // Because vector angle is always shortest and has no direction
angle = angle * direction * 180 / Math.PI;
return angle;
}
<script src="../js/gyronorm.complete.min.js" type="text/javascript"></script>
<script>
gn.init().then(function() {
gn.start(function(data) {
var calculation = processSensorData(-data.dm.gx, data.dm.gy, data.dm.gz, data.do.alpha, data.do.beta, data.do.gamma);
updateInterface(calculation.rotationX, calculation.rotationZ, calculation.viewDistance);
});
}).catch(function(e) {
// Catch if the DeviceOrientation or DeviceMotion is not supported by the browser or device
});
function processSensorData(accelerationIncludingGravityX, accelerationIncludingGravityY, accelerationIncludingGravityZ, alpha, beta, gamma) {
var plane = {
"x": 0,
"y": 0,
"z": 1
}
var deviceRotationVector = {
"x": accelerationIncludingGravityX,
"y": accelerationIncludingGravityY,
"z": accelerationIncludingGravityZ
}
var viewAngle = getAngleBetweenVectorAndPlane(deviceRotationVector, plane);
var compassHeading = getCompassHeading(alpha, beta, gamma);
var viewDistance = getViewDistance(viewAngle);
var phoneTilt = Math.atan2(deviceRotationVector.y, deviceRotationVector.x) * 180 / Math.PI + 90;
var calculations = {
"rotationY": viewAngle,
"rotationX": compassHeading,
"rotationZ": phoneTilt,
"viewDistance": viewDistance
}
return calculations;
}
</script>
function getCompassHeading(alpha, beta, gamma) {
// https://stackoverflow.com/questions/18112729/calculate-compass-heading-from-deviceorientation-event-api
// 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;
if (compassHeading < -180) {
compassHeading += 360;
}
if (compassHeading > 180) {
compassHeading -= 360;
}
return compassHeading;
}
function getViewDistance(verticalAngleInDegree, altitudeInM) {
verticalAngleInDegree = 90 - verticalAngleInDegree;
var defaultAltitude = 1.8; // Your eyes above ground
altitudeInM = altitudeInM || defaultAltitude; //m
if (verticalAngleInDegree > 90) {
return 999999999999999; // You are looking above to horizon
} else {
// https://www.matheretter.de/formeln/geometrie/dreieckrw/
var distance = Math.tan(verticalAngleInDegree / 180 * Math.PI) * altitudeInM;
return distance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment