javascript - calculate compass heading angle from alpha, beta and gamma angles of mobile device orientation (ondeviceorientation event as source)

JavaScript
[Edit]
+
0
-
0

JavaScript - calculate compass heading angle from alpha, beta and gamma angles of mobile device orientation (ondeviceorientation event as source)

9600
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
const RADIAN = Math.PI / 180; const DEGREE = 180 / Math.PI; // Calculates compass heading angle from alpha, beta and gamma angles of mobile device orientation. // // Note: // The Earth coordinate frame, described by the values x, y, and z, is aligned based on gravity and standard magnetic orientation. // // Coordinate system // X-axis represents the east-west direction (where east is positive) // Y-axis represents the north-south direction (where north is positive) // Z-axis represents the up-down direction, perpendicular to the ground (where up is positive) // // Arguments: // alpha the rotation in degrees around the Z-axis // beta the rotation in degrees around the X-axis // gamma the rotation in degrees around the Y-axis // // up // ^ [N] // Z-axis | ^ Y-axis // | / // --|-/---- // / |/ / // / *---/------> [E] // / / X-axis // / o / // --------- // phone screen surface in the position // alpha=0, beta=0, gamma=0 // // Result: compass heading angle in degrees in the range <0, 360). // // [N] // 0 // 315 ^ 45 // . | . // [W] 270 <-- + --> 90 [E] // . | . // 225 v 135 // 180 // [S] // const calculateCompassHeadingAngle = (alpha, beta, gamma) => { const rX = beta * RADIAN || 0; const rY = gamma * RADIAN || 0; const rZ = alpha * RADIAN || 0; const sX = Math.sin(rX); const sY = Math.sin(rY); const sZ = Math.sin(rZ); const cX = Math.cos(rX); const cY = Math.cos(rY); const cZ = Math.cos(rZ); const vX = -cZ * sY - sZ * sX * cY; const vY = -sZ * sY + cZ * sX * cY; const angle = Math.atan(vX / vY); if (vY < 0) { return angle * DEGREE + 180; } if (vX < 0) { return angle * DEGREE + 360; } return angle * DEGREE; }; // Usage example: // Hint: consider to use 'deviceorientationabsolute' event. window.addEventListener('deviceorientation', (event) => { // // ⚠️ Warnings ⚠️: // - on some devices it may be necessary to use `event.webkitCompassHeading` property instead of `calculateCompassHeadingAngle()` method, // - it is good to check `event.absolute` property to know if compass heading angle indicates absolutely orientation (that is, in reference to the Earth's coordinate) or it is determined by the device. // const angle = calculateCompassHeadingAngle(event.alpha, event.beta, event.gamma); console.log(`compass heading angle: ${angle}`); }); // References: // // 1. https://web.dev/articles/device-orientation // 2. https://w3c.github.io/deviceorientation/spec-source-orientation.html#worked-example