Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating the cardinal direction of a smartphone with JS

Tags:

javascript

In JavaScript we can get a device alpha, beta and gamma angles.

  • alpha: rotation around the z-axis [0, 360]
  • beta: rotation around the x-axis [90, -90]
  • gamma: rotation around the y-axis [180, -180]


(source: google.com)

window.addEventListener('deviceorientation', (event)=>{

    const alpha = event.alpha; // Returns the rotation of the device around the Z axis
    const beta = event.beta;  // Returns the rotation of the device around the X axis; that is, the number of degrees, ranged between -180 and 180
    const gamma = event.gamma; // Returns the rotation of the device around the Y axis; that is, the number of degrees, ranged between -90 and 90

    console.log(`alpha: ${alpha}, beta: ${beta}, gamma: ${gamma}`);

}, false);

However, I want use these angles to determine the device cardinal direction (North, West, East and South).

My question:
Is it possible to just use the alpha-angle to determine the cardinal direction of the device, or should I also use beta and gamma?
If beta and gamma are needed; in order to calculate the cardinal direction, how should I use them in my calculation, is there any formulas I should know of?

like image 670
August Jelemson Avatar asked Oct 29 '25 17:10

August Jelemson


1 Answers

var heading;

window.addEventListener('deviceorientation', handleOrientation, false);

const handleOrientation = (event) => {
    if(event.webkitCompassHeading) {
        // some devices don't understand "alpha" (especially IOS devices)
        heading = event.webkitCompassHeading;
    }
    else{
        heading = compassHeading(event.alpha, event.beta, event.gamma);
    }
};

const compassHeading = (alpha, beta, gamma) => {

    // Convert degrees to radians
    const alphaRad = alpha * (Math.PI / 180);
    const betaRad = beta * (Math.PI / 180);
    const gammaRad = gamma * (Math.PI / 180);

    // Calculate equation components
    const cA = Math.cos(alphaRad);
    const sA = Math.sin(alphaRad);
    const cB = Math.cos(betaRad);
    const sB = Math.sin(betaRad);
    const cG = Math.cos(gammaRad);
    const sG = Math.sin(gammaRad);

    // Calculate A, B, C rotation components
    const rA = - cA * sG - sA * sB * cG;
    const rB = - sA * sG + cA * sB * cG;
    const rC = - cB * cG;

    // Calculate compass heading
    let 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;
};

This code above was inspired from these links:

  • Calculate compass heading from DeviceOrientation Event API

  • Can I use Javascript to get the compass heading for iOS and Android?

  • https://www.w3.org/2008/geolocation/wiki/images/e/e0/Device_Orientation_%27alpha%27_Calibration-_Implementation_Status_and_Challenges.pdf

  • https://w3c.github.io/deviceorientation/spec-source-orientation.html#worked-example

like image 81
August Jelemson Avatar answered Oct 31 '25 07:10

August Jelemson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!