Share via


附錄:矩陣轉換

本主題提供 2D 圖形矩陣轉換的數學概觀。 不過,您不需要知道矩陣數學,才能在 Direct2D 中使用轉換。 如果您對數學感興趣,請閱讀本主題;否則,請放心略過本主題。

矩陣簡介

矩陣是實數的矩形陣列。 矩陣 的順序 是資料列和資料行的數目。 例如,如果矩陣有 3 個數據列和 2 個數據行,則順序為 3 × 2。 矩陣通常會以方括弧括住的矩陣元素來顯示:

3 x 2 矩陣。

標記法:矩陣是由大寫字母所指定。 元素會以小寫字母指定。 下標表示元素的資料列和資料行編號。 例如,ij 是位於矩陣 A 之 i'th 列和 j'th 資料行的專案。

下圖顯示 i × j 矩陣,其中包含矩陣中每個儲存格中的個別元素。

具有 i 資料列和 j 資料行的矩陣。

矩陣作業

本節說明在矩陣上定義的基本作業。

加法。 兩個矩陣的總和 A + B 是藉由新增 A 和 B 的對應元素來取得:

A + B = \[ a*ij* \] + \[ b*ij* \] = \[ a*ij* + b*ij* \]

純量乘法。 此作業會將矩陣乘以實數。 假設有實數 k,則純量產品 kA 會藉由將 A 的每個元素乘以 k來取得。

kA = k\[ a*ij* \] = \[ k × a*ij* \]

矩陣乘法。 假設有兩個矩陣 A 和 B 具有 order (m × n) 和 (n × p) ,則產品 C = A × B 是具有訂單 (m × p) 的矩陣,定義如下:

顯示矩陣乘法的公式。

或,同樣地:

c*ij* = a*i*1 x b1*j* + a*i*2 x b2*j* + ... + a*in* + b*nj*

也就是說,若要計算每個元素 cij,請執行下列動作:

  1. 採用 A 的第 i 列和 B 的第 j 個數據行。
  2. 將列和資料行中的每個元素配對相乘:第一個資料列專案乘以第一個資料行專案、第二個數據列專案乘以第二個數據行專案等等。
  3. 加總結果。

以下是將 (2 × 2) 矩陣乘以 (2 × 3) 矩陣的範例。

矩陣乘法。

矩陣乘法不是交換的。 也就是說,A × B ≠ B × A。此外,從定義中,其後面不會乘以每一組矩陣。 左側矩陣中的資料行數目必須等於右側矩陣中的資料列數目。 否則,不會定義×運算子。

識別矩陣。 指定 I 的識別矩陣是定義如下的平方矩陣:

I*ij* = 1 如果 *i* = *j*,則為 0,否則為 0。

換句話說,識別矩陣會針對每個元素包含 1 個,其中資料列編號等於資料行編號,而所有其他元素則為零。 例如,以下是 3 個× 3 個識別矩陣。

識別矩陣。

任何矩陣 M 的下列相等保留。

M x I = M I x M = M

Affine Transforms

相依轉換是一種數學運算,可將一個座標空間對應到另一個座標空間。 換句話說,它會將一組點對應到另一組點。 Affine 轉換有一些功能,讓它們在電腦圖形中很有用。

  • Affine 轉換會保留 共構性。 如果三個或多個點落在一行上,它們仍會在轉換之後形成一行。 直線維持直線。
  • 兩個相依轉換的組成是一個相依轉換。

2D 空間的 Affine 轉換具有下列形式。

顯示 2D 空間的相依轉換。

如果您套用稍早指定的矩陣乘法定義,您可以顯示兩個相依轉換的乘積是另一個相依轉換。 若要使用相依轉換來轉換 2D 點,此點會以 1 × 3 矩陣表示。

P = \|x y 1 \|

前兩個專案包含點的 x 和 y 座標。 1 會放在第三個元素中,讓數學正常運作。 若要套用轉換,請將兩個矩陣相乘,如下所示。

P' = P × M

這會展開至下列內容。

相依轉換。

where

x' = ax + cy + e y' = bx + dy + f

若要取得轉換點,請取得矩陣 P 的前兩個元素。

p = (x', y') = (ax + cy + e, bx + dy + f)

注意

1 × n 矩陣稱為 資料列向量。 Direct2D 和 Direct3D 都會使用資料列向量來代表 2D 或 3D 空間中的點。 您可以使用資料行向量 (n × 1) 並轉置轉換矩陣來取得相等的結果。 大部分的圖形文字都會使用資料行向量形式。 本主題提供資料列向量表單,以便與 Direct2D 和 Direct3D 一致性。

 

接下來的數個區段會衍生基本轉換。

翻譯轉換

轉譯轉換矩陣的格式如下。

翻譯轉換。

將點 P 插入此方程式會產生:

P' = (*x* + *dx*, *y* + *dy*)

