共用方式為


附錄:矩陣轉換

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

矩陣簡介

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

3 x 2 矩陣。

表示法:矩陣是由大寫字母指定。 元素是由小寫字母所指定。 下標表示項目的數據列和數據行編號。 例如,ij 是矩陣 A 的第 i 列和第 j 欄的專案。

下圖顯示 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 的第一個數據列和 B 的 j『th 數據行。
  2. 將數據列和數據行中的每個專案組相乘:第一個數據列專案乘以第一個數據行專案、第二列專案乘以第二個數據行專案等等。
  3. 加總結果。

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

矩陣乘法。

矩陣乘法不是通勤的。 也就是說,A × B ≠ B × A。此外,從其之後的定義中,並非所有矩陣都可以相乘。 左側矩陣中的數據行數目必須等於右側矩陣中的數據列數目。 否則,不會定義×運算符。

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

I*ij* = 1 如果 *i* = *j*,否則為 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

這會展開至下列內容。

仿射轉換。

哪裡

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 軸中 dx 所翻譯的點 (x, y), Y 軸中的 dy

顯示兩點翻譯的圖表。

調整轉換

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

調整轉換。

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

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

,對應到以 dx dy縮放的點 (x,y)。

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

繞原點旋轉

要繞原點旋轉的矩陣具有下列形式。

顯示旋轉轉換的公式。

轉換的點為:

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) 設為原點來衍生此矩陣。

顯示繞點旋轉的圖表。

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

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

現在,使用公式 x1 = ax0 + cy0 + e 從稍早插入轉換矩陣。 使用相同的程式來衍生 y1。

扭曲轉換

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

  • 1:沿著 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Ф)

若要查看此轉換的運作方式,請個別考慮每個元件。 ≦參數會將 x 方向中的每個點移動等於 tan^。 下圖顯示 ^與 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,並提供協助程式方法來建立任何基本的仿射轉換。 類別也會定義 運算符*() 來撰寫兩個或多個轉換,如在 Direct2D 中套用轉換中所述。

下一個

模組 4. 用戶輸入