传感器方向
加速计、陀螺仪、指南针、测斜仪和 OrientationSensor 类的传感器数据由参考轴定义。 这些轴由设备的参考帧定义,并在用户旋转时随设备旋转。 如果你的应用支持自动旋转并重新定位设备以适应用户旋转设备,则必须在使用它之前调整传感器数据以供旋转。
重要的 API
显示方向与设备方向
若要了解传感器的参考轴,需要区分显示方向与设备方向。 显示方向是方向文本,图像显示在屏幕上,而设备方向是设备的物理定位。
注意
正 z 轴从设备屏幕向外扩展,如下图所示。
在下图中,设备和显示方向都采用 Landscape(所示的传感器轴特定于横向方向)。
此图显示了采用 Landscape 的显示和设备方向。
第二张图显示了采用 LandscapeFlipped 的显示和设备方向。
最后一张图显示了采用 Landscape 的显示方向和采用 LandscapeFlipped 的设备方向。
可以通过使用 GetForCurrentView 方法和 CurrentOrientation 属性通过 DisplayInformation 类查询方向值。 然后,可以通过与 DisplayOrientations 枚举进行比较来创建逻辑。 请记住,对于支持的每个方向,必须支持将引用轴转换为该方向。
横向优先与纵向优先设备
制造商既生产横向优先设备,又生产纵向优先设备。 参考帧因横向优先设备(如台式机和笔记本电脑)和纵向优先设备(如手机和某些平板电脑)而异。 下表显示了横向优先设备和纵向优先设备的传感器轴。
方向 | 横向优先 | 纵向优先 |
---|---|---|
横向 | ||
纵向 | ||
LandscapeFlipped | ||
PortraitFlipped |
设备广播显示器和无外设设备
某些设备能够将显示器广播到另一台设备。 例如,可以拍摄平板电脑并将显示器广播到将采用横向方向的投影仪。 在这种情况下,请务必记住设备方向基于原始设备,而不是显示显示器的设备方向。 因此,加速计将报告平板电脑的数据。
此外,某些设备没有显示器。 使用这些设备时,这些设备的默认方向为纵向。
显示方向和指南针标题
指南针标题取决于参考轴,因此它随设备方向变化。 根据此表进行补偿(假定用户正朝北)。
显示方向 | 指南针标题的参考轴 | 朝北时 API 指南针方向 (横向优先) | 朝北时的 API 指南针方向 (纵向优先) | 指南针标题补偿 (横向优先) | 指南针标题补偿 (纵向优先) |
---|---|---|---|---|---|
横向 | Z- | 0 | 270 | 方位 | (标题 + 90) % 360 |
纵向 | Y | 90 | 0 | (标题 + 270) % 360 | 方位 |
LandscapeFlipped | Z | 180 | 90 | (标题 + 180) % 360 | (标题 + 270) % 360 |
PortraitFlipped | Y | 270 | 180 | (标题 + 90) % 360 | (标题 + 180) % 360 |
根据表中所示修改指南针标题,以便正确显示标题。 以下代码片段演示如何执行此操作。
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...
}
使用加速计和陀螺仪显示方向
此表将加速计和陀螺仪数据转换为显示方向。
参考轴 | X | Y | Z |
---|---|---|---|
横向 | X | Y | Z |
纵向 | Y | -X | Z |
LandscapeFlipped | -X | -y | Z |
PortraitFlipped | -y | X | Z |
下面的代码示例将这些转换应用到陀螺仪。
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...
}
显示方向和设备方向
OrientationSensor 数据必须以不同的方式更改。 请考虑逆时针旋转到 z 轴时的不同方向,因此我们需要反向旋转以重新获取用户的方向。 对于四元数数据,可以使用 Euler 的公式通过引用四元数定义旋转,还可以使用引用旋转矩阵。
若要获取所需的相对方向,请将引用对象与绝对对象相乘。 请注意,此数学不是通勤的。
在前面的表达式中,绝对对象由传感器数据返回。
显示方向 | 反时针旋转绕 Z | 参考四元数(反向旋转) | 引用旋转矩阵 (反向旋转) |
---|---|---|---|
横向 | 0 | 1 + 0i + 0j + 0k | [1 0 0 0 1 0 0 0 1] |
纵向 | 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] |