Orientação do sensor

Os dados dos sensores das classes Accelerometer, Gyrometer, Compass, Inclinometer e OrientationSensor são definidos pelos seus eixos de referência. Estes eixos são definidos pelo referencial do dispositivo e rodam com o dispositivo à medida que o utilizador o roda. Se a sua aplicação suportar rotação automática e se reorientar para acomodar o dispositivo à medida que o utilizador o roda, deve ajustar os dados do sensor para a rotação antes de o usar.

Orientação do ecrã vs orientação do dispositivo

Para compreender os eixos de referência dos sensores, é necessário distinguir a orientação do ecrã da orientação do dispositivo. A orientação do ecrã é a direção em que o texto e as imagens são exibidos no ecrã, enquanto a orientação do dispositivo é a posição física do dispositivo.

Note

O eixo z positivo estende-se para fora do ecrã do dispositivo, como mostrado na imagem seguinte. Eixo Z para portátil

Nos diagramas seguintes, tanto a orientação do dispositivo como do ecrã estão em Paisagem (os eixos dos sensores mostrados são específicos para a orientação paisagem).

Este diagrama mostra tanto o ecrã como a orientação do dispositivo em Paisagem.

Ecrã e orientação do dispositivo em Paisagem

Este diagrama seguinte mostra tanto o ecrã como a orientação do dispositivo em LandscapeFlipped.

Ecrã e orientação do dispositivo no LandscapeFlipped

Este diagrama final mostra a orientação do ecrã em Paisagem enquanto a orientação do dispositivo é LandscapeFlipped.

Orientação do ecrã em Paisagem quando a orientação do dispositivo é Paisagem invertida

Pode consultar os valores de orientação através da classe DisplayInformation usando o método GetForCurrentView com a propriedade CurrentOrientation. Depois podes criar lógica comparando com a enumeração DisplayOrientations. Lembra-te que para cada orientação que apoias, tens de suportar uma conversão dos eixos de referência para essa orientação.

Dispositivos com paisagem primeiro vs retrato primeiro

Os fabricantes produzem dispositivos tanto para paisagem como para retratos. O referencial varia entre dispositivos com orientação paisagem (como computadores de secretária e portáteis) e dispositivos orientados para retrato (como telemóveis e alguns tablets). A tabela seguinte mostra os eixos sensores tanto para dispositivos em primeiro plano como para retrato.

Orientação Paisagem em primeiro lugar Retrato em primeiro lugar
Paisagem Dispositivo concebido prioritariamente para o modo horizontal em orientação horizontal Dispositivo concebido para orientação vertical na orientação horizontal
Retrato Dispositivo com orientação horizontal predefinida na orientação vertical Dispositivo prioritariamente vertical em orientação vertical
Paisagem Invertida Dispositivo orientado primeiro para horizontal em orientação horizontal invertida Dispositivo vertical em primeiro lugar na orientação horizontal invertida
Retrato Invertido Dispositivo com orientação principal horizontal em orientação vertical invertida Dispositivo prioritariamente em modo retrato na orientação PortraitFlipped

Dispositivos com ecrã e dispositivos sem ecrã

Alguns dispositivos têm a capacidade de transmitir o ecrã para outro dispositivo. Por exemplo, pode pegar num tablet e transmitir o ecrã para um projetor que estará em orientação horizontal. Neste cenário, é importante ter em mente que a orientação do dispositivo é baseada no dispositivo original, e não no que apresenta o ecrã. Assim, um acelerómetro reportaria dados para o tablet.

Além disso, alguns dispositivos não têm ecrã. Nestes dispositivos, a orientação padrão é retrato.

Orientação do ecrã e rumo da bússola

O rumo da bússola depende dos eixos de referência e, por isso, muda conforme a orientação do dispositivo. Compensa com base nesta tabela (partindo do princípio de que o utilizador está virado para norte).

Orientação do ecrã Eixo de referência para o rumo da bússola Orientação da bússola da API quando está voltada para norte (em orientação horizontal) Rumo da bússola API quando está virado para norte (retrato primeiro) Compensação do rumo da bússola (paisagem em primeiro lugar) Compensação do rumo da bússola (retrato primeiro)
Horizontal -Z 0 270 Título (Direção + 90) % 360
Vertical Y 90 0 (Direção + 270) % 360 Título
Paisagem Invertida Z 180 90 (Rumo + 180) % 360 (Direção + 270) % 360
Retrato Invertido Y 270 180 (Direção + 90) % 360 (Rumo + 180) % 360

