Sensororientering

Sensordata från Accelerometer, Gyrometer, Compass, Inclinometer och OrientationSensor definieras av deras referensaxlar. Dessa axlar definieras av enhetens referensram och roteras med enheten när användaren vrider den. Om appen stöder automatisk rotation och omorienterar sig för att hantera enheten när användaren roterar den, måste du justera sensordata för rotationen innan du använder den.

Visningsorientering jämfört med enhetsorientering

För att förstå referensaxlarna för sensorer måste du skilja visningsorientering från enhetens orientering. Visningsorientering är den riktning som text och bilder visas i på skärmen, medan enhetsorientering är enhetens fysiska position.

Note

Den positiva z-axeln sträcker sig ut från enhetsskärmen, vilket visas i följande bild. Z-axel för bärbar dator

I följande diagram finns både enheten och visningsorienteringen i Landscape (de sensoraxlar som visas är specifika för liggande orientering).

Det här diagrammet visar både visnings- och enhetsorientering i Landscape.

Skärm- och enhetsorientering i liggande läge

I nästa diagram visas både visnings- och enhetsorienteringen i LandscapeFlipped.

Visnings- och enhetsorientering i LandscapeFlipped

Det här sista diagrammet visar visningsorienteringen i Liggande medan enhetens orientering är LandscapeFlipped.

Visa i liggande format när enhetens orientering är omvänt liggande format

Du kan köra frågor mot orienteringsvärdena via klassen DisplayInformation med hjälp av metoden GetForCurrentView med egenskapen CurrentOrientation. Sedan kan du skapa logik genom att jämföra med uppräkningen DisplayOrientations. Kom ihåg att för varje orientering som du stöder måste du stödja en konvertering av referensaxlarna till den orienteringen.

Enheter i första hand för liggande läge kontra enheter i första hand för stående läge

Tillverkare tillverkar både enheter som i första hand används i liggande läge och enheter som i första hand används i stående läge. Referensramen skiljer sig mellan enheter som i första hand används i liggande format (till exempel stationära datorer och bärbara datorer) och enheter som i första hand används i stående format (till exempel telefoner och vissa surfplattor). Följande tabell visar sensoraxlarna för både enheter av typen liggande först och enheter av typen stående först.

Orientering Liggande läge först Porträtt först
Landskap Liggande enhet i liggande orientering Stående enhet i liggande orientering
Porträtt Liggande enhet i stående orientering Enhet med stående läge som standard i stående orientering
LandscapeFlipped Liggande enhet i liggande orientering Enhet med porträttläge som standard i omvänt liggande läge
PortraitFlipped Enhet med liggande grundorientering i omvänd stående orientering Enhet med stående orientering som standard i omvänd stående orientering

Enheter som sänder visning och huvudlösa enheter

Vissa enheter har möjlighet att sända visningen till en annan enhet. Du kan till exempel ta en surfplatta och sända visningen till en projektor som kommer att vara i liggande orientering. I det här scenariot är det viktigt att komma ihåg att enhetens orientering baseras på den ursprungliga enheten, inte den som visar skärmen. Så en accelerometer skulle rapportera data för surfplattan.

Dessutom har vissa enheter ingen skärm. Med dessa enheter är standardorienteringen för dessa enheter stående.

Visa orientering och kompassrubrik

Kompassrubriken beror på referensaxlarna och ändras därför med enhetens orientering. Du kompenserar baserat på den här tabellen (anta att användaren är mot norr).

Visningsorientering Referensaxel för kompassrubrik API-kompassriktning vid riktning mot norr (liggande läge först) API-kompassriktning vid riktning mot norr (stående läge först) Kompassriktningskompensering (liggande läge först) Kompassriktningskompensation (stående läge först)
Liggande -Z 0 270 Rubrik (Riktning + 90) % 360
Stående J 90 0 (Rubrik + 270) % 360 Rubrik
LandscapeFlipped Z 180 90 (Riktning + 180) % 360 (Rubrik + 270) % 360
PortraitFlipped J 270 180 (Riktning + 90) % 360 (Riktning + 180) % 360

Ändra kompassrubriken enligt tabellen så att rubriken visas korrekt. Följande kodfragment visar hur du gör detta.

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

Visa orientering med accelerometern och gyrometern

Den här tabellen konverterar accelerometer- och gyrometerdata för visningsorientering.

Referensaxlar X J Z
Landskap X J Z
Porträtt J -X Z
LandscapeFlipped -X -Y Z
PortraitFlipped -Y X Z

Följande kodexempel tillämpar dessa konverteringar på gyrometern.

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

Visa orientering och enhetsorientering

Data OrientationSensor måste ändras på ett annat sätt. Tänk på dessa olika orienteringar som rotationer motsols till z-axeln, så vi måste vända rotationen för att få tillbaka användarens orientering. För quaternion-data kan vi använda Eulers formel för att definiera en rotation med en referenskvaternion, och vi kan också använda en referensrotationsmatris.

Eulers formel

För att få den relativa orientering du vill ha multiplicerar du referensobjektet mot det absoluta objektet. Observera att den här matematiken inte är kommutativ.

Multiplicera referensobjektet mot det absoluta objektet

I föregående uttryck returneras det absoluta objektet av sensordata.

Visningsorientering Motsols rotation runt Z Referenskvaternion (omvänd rotation) Referensrotationsmatris (omvänd rotation)
Landskap 0 1 + 0i + 0j + 0k [1 0 0
0 1 0
0 0 1]
Porträtt 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]

Se även

Integrera rörelse- och orienteringssensorer