De oriëntatiesensoren gebruiken

Lees hoe je de oriëntatiesensoren gebruikt om de oriëntatie van het apparaat te bepalen.

In dit voorbeeld wordt een eenvoudige app gemaakt die afhankelijk is van een oriëntatiesensor als invoerapparaat. Een oriëntatiesensor is een van de verschillende typen omgevingssensoren waarmee apps kunnen reageren op wijzigingen in de apparaatstand.

Note

Dit artikel is gericht op code die laat zien hoe u een oriëntatiesensor gebruikt. Zie Sensoren: Oriëntatiesensor voor een overzicht van de oriëntatiesensoren.

Prerequisites

U moet bekend zijn met de oriëntatiesensor en het gebruik ervan. Zie Sensoren: Oriëntatiesensor.

Het apparaat dat u gebruikt, moet een oriëntatiesensor ondersteunen.

Richtingssensortypen

Er zijn twee verschillende typen sensor-API's voor oriëntatie opgenomen in de Windows. Devices.Sensors naamruimte: OrientationSensor en SimpleOrientation. Hoewel beide sensoren oriëntatiesensoren zijn, is die term overbelast en worden ze gebruikt voor zeer verschillende doeleinden. Omdat beide oriëntatiesensoren echter zijn, worden ze beide behandeld in dit artikel.

De OrientationSensor-API wordt gebruikt in 3D-apps om een quaternion en een rotatiematrix te verkrijgen. Een quaternion kan het best worden begrepen als een rotatie van een punt [x,y,z] om een willekeurige as (in tegenstelling tot een rotatiematrix, die rotaties om drie assen beschrijft). De wiskunde achter quaternionen is vrij exotisch, omdat die de geometrische eigenschappen van complexe getallen en de wiskundige eigenschappen van imaginaire getallen omvat, maar ermee werken is eenvoudig en frameworks zoals DirectX bieden er ondersteuning voor. Een complexe 3D-app kan de oriëntatiesensor gebruiken om het perspectief van de gebruiker aan te passen. Deze sensor combineert invoer van de accelerometer, gyrometer en kompas.

De SimpleOrientationSensor-API wordt gebruikt om de huidige fysieke afdrukstand van het apparaat te bepalen in termen van definities zoals staand omhoog, staand omlaag, liggend links en Liggend rechts. Het kan ook vaststellen of een apparaat met de voorkant naar boven of naar beneden ligt. In plaats van eigenschappen zoals 'portret omhoog' of 'landschap links' te retourneren, retourneert deze sensor een rotatiewaarde: 'Niet gedraaid', '90 graden linksom gedraaid', enzovoort. De volgende tabel koppelt veelvoorkomende oriëntatie-eigenschappen aan de bijbehorende sensorwaarde.

Oriëntatie Overeenkomende sensorlezing
Portret omhoog Niet geroteerd
Liggende stand naar links Gedraaid90GradenTegenDeKlokIn
Portret naar beneden Gedraaid180GradenTegenDeKlokIn
Liggend naar rechts Gedraaid270GradenTegenDeKlokIn

Voorbeeldcode - oriëntatiesensor

using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Windows.Devices.Sensors;

namespace DevicesDemo.Pages
{
    public sealed partial class OrientationSensorPage : Page
    {
        private OrientationSensor? orientationSensor;

        public OrientationSensorPage()
        {
            InitializeComponent();

            // Get the default orientation sensor object.
            orientationSensor = OrientationSensor.GetDefault();

            if (orientationSensor != null)
            {
                // Establish the report interval.
                uint minReportInterval = orientationSensor.MinimumReportInterval;
                uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
                orientationSensor.ReportInterval = reportInterval;

                // Assign an event handler for the reading-changed event.
                orientationSensor.ReadingChanged += OrientationSensor_ReadingChanged;
            }
            else
            {
                statusBar.Message = "No orientation sensor was found.";
                statusBar.Severity = InfoBarSeverity.Error;
                statusBar.IsOpen = true;
            }
        }