對應至 x、y) X 軸中由 dx 轉譯的 (點,而 Y 軸則 為 dy

顯示兩點翻譯的圖表。

調整轉換

縮放轉換矩陣的格式如下。

調整轉換。

將點 P 插入此方程式會產生:

P' = (*x* ** * *dx*, *y* * )

對應至 x,y) 以 dxdy縮放的 (點。

顯示兩點縮放比例的圖表。

繞原點旋轉

在原點周圍旋轉的矩陣具有下列形式。

顯示旋轉轉換的公式。

轉換的點為:

P' = (*x*cosΘ – ysinΘ、*x*sinΘ + *y*cosΘ)

證明。 若要顯示 P 代表旋轉,請考慮下圖。

顯示繞原點旋轉的圖表。

假設︰

P = (x,y)

要轉換的原始點。

Φ

線條所形成的角度 (0,0) 至 P。

Θ

旋轉 (x,y) 原點的角度。

P' = (x',y')

已轉換的點。

R

行 (0,0) 到 P 的長度。此外,旋轉圓圈的半徑。

注意

此圖表使用幾何中使用的標準座標系統,其中正 y 軸向上指向。 Direct2D 使用 Windows 座標系統,其中正 Y 軸向下點。

 

X 軸與線條 (0,0) 到 P' 之間的角度為 Ф + Θ。 下列身分識別保留:

x = R cosФ y = R sinФ x' = R cos (Ф + Θ) y' = R sin (Ф+ Θ)

現在在 Θ 方面解決 x' 和 y'。 透過三角加法公式:

x' = R (cosФcosΘ – sinФsinΘ) = RcosФcosΘ – RsinФsinΘ y' = R (sinФcosΘ + cosInΘ) = RsinФcosΘ + RcosФsinΘ

替代,我們得到:

x' = xcosΘ – ysinΘ y' = xsinΘ + ycosΘ

對應至稍早顯示的轉換點 P。

繞任意點旋轉

若要繞著點 (x,y) ,而不是原點旋轉,則會使用下列矩陣。

旋轉轉換。

您可以擷取 (x,y) 成為原點來衍生此矩陣。

顯示繞點旋轉的圖表。

讓 (x1、y1) 成為旋轉點 (x0、y0) 繞 (x,y) 點所產生的點。 我們可以衍生 x1,如下所示。

x1 = (x0 – x) cosΘ – (y0 – y) sinΘ + x1 = x0cosΘ – y0sinΘ + \[ (1 – cosΘ) + ysinΘ \]

現在,使用公式 x1 = ax0 + cy0 + e,將這個方程式插入轉換矩陣中。 使用相同的程式衍生 y1。

扭曲轉換

扭曲轉換是由四個參數所定義:

  • Θ:沿著 X 軸扭曲的數量,以 Y 軸的角度測量。
  • Ф:沿著 Y 軸扭曲的數量,以 X 軸的角度測量。
  • (pxpy) :執行扭曲之點的 x 和 y 座標。

扭曲轉換會使用下列矩陣。

扭曲轉換。

轉換的點為:

P' = (*x* + *y*tanΘ – *py*tanΘ, *y* + *x*tanФ) – *py*tanФ

或對等:

P' = (*x* + (*y* – *py*) tanΘ、*y* + (*x* – *px*) tanФ)

若要查看此轉換的運作方式,請個別考慮每個元件。 Θ 參數會以等於 tanΘ 的數量移動 x 方向的每個點。 下圖顯示 Θ 與 X 軸扭曲之間的關聯性。

顯示沿著 X 軸扭曲的圖表。

以下是套用至矩形的相同扭曲:

顯示套用至矩形時沿著 X 軸扭曲的圖表。

Ф 參數的效果相同,但沿著 Y 軸:

顯示沿著 Y 軸扭曲的圖表。

下圖顯示套用至矩形的 Y 軸扭曲。

顯示套用至矩形時沿著 Y 軸扭曲的圖表。

最後,參數 pxpy 會沿著 X 軸和 y 軸移動扭曲的中心點。

代表 Direct2D 中的轉換

所有 Direct2D 轉換都是相依轉換。 Direct2D 不支援非相依轉換。 轉換是由 D2D1_MATRIX_3X2_F 結構表示。 這個結構會定義 3 × 2 矩陣。 因為 affine 轉換的第三個數據行一律是相同的 ([0, 0, 1]) ,而且因為 Direct2D 不支援非相依轉換,所以不需要指定整個 3 × 3 矩陣。 在內部,Direct2D 會使用 3 × 3 個矩陣來計算轉換。

D2D1_MATRIX_3X2_F的成員會根據其索引位置命名:_11成員是元素 (1,1) ,_12成員是元素 (1,2) 等等。 雖然您可以直接初始化結構成員,但建議您使用 D2D1::Matrix3x2F 類別。 這個類別會繼承 D2D1_MATRIX_3X2_F ,並提供協助程式方法來建立任何基本相依轉換。 類別也會定義 operator* () 來撰寫兩個或多個轉換,如 在 Direct2D 中套用轉換中所述。

下一個

模組 4. 使用者輸入