Orientação do sensor
Os dados do sensor das classes Accelerometer, Gyrometer, Compass, Inclinometer e OrientationSensor são definidos por seus eixos de referência. Esses eixos são definidos pelo quadro de referência do dispositivo e giram com o dispositivo à medida que o usuário o gira. Se o aplicativo der suporte à rotação automática e se reorientar para acomodar o dispositivo à medida que o usuário o gira, você deverá ajustar os dados do sensor para a rotação antes de usá-lo.
APIs importantes
Orientação da tela vs orientação do dispositivo
Para entender os eixos de referência dos sensores, você precisa distinguir a orientação da exibição da orientação do dispositivo. A orientação da tela é a direção em que o texto e as imagens são exibidos na tela, enquanto a orientação do dispositivo é o posicionamento físico do dispositivo.
Observação
O eixo z positivo se estende para fora da tela do dispositivo, conforme mostrado na imagem a seguir.
Nos diagramas a seguir, a orientação do dispositivo e da tela está em Paisagem (os eixos do sensor mostrados são específicos da orientação paisagem).
Este diagrama mostra a orientação da tela e do dispositivo em Paisagem.
Este próximo diagrama mostra a orientação da exibição e do dispositivo em LandscapeFlipped.
Este diagrama final mostra a orientação de exibição em Paisagem enquanto a orientação do dispositivo é LandscapeFlipped.
Você pode consultar os valores de orientação por meio da classe DisplayInformation usando o método GetForCurrentView com a propriedade CurrentOrientation. Em seguida, você pode criar lógica comparando com a enumeração DisplayOrientations. Lembre-se de que, para cada orientação que você suporta, você deve suportar uma conversão dos eixos de referência para essa orientação.
Dispositivos que priorizam a paisagem versus os que priorizam o retrato
Os fabricantes produzem dispositivos que priorizam a paisagem e o retrato. O quadro de referência varia entre dispositivos que priorizam a paisagem (como desktops e laptops) e dispositivos que priorizam o retrato (como telefones e alguns tablets). A tabela a seguir mostra os eixos do sensor para dispositivos que priorizam paisagem e retrato.
Orientação | Paisagem em primeiro lugar | Retrato em primeiro lugar |
---|---|---|
Paisagem | ||
Retrato | ||
Paisagem invertida | ||
Retrato invertido |
Dispositivos que transmitem dispositivos de exibição e sem cabeça
Alguns dispositivos têm a capacidade de transmitir a tela para outro dispositivo. Por exemplo, você pode pegar um tablet e transmitir a tela para um projetor que estará na orientação paisagem. Nesse cenário, é importante ter em mente que a orientação do dispositivo é baseada no dispositivo original, não no que apresenta a tela. Assim, um acelerômetro relataria dados para o tablet.
Além disso, alguns dispositivos não possuem tela. Com esses dispositivos, a orientação padrão para esses dispositivos é retrato.
Orientação da tela e direção da bússola
O rumo da bússola depende dos eixos de referência e, portanto, muda com a orientação do dispositivo. Você compensa com base nesta tabela (suponha que o usuário esteja voltado para o norte).
Orientação de exibição | Eixo de referência para o rumo da bússola | Rumo da bússola API quando voltado para o norte (paisagem primeiro) | Rumo da bússola da API quando voltado para o norte (retrato primeiro) | Compensação de rumo da bússola (paisagem-primeiro) | Compensação do rumo da bússola (retrato primeiro) |
---|---|---|---|---|---|
Paisagem | Z- | 0 | 270 | Direcionamento | (Rubrica + 90) % 360 |
Retrato | Y | 90 | 0 | (Rubrica + 270) % 360 | Direcionamento |
Paisagem invertida | Z | 180 | 90 | (Rubrica + 180) % 360 | (Rubrica + 270) % 360 |
Retrato invertido | Y | 270 | 180 | (Rubrica + 90) % 360 | (Rubrica + 180) % 360 |
Modifique o rumo da bússola conforme mostrado na tabela para exibir corretamente o rumo. O snippet de código a seguir demonstra como fazer isso.
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.
DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
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 visor com o acelerômetro e o giroscópio
Esta tabela converte os dados do acelerômetro e do giroscópio para orientação da tela.
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 exemplo de código a seguir aplica essas conversões ao giroscópio.
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.
DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
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 da tela e orientação do dispositivo
Os dados do OrientationSensor devem ser alterados de uma maneira diferente. Pense nessas diferentes orientações como rotações no sentido anti-horário em relação ao eixo z, portanto, precisamos inverter a rotação para obter a orientação do usuário. Para dados de quatérnio, podemos usar a fórmula de Euler para definir uma rotação com um quatérnion de referência e também podemos usar uma matriz de rotação de referência.
Para obter a orientação relativa desejada, multiplique o objeto de referência pelo objeto absoluto. Observe que essa matemática não é comutativa.
Na expressão anterior, o objeto absoluto é retornado pelos dados do sensor.
Orientação de exibição | Rotação no sentido anti-horário em torno de Z | Quatérnion de referência (rotação reversa) | Matriz de rotação de referência (rotação reversa) |
---|---|---|---|
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] |