센서 방향

가속도계, 자이로미터, 나침반, 경사계OrientationSensor 클래스의 센서 데이터는 참조 축에 의해 정의됩니다. 이러한 축은 디바이스의 참조 프레임에서 정의되고 사용자가 돌릴 때 디바이스와 함께 회전합니다. 앱이 자동 회전을 지원하며 사용자가 회전할 때 디바이스를 수용할 수 있도록 자체 방향을 다시 지정하는 경우, 센서 데이터를 사용하기 전에 회전에 맞게 조정해야 합니다.

중요 API

디스플레이 방향 vs 디바이스 방향

센서의 참조 축을 이해하려면 디스플레이 방향과 디바이스 방향을 구분해야 합니다. 디스플레이 방향은 텍스트 방향이며 이미지는 화면에 표시되는 반면 디바이스 방향은 디바이스의 물리적 위치입니다.

참고

양수 z축은 다음 이미지와 같이 디바이스 화면에서 확장됩니다. 노트북용 Z축

다음 다이어그램에서는 디바이스 및 디스플레이 방향이 모두 가로입니다. 표시된 센서 축은 가로 방향에만 적용됩니다.

이 다이어그램에서는 디스플레이 및 디바이스 방향이 둘 다 가로입니다.

가로의 디스플레이 및 디바이스 방향

이 다음 다이어그램에서는 디스플레이 및 디바이스 방향이 둘 다 LandscapeFlipped입니다.

LandscapeFlipped의 디스플레이 및 디바이스 방향

이 마지막 다이어그램에서 디스플레이 방향은 가로이고 디바이스 방향은 LandscapeFlipped입니다.

디바이스 방향이 LandscapeFlipped인 동안 가로 방향 표시

CurrentOrientation 속성과 함께 GetForCurrentView 메서드를 사용하여 DisplayInformation 클래스를 통해 방향 값을 쿼리할 수 있습니다. 그런 다음 DisplayOrientations 열거와 비교하며 논리를 만들 수 있습니다. 지원하는 모든 방향에 대해 참조 축을 해당 방향으로 변환하도록 지원해야 합니다.

가로 우선 vs 세로 우선 디바이스

제조업체는 가로 우선 디바이스와 세로 우선 디바이스를 모두 생산합니다. 참조 프레임은 가로 우선 디바이스(예시: 데스크톱 및 노트북)와 세로 우선 디바이스(예시: 휴대폰 및 일부 태블릿)에 따라 다릅니다. 다음의 테이블은 가로 우선 디바이스와 세로 우선 디바이스 모두에 대한 센서 축을 보여 줍니다.

방향 가로 우선 세로 우선
가로 가로 방향의 가로 우선 디바이스 가로 방향의 세로 우선 디바이스
세로 방향 세로 방향의 가로 우선 디바이스 세로 방향의 세로 우선 디바이스
LandscapeFlipped LandscapeFlipped 방향의 가로 우선 디바이스 LandscapeFlipped 방향의 세로 우선 디바이스
PortraitFlipped PortraitFlipped 방향의 가로 우선 디바이스 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]

참고 항목

동작 및 방향 센서 통합하기