Modificar o rumo da bússola conforme mostrado na tabela para mostrar corretamente o rumo. O seguinte excerto de código demonstra como fazer isto.

private void ReadingChanged(object sender, CompassReadingChangedEventArgs e)
{
    double heading = e.Reading.HeadingMagneticNorth;
    double displayOffset;

    // Calculate the compass heading offset based on
    // the current display orientation.
    // In WinUI 3 desktop apps, use interop to get DisplayInformation for the current window.
    var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);
    DisplayInformation displayInfo = DisplayInformation.CreateForWindowId(
        Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd));

    switch (displayInfo.CurrentOrientation)
    {
        case DisplayOrientations.Landscape:
            displayOffset = 0;
            break;
        case DisplayOrientations.Portrait:
            displayOffset = 270;
            break;
        case DisplayOrientations.LandscapeFlipped:
            displayOffset = 180;
            break;
        case DisplayOrientations.PortraitFlipped:
            displayOffset = 90;
            break;
     }

    double displayCompensatedHeading = (heading + displayOffset) % 360;

    // Update the UI...
}

Orientação do ecrã com o acelerómetro e giroscópio

Esta tabela converte dados de acelerómetro e giroscópio para orientação do ecrã.

Eixos de referência X Y Z
Paisagem X Y Z
Retrato Y -X Z
Paisagem Invertida -X -Y Z
Retrato Invertido -Y X Z

O seguinte exemplo de código aplica estas conversões ao girometro.

private void ReadingChanged(object sender, GyrometerReadingChangedEventArgs e)
{
    double x_Axis;
    double y_Axis;
    double z_Axis;

    GyrometerReading reading = e.Reading;  

    // Calculate the gyrometer axes based on
    // the current display orientation.
    // In WinUI 3 desktop apps, use interop to get DisplayInformation for the current window.
    var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);
    DisplayInformation displayInfo = DisplayInformation.CreateForWindowId(
        Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd));
    switch (displayInfo.CurrentOrientation)
    {
        case DisplayOrientations.Landscape:
            x_Axis = reading.AngularVelocityX;
            y_Axis = reading.AngularVelocityY;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.Portrait:
            x_Axis = reading.AngularVelocityY;
            y_Axis = -1 * reading.AngularVelocityX;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.LandscapeFlipped:
            x_Axis = -1 * reading.AngularVelocityX;
            y_Axis = -1 * reading.AngularVelocityY;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.PortraitFlipped:
            x_Axis = -1 * reading.AngularVelocityY;
            y_Axis = reading.AngularVelocityX;
            z_Axis = reading.AngularVelocityZ;
            break;
     }

    // Update the UI...
}

Orientação do ecrã e do dispositivo

Os dados OrientationSensor devem ser alterados de forma diferente. Pense nestas diferentes orientações como rotações no sentido contrário ao eixo z, por isso precisamos de inverter a rotação para recuperar a orientação do utilizador. Para dados de quaterniões, podemos usar a fórmula de Euler para definir uma rotação com um quaternião de referência, e também podemos usar uma matriz de rotação de referência.

Fórmula de Euler

Para obter a orientação relativa que queres, multiplica o objeto de referência pelo objeto absoluto. Note que esta matemática não é comutativa.

Multiplicar o objeto de referência pelo objeto absoluto

Na expressão anterior, o objeto absoluto é devolvido pelos dados do sensor.

Orientação do ecrã Rotação no sentido anti-horário em torno de Z Quaternião de referência (rotação inversa) Matriz de rotação de referência (rotação inversa)
Paisagem 0 1 + 0i + 0j + 0k [1 0 0
0 1 0
0 0 1]
Retrato 90 cos(-45⁰) + (i + j + k)*sin(-45⁰) [0 1 0
-1 0 0
0 0 1]
Paisagem Invertida 180 0 - i - j - k [1 0 0
0 1 0
0 0 1]
Retrato Invertido 270 cos(-135⁰) + (i + j + k)*sin(-135⁰) [0 -1 0
1 0 0
0 0 1]

Ver também

Integração de Sensores de Movimento e Orientação