        // This event handler writes the current orientation
        // reading to the text blocks on the XAML page.
        private void OrientationSensor_ReadingChanged(OrientationSensor sender, OrientationSensorReadingChangedEventArgs args)
        {
            DispatcherQueue?.TryEnqueue(DispatcherQueuePriority.Normal, () =>
            {
                OrientationSensorReading reading = args.Reading;
                // Quaternion values
                txtQuaternionX.Text = String.Format("{0,8:0.00000}", reading.Quaternion.X);
                txtQuaternionY.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Y);
                txtQuaternionZ.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Z);
                txtQuaternionW.Text = String.Format("{0,8:0.00000}", reading.Quaternion.W);

                // Rotation Matrix values
                txtM11.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M11);
                txtM12.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M12);
                txtM13.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M13);
                txtM21.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M21);
                txtM22.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M22);
                txtM23.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M23);
                txtM31.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M31);
                txtM32.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M32);
                txtM33.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M33);
            });
        }
    }
}
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid Margin="24">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>
        <TextBlock Text="M11:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM11" Grid.Column="1" Text="---"/>
        <TextBlock Text="M12:" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM12" Grid.Column="1" Grid.Row="1" Text="---"/>
        <TextBlock Text="M13:" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM13" Grid.Column="1" Grid.Row="2" Text="---"/>

        <TextBlock Text="M21:" Grid.Column="2" Grid.Row="0" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM21" Grid.Column="3" Grid.Row="0" Text="---"/>
        <TextBlock Text="M22:" Grid.Column="2" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM22" Grid.Column="3" Grid.Row="1" Text="---"/>
        <TextBlock Text="M23:" Grid.Column="2" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM23" Grid.Column="3" Grid.Row="2" Text="---"/>

        <TextBlock Text="M31:" Grid.Column="4" Grid.Row="0" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM31" Grid.Column="5" Grid.Row="0" Text="---"/>
        <TextBlock Text="M32:" Grid.Column="4" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM32" Grid.Column="5" Grid.Row="1" Text="---"/>
        <TextBlock Text="M33:" Grid.Column="4" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM33" Grid.Column="5" Grid.Row="2" Text="---"/>

    </Grid>
    <Grid Margin="24" Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>

        <TextBlock Text="Quaternion X:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionX" Grid.Column="1" Grid.Row="0" Text="---"/>
        <TextBlock Text="Quaternion Y:" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionY" Grid.Column="1" Grid.Row="1" Text="---"/>
        <TextBlock Text="Quaternion Z:" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionZ" Grid.Column="1" Grid.Row="2" Text="---"/>
        <TextBlock Text="Quaternion W:" Grid.Row="3" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionW" Grid.Column="1" Grid.Row="3" Text="---"/>
    </Grid>

    <InfoBar x:Name="statusBar" Grid.Row="2"/>
</Grid>

Wanneer de app actief is, kunt u de oriëntatiewaarden wijzigen door het apparaat te bewegen.

In het vorige voorbeeld ziet u de essentiële code die u moet schrijven om oriëntatiesensorinvoer in uw app te integreren.

Verbinding maken met de sensor

Roep de GetDefault-methode aan om een verbinding tot stand te brengen met de standaardstandsensor.

private OrientationSensor? orientationSensor;
// ...
orientationSensor = OrientationSensor.GetDefault();

U kunt ook FromIdAsync aanroepen om een object OrientationSensor te maken op basis van een DeviceInformation.Id-waarde. Zie Apparaten inventariseren voor meer informatie.

Als er geen sensor voor oriëntatiesensor wordt gedetecteerd, wordt het statusbericht bijgewerkt om de gebruiker hiervan op de hoogte te stellen.

Het rapportinterval instellen

Het rapportinterval wordt ingesteld in de constructor van de pagina. Met deze code wordt het minimale interval opgehaald dat door het apparaat wordt ondersteund en vergeleken met een aangevraagd interval van 16 milliseconden (wat een vernieuwingsfrequentie van 60 Hz bij benadering is). Als het minimaal ondersteunde interval groter is dan het aangevraagde interval, stelt de code de waarde in op het minimum. Anders wordt de waarde ingesteld op het aangevraagde interval.

uint minReportInterval = orientationSensor.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
orientationSensor.ReportInterval = reportInterval;

Sensorgegevens lezen

De nieuwe oriëntatiesensorgegevens worden vastgelegd in de gebeurtenis-handler ReadingChanged. Telkens wanneer het sensorstuurprogramma nieuwe gegevens van de sensor ontvangt, worden de waarden aan uw app doorgegeven met behulp van deze gebeurtenis. In dit voorbeeld worden deze nieuwe waarden naar de tekstblokken geschreven die in de XAML voor de bijbehorende pagina zijn gevonden.

orientationSensor.ReadingChanged += OrientationSensor_ReadingChanged;
// ...

private void OrientationSensor_ReadingChanged(OrientationSensor sender, OrientationSensorReadingChangedEventArgs args)
{
    DispatcherQueue?.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        OrientationSensorReading reading = args.Reading;
        // Quaternion values
        txtQuaternionX.Text = String.Format("{0,8:0.00000}", reading.Quaternion.X);
        txtQuaternionY.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Y);
        txtQuaternionZ.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Z);
        txtQuaternionW.Text = String.Format("{0,8:0.00000}", reading.Quaternion.W);

        // Rotation Matrix values
        txtM11.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M11);
        txtM12.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M12);
        txtM13.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M13);
        txtM21.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M21);
        txtM22.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M22);
        txtM23.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M23);
        txtM31.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M31);
        txtM32.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M32);
        txtM33.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M33);
    });
}

Voorbeeldcode - eenvoudige oriëntatiesensor

using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Windows.Devices.Sensors;

namespace DevicesDemo.Pages
{
    public sealed partial class SimpleOrientationPage : Page
    {
        private SimpleOrientationSensor? simpleOrientationSensor;

