Sensor data and display orientation (HTML)

Sensor data from the Accelerometer, Gyrometer, Compass, Inclinometer, and OrientationSensor classes is defined by their reference axes. These axes are defined by the device's landscape orientation and rotate with the device as the user turns it. If your app supports automatic rotation – that is, if it reorients itself to accommodate the device as the user rotates it – you must adjust your sensor data for the rotation before using it.

Display orientation vs device orientation

In order to understand the reference axes for sensors, you need to distinguish display orientation from device orientation. Display orientation is the direction text and images are displayed on the screen whereas device orientation is the physical positioning of the device. In the following picture, both the device and display orientation are in Landscape.

Display and device orientation in Landscape

The following picture shows both the display and device orientation in LandscapeFlipped.

Display and device orientation in LandscapeFlipped

The next picture shows the display orientation in Landscape while the device orientation is LandscapeFlipped.

Display orientation in Landscape while the device orientation is LandscapeFlipped.

You can query the orientation values through the DisplayInformation class by using the GetForCurrentView method with the CurrentOrientation property. Then you can create logic by comparing against the DisplayOrientations enumeration. Remember that for every orientation you support, you have to support a conversion of the reference axes to that orientation.

Landscape-first vs portrait-first devices

Manufacturers are now producing both landscape-first and portrait-first devices. When manufacturers integrate components into devices, they do so in a unified and consistent way so that all devices operate within the same reference frame. The following table shows the sensor axes for both landscape-first and portrait first devices.

Orientation Landscape-first Portrait-first

Landscape

Landscape-first device in Landscape orientation Portrait-first device in Landscape orientation

Portrait

Landscape-first device in Portrait orientation Portrait-first device in Portrait orientation

LandscapeFlipped

Landscape-first device in LandscapeFlipped orientation Portrait-first device in LandscapeFlipped orientation

PortraitFlipped

Landscape-first device in PortraitFlipped orientation Portrait-first device in PortraitFlipped orientation

 

Display orientation and compass heading

Compass heading depends upon the reference axes and so it changes with the device orientation. You compensate based on this table (assume the user is facing north).

Display orientation Reference axis for compass heading API compass heading when facing north Compass heading compensation

Landscape

-Z

0

Heading

Portrait

Y

90

(Heading + 270) % 360

LandscapeFlipped

Z

180

(Heading + 180) % 360

PortraitFlipped

Y

270

(Heading + 90) % 360

 

Modify the compass heading as shown in the table in order to correctly display the heading, as shown here.

function readingChanged(e) {
    var heading = e.reading.headingMagneticNorth;
    var displayOffset;

    // Calculate the compass heading offset based on
    // the current display orientation.
    var displayInfo = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
    
    switch (displayInfo.currentOrientation) {
        case Windows.Graphics.Display.DisplayOrientations.landscape:
            displayOffset = 0;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portrait:
            displayOffset = 270;
            break;
        case Windows.Graphics.Display.DisplayOrientations.landscapeFlipped:
            displayOffset = 180;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portraitFlipped:
            displayOffset = 90;
            break;
     }

    var displayCompensatedHeading = (heading + displayOffset) % 360;

    // Update the UI...
}

Display orientation with the accelerometer and gyrometer

This table converts accelerometer and gyrometer data for display orientation.

Reference axes X Y Z

Landscape

X

Y

Z

Portrait

Y

-X

Z

LandscapeFlipped

-X

-Y

Z

PortraitFlipped

-Y

X

Z

 

Here's a code example that applies these conversions to the gyrometer.

function readingChanged(e) {
    var reading = e.reading;
    var displayOffset;

    // Calculate the gyrometer axes based on
    // the current display orientation.
    var displayInfo = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
    switch (displayInfo.currentOrientation) {
        case Windows.Graphics.Display.DisplayOrientations.landscape: 
            x_Axis = reading.angularVelocityX;
            y_Axis = reading.angularVelocityY;
            z_Axis = reading.angularVelocityZ;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portrait: 
            x_Axis = reading.angularVelocityY;
            y_Axis = -1 * reading.angularVelocityX;
            z_Axis = reading.angularVelocityZ;
            break; 
        case Windows.Graphics.Display.DisplayOrientations.landscapeFlipped: 
            x_Axis = -1 * reading.angularVelocityX;
            y_Axis = -1 * reading.angularVelocityY;
            z_Axis = reading.angularVelocityZ;
            break; 
        case Windows.Graphics.Display.DisplayOrientations.portraitFlipped: 
            x_Axis = -1 * reading.angularVelocityY;
            y_Axis = reading.angularVelocityX;
            z_Axis = reading.angularVelocityZ;
            break;
     }

    // Update the UI...
}

Display orientation and device orientation

The OrientationSensor must be changed in a different way. Think of the different orientations as rotations counterclockwise to the Z axis, so we need to reverse the rotation to get back the user’s orientation. For quaternion data, we can use Euler’s formula to define a rotation with a reference quaternion, and we can also use a reference rotation matrix.

Euler's formula

To get the relative orientation you want, multiply the reference object against the absolute object. Note that this math is not commutative.

Multiply the reference object against the absolute object

In the preceding expression, the absolute object is returned by the sensor data.

Display orientation Counterclockwise rotation around Z Reference quaternion (reverse rotation) Reference rotation matrix (reverse rotation)

Landscape

0

1 + 0i + 0j + 0k

[1 0 0

0 1 0

0 0 1]

Portrait

90

cos(-45⁰) + (i + j + k)*sin(-45⁰)

[0 1 0

-1 0 0

0 0 1]

LandscapeFlipped

180

0 - i - j - k

[1 0 0

0 1 0

0 0 1]

PortraitFlipped

270

cos(-135⁰) + (i + j + k)*sin(-135⁰)

[0 -1 0

1 0 0

0 0 1]