感應器方向

來自加速度計陀螺儀Compass傾斜計,以及OrientationSensor類別的感測器資料,皆依其參考軸定義。 這些軸線由裝置的參考座標系定義,隨著使用者旋轉裝置而旋轉。 如果你的應用程式支援自動旋轉,並且會隨著使用者旋轉裝置調整方向,你必須在使用前調整感測器數據以配合旋轉。

顯示方向與裝置方向

為了理解感測器的參考軸,你需要區分顯示方向和裝置方向。 顯示方向是指文字和影像在螢幕上的顯示方向,而裝置方向則是裝置的物理位置。

Note

正 z 軸從裝置螢幕延伸,如下圖所示。 筆電的 Z 軸

在以下圖表中,裝置與顯示方向皆為Landscape(所示感測器軸線為專屬於地形方向)。

此圖示顯示Landscape中的顯示與裝置方向。

橫向模式下的顯示與裝置方向

下圖顯示了 LandscapeFlipped 中的顯示與裝置方向。

LandscapeFlipped 中的顯示與裝置方向

這張最後的圖示顯示了 Landscape 中的顯示方向,而裝置的方向則是 LandscapeFlipped

顯示方向為橫向,而裝置方向則為橫向翻轉

你可以透過 DisplayInformation 類別查詢方向值,方法是使用 GetForCurrentView 方法,並設定 CurrentOrientation 屬性。 接著,您可以藉由與 DisplayOrientations 列舉進行比較來建立邏輯。 記得,每一個你支援的方向,都必須支援參考軸轉換成該方向。

橫向優先與直向優先裝置比較

製造商同時生產橫向優先和直向優先的裝置。 參考系在橫向優先裝置(如桌上型電腦和筆電)與直向優先裝置(如手機和部分平板)之間有所不同。 下表顯示了橫向優先與直向先掃描裝置的感測器軸。

導覽 景觀優先 肖像優先
地貌 景觀優先裝置在景觀導向中 處於橫向方向的直向優先裝置
Portrait 以橫向為主的裝置處於直向模式 以直向為主的裝置處於直向方向時
景觀翻轉 Landscape 優先裝置在 LandscapeFlipped 方向中 以直向為主的裝置處於橫向翻轉方向
肖像翻轉 預設為橫向的裝置處於直向翻轉方向時 直向優先裝置,採用 PortraitFlipped 方向

廣播顯示裝置與無頭裝置

有些裝置能將顯示訊號廣播到其他裝置。 舉例來說,你可以拿一台平板,將顯示效果廣播到橫向投影機上。 在此情況下,請務必留意,裝置方向是以原始裝置為準,而不是以顯示畫面的裝置為準。 所以加速度計會為平板報告數據。

此外,有些裝置沒有顯示螢幕。 對於這些裝置,其預設方向為直向。

顯示方向與羅盤航向

羅盤方位取決於參考軸,因此會隨裝置方向而改變。 你根據這張表格來補償(假設使用者面向北方)。

顯示方向 羅盤方位的參考軸 面向北方時的 API 羅盤方位(橫向先行) 面朝北方時的 API 羅盤方位(先直向) 羅盤航向補償(先行地形) 指南針航向補償(以直向為先)
橫向 -Z 0 270 標題 (航向 + 90) % 360
直向 Y 90 0 (航向 + 270) % 360 標題
景觀翻轉 Z 180 90 (航向 + 180) % 360 (航向 + 270) % 360
肖像翻轉 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.
    // 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...
}

加速度計與陀螺儀的顯示方向

此表將加速度計與陀螺儀資料轉換為顯示方向。

參考軸 X Y Z
地貌 X Y Z
Portrait Y -X Z
景觀翻轉 -X -Y Z
肖像翻轉 -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.
    // 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...
}

顯示方向與裝置方向

OrientationSensor 資料必須以不同方式更改。 把這些不同的方向想像成逆時針旋轉,所以我們需要反轉旋轉才能恢復使用者的方向。 對於四元數資料,我們可以使用歐拉公式定義帶有參考四元數的旋轉,也可以使用參考旋轉矩陣。

歐拉公式

要得到你想要的相對方向,請將參考物件與絕對物件相乘。 請注意,此數學不是交換的。

將參考對象與絕對對象相乘

在前述表達式中,感測器資料會回傳絕對物件。

顯示方向 繞 Z 的逆時針旋轉 參考四元數(反向旋轉) 參考旋轉矩陣(反向旋轉)
地貌 0 1 + 0i + 0j + 0k [1 0 0
0 1 0
0 0 1]
Portrait 90 cos(-45⁰) + (i + j + k)*sin(-45⁰) [0 1 0
-1 0 0
0 0 1]
景觀翻轉 180 0 - I - j - k [1 0 0
0 1 0
0 0 1]
肖像翻轉 270 cos(-135⁰) + (i + j + k)*sin(-135⁰) [0 -1 0
1 0 0
0 0 1]

另請參閱

整合運動與方向感測器