        public SimpleOrientationPage()
        {
            InitializeComponent();

            // Get the default simple orientation sensor object.
            simpleOrientationSensor = SimpleOrientationSensor.GetDefault();

            // Assign an event handler.
            if (simpleOrientationSensor != null)
            {
                // Assign an event handler for the reading-changed event.
                simpleOrientationSensor.OrientationChanged 
                    += SimpleOrientationSensor_OrientationChanged;
            }
            else
            {
                statusBar.Message = "No simple orientation sensor was found.";
                statusBar.Severity = InfoBarSeverity.Error;
                statusBar.IsOpen = true;
            }
        }

        // This event handler writes the current simple orientation
        // reading to the text block on the XAML page.
        private void SimpleOrientationSensor_OrientationChanged(SimpleOrientationSensor sender, 
            SimpleOrientationSensorOrientationChangedEventArgs args)
        {
            DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
            {
                switch (args.Orientation)
                {
                    case SimpleOrientation.NotRotated:
                        txtOrientation.Text = "Not Rotated";
                        break;
                    case SimpleOrientation.Rotated90DegreesCounterclockwise:
                        txtOrientation.Text = "Rotated 90 Degrees Counterclockwise";
                        break;
                    case SimpleOrientation.Rotated180DegreesCounterclockwise:
                        txtOrientation.Text = "Rotated 180 Degrees Counterclockwise";
                        break;
                    case SimpleOrientation.Rotated270DegreesCounterclockwise:
                        txtOrientation.Text = "Rotated 270 Degrees Counterclockwise";
                        break;
                    case SimpleOrientation.Faceup:
                        txtOrientation.Text = "Faceup";
                        break;
                    case SimpleOrientation.Facedown:
                        txtOrientation.Text = "Facedown";
                        break;
                    default:
                        txtOrientation.Text = "Unknown orientation";
                        break;
                }
            });
        }
    }
}
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid Margin="24">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Orientation:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtOrientation" Grid.Column="1" Text="---"/>
    </Grid>

    <InfoBar x:Name="statusBar" Grid.Row="1"/>
</Grid>

Wanneer de app actief is, kunt u de oriëntatiewaarden wijzigen door het apparaat te bewegen.

In het vorige voorbeeld ziet u de essentiële code die u moet schrijven om sensorinvoer voor eenvoudige oriëntatie in uw app te integreren.

Verbinding maken met de eenvoudige oriëntatiesensor

Roep de GetDefault-methode aan om een verbinding tot stand te brengen met de standaardstandsensor.

private SimpleOrientationSensor? simpleOrientationSensor;
// ...
simpleOrientationSensor = SimpleOrientationSensor.GetDefault();

U kunt ook FromIdAsync aanroepen om een SimpleOrientationSensor-object te maken op basis van een DeviceInformation.Id-waarde. Zie Apparaten inventariseren voor meer informatie.

Als er geen eenvoudige sensor voor oriëntatiesensor wordt gedetecteerd, wordt het statusbericht bijgewerkt om de gebruiker te informeren.

De eenvoudige gegevens van de oriëntatiesensor lezen

De nieuwe eenvoudige oriëntatiesensorgegevens worden vastgelegd in de gebeurtenis-handler OrientationChanged . Telkens wanneer het sensorstuurprogramma nieuwe gegevens van de sensor ontvangt, worden de waarden aan uw app doorgegeven met behulp van deze gebeurtenis. In dit voorbeeld worden deze nieuwe waarden naar het tekstblok geschreven dat in de XAML voor de bijbehorende pagina is gevonden.

simpleOrientationSensor.OrientationChanged 
    += SimpleOrientationSensor_OrientationChanged;
// ...

private void SimpleOrientationSensor_OrientationChanged(SimpleOrientationSensor sender,
    SimpleOrientationSensorOrientationChangedEventArgs args)
{
    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        switch (args.Orientation)
        {
            case SimpleOrientation.NotRotated:
                txtOrientation.Text = "Not Rotated";
                break;
            case SimpleOrientation.Rotated90DegreesCounterclockwise:
                txtOrientation.Text = "Rotated 90 Degrees Counterclockwise";
                break;
            case SimpleOrientation.Rotated180DegreesCounterclockwise:
                txtOrientation.Text = "Rotated 180 Degrees Counterclockwise";
                break;
            case SimpleOrientation.Rotated270DegreesCounterclockwise:
                txtOrientation.Text = "Rotated 270 Degrees Counterclockwise";
                break;
            case SimpleOrientation.Faceup:
                txtOrientation.Text = "Faceup";
                break;
            case SimpleOrientation.Facedown:
                txtOrientation.Text = "Facedown";
                break;
            default:
                txtOrientation.Text = "Unknown orientation";
                break;
        }
    });
}

Als alternatief voor de OrientationChanged gebeurtenis kunt u de huidige oriëntatie eenmalig opvragen door de methode GetCurrentOrientation aan te roepen.