感應器資料和顯示方向 (HTML)

[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]

取自 AccelerometerGyrometerCompassInclinometer 以及 OrientationSensor 類別的感應器資料是由它們的參考軸線定義的。 這些軸線是由裝置的橫式方向定義,並在使用者轉動裝置時隨著旋轉。 如果您的應用程式支援自動旋轉 – 也就是說,如果它會隨著使用者旋轉時調整自己的方向來適應裝置 – 您就必須在使用前先行針對旋轉調整感應器資料。

顯示方向和裝置方向

為了了解感應器的參考軸線,您必須區分顯示方向與裝置方向。顯示方向就是螢幕上顯示的方向文字與影像,而裝置方向則是裝置的實際位置。下圖的裝置方向與顯示方向都是 Landscape

顯示方向與裝置方向為 Landscape

下圖說明顯示方向與裝置方向都是 LandscapeFlipped

顯示方向與裝置方向為 LandscapeFlipped

下一張圖說明顯示方向為 Landscape,而裝置方向為 LandscapeFlipped。

顯示方向為 Landscape,而裝置方向為 LandscapeFlipped。

使用 GetForCurrentView 方法搭配 CurrentOrientation 屬性,即可透過 DisplayInformation 類別查詢方向值。接著與 DisplayOrientations 列舉比較就能建立邏輯。 記住您支援哪些方向,就必須支援將參考軸線轉換為該方向。

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

現在製造商會同時生產橫向優先裝置與直向優先裝置。製造商會以一致的方式將元件整合到裝置,這樣所有裝置都能以相同的參考架構來運作。 下表顯示橫向優先裝置與直向優先裝置的感應器軸線。

方向 橫向優先 直向優先

Landscape

方向為 Landscape 的橫向優先裝置 方向為 Landscape 的直向優先裝置

Portrait

方向為 Portrait 的橫向優先裝置 方向為 Portrait 的直向優先裝置

LandscapeFlipped

方向為 LandscapeFlipped 的橫向優先裝置 方向為 LandscapeFlipped 的直向優先裝置

PortraitFlipped

方向為 PortraitFlipped 的橫向優先裝置 方向為 PortraitFlipped 的直向優先裝置

 

顯示方向和指南針朝向

指南針朝向取決於參考軸線,所以它會隨著裝置方向變更。 您要根據下表進行調整 (假設使用者面向北方)。

顯示方向 指南針朝向的參考軸線 面向北方的 API 指南針朝向 指南針朝向調整

Landscape

-Z

0

朝向

Portrait

Y

90

(朝向 + 270) % 360

LandscapeFlipped

Z

180

(朝向 + 180) % 360

PortraitFlipped

Y

270

(朝向 + 90) % 360

 

如表中所示修改指南針朝向,以便正確顯示朝向,如這裡所示。

function readingChanged(e) {
    var heading = e.reading.headingMagneticNorth;
    var displayOffset;

    // Calculate the compass heading offset based on
    // the current display orientation.
    var displayInfo = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
    
    switch (displayInfo.currentOrientation) {
        case Windows.Graphics.Display.DisplayOrientations.landscape:
            displayOffset = 0;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portrait:
            displayOffset = 270;
            break;
        case Windows.Graphics.Display.DisplayOrientations.landscapeFlipped:
            displayOffset = 180;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portraitFlipped:
            displayOffset = 90;
            break;
     }

    var displayCompensatedHeading = (heading + displayOffset) % 360;

    // Update the UI...
}

包含加速計和陀螺儀的顯示方向

本表轉換顯示方向的加速計和陀螺儀資料。

參考軸線 X Y Z

Landscape

X

Y

Z

Portrait

Y

-X

Z

LandscapeFlipped

-X

-Y

Z

PortraitFlipped

-Y

X

Z

 

以下是將這些轉換套用到陀螺儀的程式碼範例。

function readingChanged(e) {
    var reading = e.reading;
    var displayOffset;

    // Calculate the gyrometer axes based on
    // the current display orientation.
    var displayInfo = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
    switch (displayInfo.currentOrientation) {
        case Windows.Graphics.Display.DisplayOrientations.landscape: 
            x_Axis = reading.angularVelocityX;
            y_Axis = reading.angularVelocityY;
            z_Axis = reading.angularVelocityZ;
            break;
        case Windows.Graphics.Display.DisplayOrientations.portrait: 
            x_Axis = reading.angularVelocityY;
            y_Axis = -1 * reading.angularVelocityX;
            z_Axis = reading.angularVelocityZ;
            break; 
        case Windows.Graphics.Display.DisplayOrientations.landscapeFlipped: 
            x_Axis = -1 * reading.angularVelocityX;
            y_Axis = -1 * reading.angularVelocityY;
            z_Axis = reading.angularVelocityZ;
            break; 
        case Windows.Graphics.Display.DisplayOrientations.portraitFlipped: 
            x_Axis = -1 * reading.angularVelocityY;
            y_Axis = reading.angularVelocityX;
            z_Axis = reading.angularVelocityZ;
            break;
     }

    // Update the UI...
}

顯示方向和裝置方向

OrientationSensor必須以不同方式變更。 想像不同的方向,如逆時針旋轉到 Z 軸,所以我們需要讓旋轉反轉以回到使用者的方向。對於四元數資料,我們可以使用尤拉公式來定義參考四元數旋轉,也可以使用參考旋轉矩陣。

尤拉公式

若要取得您想要的相對方向,請將參考物件比對絕對物件相乘。請注意,這個數學公式不可以交換。

將參考物件比對絕對物件相乘。

在前面的運算式中,絕對物件是由感應器資料傳回。

顯示方向 延著 Z 軸逆時針旋轉 參考四元數 (反向旋轉) 參考旋轉矩陣 (反向旋轉)

Landscape

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]

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]