Данные датчиков и ориентация экрана (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]

Данные датчиков классов Accelerometer, Gyrometer, Compass, Inclinometer и OrientationSensor определяются их опорными осями. Эти оси определяются альбомной ориентацией устройства и поворачиваются вместе с ним. Если ваше приложение поддерживает автоматический поворот — то есть автоматически меняет ориентацию, когда пользователь поворачивает устройство — необходимо скорректировать данные датчиков для поворота до начала его использования.

Ориентация дисплея и ориентация устройства

Чтобы получить представление об опорных осях для датчиков, необходимо понимать разницу между ориентацией дисплея и ориентацией устройства. Ориентация дисплея — это направление, в котором на экране отображаются текст и изображения, а ориентация устройства — это его физическое положение. На следующем изображении ориентация как устройства, так и дисплея — Landscape.

Альбомная ориентация дисплея и устройства

На следующем изображении ориентация как устройства, так и дисплея — LandscapeFlipped.

Альбомная (перевернутая) ориентация дисплея и устройства

На следующем изображении вы видите дисплей в альбомной ориентации, а устройство — в альбомной (перевернутой).

Дисплей в альбомной ориентации, а устройство — в альбомной (перевернутой).

Можно запросить значения ориентации при помощи класса DisplayInformation, используя метод GetForCurrentView со свойством CurrentOrientation. Затем можно создать логику путем сравнения с перечислением DisplayOrientations. Следует помнить, что для каждой поддерживаемой ориентации необходимо предусмотреть преобразование опорных осей.

Устройства с преимущественно альбомной и преимущественно книжной ориентацией

Сейчас изготовители создают устройства и с преимущественно альбомной, и с преимущественно книжной ориентацией. Изготовители интегрируют компоненты в устройства согласованно, чтобы все устройства работали в одинаковой системе отсчета. В следующей таблице представлены оси датчиков для устройств обоих видов.

Ориентация Преимущественно альбомная Преимущественно книжная

Landscape

Устройства с преимущественно альбомной ориентацией в альбомной ориентации Устройства с преимущественно книжной ориентацией в альбомной ориентации

Portrait

Устройства с преимущественно альбомной ориентацией в книжной ориентации Устройства с преимущественно книжной ориентацией в книжной ориентации

LandscapeFlipped

Устройства с преимущественно альбомной ориентацией в альбомной (перевернутой) ориентации Устройства с преимущественно книжной ориентацией в альбомной (перевернутой) ориентации

PortraitFlipped

Устройства с преимущественно альбомной ориентацией в книжной (перевернутой) ориентации Устройства с преимущественно книжной ориентацией в книжной (перевернутой) ориентации

 

Ориентация экрана и направление по компасу

Направление по компасу зависит от опорных осей и, следовательно, меняется вместе с ориентацией устройства. Компенсация отклонения компаса определяется по следующей таблице (предполагается, что пользователь стоит лицом к северу).

Ориентация экрана Опорная ось для направления по компасу Направление по компасу, когда пользователь стоит лицом к северу, согласно API Компенсация отклонения компаса

Landscape

-Z

0

Направление

Portrait

Y

90

(Направление + 270) % 360

LandscapeFlipped

Z

180

(Направление+180) % 360

PortraitFlipped

Y

270

(Направление+90) % 360

 

Измените направление по компасу согласно таблице, чтобы правильно отобразить курс, как показано ниже.

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...
}

Ориентация экрана с использованием акселерометра и гирометра

В следующей таблице приведено преобразование данных акселерометра и гирометра для ориентации экрана.

Опорные оси X Y Z

Landscape

X

Y

Z

Portrait

Y

-X

Z

LandscapeFlipped

-X

-Y

Z

PortraitFlipped

-Y

X

Z

 

Далее приведен пример кода, где эти преобразования применяются к гирометру.

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...
}

Ориентация экрана и ориентация устройства

Данные OrientationSensor необходимо изменять по-другому. Рассматривайте разные ориентации как повороты против часовой стрелки вокруг оси Z, поэтому для того, чтобы вернуть заданную пользователем ориентацию, нужно изменить направление вращения на противоположное. Для данных кватерниона можно использовать формулу Эйлера, чтобы определить поворот с опорным кватернионом. Можно также использовать опорную матрицу вращения.

Формула Эйлера

Чтобы получить желаемую относительную ориентацию, умножьте опорный объект на абсолютный объект. Обратите внимание, что эта формула не обладает свойством коммутативности.

Умножение опорного объекта на абсолютный объект

В предыдущем выражении абсолютный объект возвращается данными датчика.

Ориентация экрана Поворот против часовой стрелки вокруг оси Z Опорный кватернион (поворот в противоположном направлении) Опорная матрица вращения (поворот в противоположном направлении)

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]