2

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?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
August Jelemson
  • 962
  • 1
  • 10
  • 29

2 Answers2

2

Apart from all the things @AugustJelemson mentioned in his code, if you want to get the actual cardinal direction from the compass direction, you could simply do

const direction = ['north','north east', 'east','south east', 'south','south west', 'west','north west'][Math.floor(((angle+22.5)%360)/45)]

At angle 0 ~ 22.5 and 338.5 ~ 360, direction will be set to north, and at 22.5 ~ 68.5, it will be set to north east, and so on.


also, the browser you test your program will tremendously change your outcome. Using IOS device will most likely break your program (even using webkitCompassHeading is pretty inaccurate).

And I personally feel you can simply use event.alpha or event.webkitCompassHeading for your angle without any problem, although what August did is a much safer method.

Cheers :)

Kenta Nomoto
  • 839
  • 6
  • 11
1
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:

August Jelemson
  • 962
  • 1
  • 10
  • 29