変換の行列表現

m×n 行列は、m 行と n 列に配置された数値のセットです。 次の図は、いくつかの行列を示したものです。

次元が異なる 6 つのマトリックスを示す図

個々の要素を追加することにより、同じサイズの 2 つの行列を加算できます。 次の図は、行列の加算の例を 2 つ示したものです。

マトリックスの追加を実行する方法を示す図

m×n 行列は n×p 行列で乗算でき、結果は m×p 行列です。 1 つ目の行列の列数は、2 つ目の行列の行数と同じである必要があります。 たとえば、4 ×2 行列に 2 ×3 行列を掛けて、4 ×3 行列を生成できます。

平面内の点と行列の行と列は、ベクターと考えることができます。 たとえば、(2, 5) は 2 つのコンポーネントを持つベクターで、(3, 7, 1) は 3 つのコンポーネントを持つベクターです。 2 つのベクターのドット積は、次のように定義されます。

(a, b) • (c, d) = ac + bd

(a, b, c) • (d, e, f) = ad + be + cf

たとえば、(2, 3) と (5, 4) のドット積は (2)(5) + (3)(4) = 22 です。 (2, 5, 1) と (4, 3, 1) のドット積は、(2) (4) + (5) (3) + (1) (1) = 24 です。 2 つのベクターのドット積は、別のベクターではなく、数値であることに注意してください。 また、ドット積を計算することができるのは、2 つのベクターのコンポーネント数が同じ場合に限られます。

A(i, j) を i番目 の行と j番目 の列の行列 A のエントリにしてみましょう。 たとえば、A(3, 2) は、3番目 の行と 2番目 の列の行列 A のエントリです。 A、B、および C が行列で、AB = C であるとすると、C のエントリは次のように計算されます。

C(i, j) = (A の i 行) • (B の j 列)

次の図は、行列の乗算の例をいくつか示したものです。

行列乗算の実行方法を示す図

平面内の点を 1 × 2 行列と考える場合は、その点に 2 × 2 行列を掛けて変換できます。 次の図は、点 (2, 1) に適用されたいくつかの変換を示したものです。

行列乗算を使用して平面内のポイントをスケーリング、回転、または反映する方法を示す図

前の図に示したすべての変換は、線形変換です。 変換など、他の特定の変換は線形ではなく、2 × 2 行列で乗算として表すことはできません。 たとえば、点 (2, 1) で開始し、それを 90 度回転し、x 方向に 3 単位平行移動し、y 方向に 4 単位平行移動したいとします。 これを実現するには、行列乗算の後に行列の加算を実行します。

行列の乗算と加算によって点を回転させ、2 回翻訳する方法を示す図

線形変換 (2 × 2 行列による乗算) とそれに続く変換 (1 × 2 行列の加算) は、アフィン変換と呼ばれます。 アフィン変換を一対の行列に格納する代わりに、変換全体を 3 × 3 行列に格納します 。1 つは線形部分用で、もう 1 つは変換用です。 この作業を行うには、平面内の点を、ダミーの 3 番目の座標を持つ 1 × 3 行列に格納する必要があります。 通常は、3 つ目の座標をすべて 1 に設定するという方法が使用されます。 たとえば、点 (2, 1) は、行列 [2 1 1] によって表されます。 次の図は、単一の 3 × 3 行列による乗算として表されるアフィン変換 (90 度回転し、x 方向に 3 単位、y 方向に 4 単位を平行移動) を示しています。

行列乗算でアフィン変換を実行する方法を示す図

前の例では、ポイント (2、 1) がポイント (2、6) にマップされています。 3 × 3 行列の 3 番目の列には、数値 0、0、1 が含まれていることに注意してください。 これは常に、アフィン変換の 3 × 3 行列の場合です。 重要なのは、列 1 と列 2 の 6 つの数値です。 行列の左上 2 × 2 部分は変換の線形部分を表し、3 番目の行の最初の 2 つのエントリは変換を表します。

最初の 2 つの列がアフィン変換の 3 x 3 行列で最も重要であることを示す図

Windows GDI+ では、アフィン変換を Matrix オブジェクトに格納できます。 アフィン変換を表す行列の 3 番目の列は常に (0, 0, 1) であるため、 Matrix オブジェクトを作成するときは、最初の 2 つの列に 6 つの数値のみを指定します。 ステートメント Matrix myMatrix(0.0f, 1.0f, -1.0f, 0.0f, 3.0f, 4.0f); は、前の図に示したマトリックスを構築します。

複合変換

複合変換とは、変換を順番に実行していく、変換のシーケンスのことです。 次の一覧に示す行列と変換について考えてみましょう。

  • 行列 A 90 度回転
  • 行列 B x 方向の係数 2 によるスケール
  • 行列 C y 方向に 3 単位を平行移動

行列 [2 1 1] で表される点 (2, 1) で始まり、A、B、C で乗算すると、ポイント (2,1) は一覧表示された順序で 3 つの変換を行います。

[2 1 1]ABC = [ –2 5 1]

複合変換の 3 つの部分を 3 つの別々の行列に格納するのではなく、A、B、C を乗算して、複合変換全体を格納する単一の 3 × 3 個の行列を取得できます。 ABC = D とした場合、点を D で乗算した結果は、A、B、C の順に乗算した結果と同じになります。

[2 1 1]D = [ –2 5 1]

次の図は、A、B、C、D の行列を示したものです。

構成行列を乗算して複数の変換を実行する方法を示す図

複合変換の行列は、個々の変換行列を乗算することによって形成できるという事実は、アフィン変換の任意のシーケンスを単一の Matrix オブジェクトに格納できることを意味します。

注意

複合変換では、順序が重要となります。 通常、回転、拡大縮小、平行移動という順序での操作は、スケーリング、回転、平行移動という順序での操作でと同じではありません。 同様に、行列の乗算においても順序が重要となります。 通常、ABC は BAC と同じではありません。

 

Matrix クラスには、複合変換を構築するためのいくつかのメソッド (Matrix::MultiplyMatrix::RotateMatrix::RotateAtMatrix::ScaleMatrix::ShearMatrix::Translate) が用意されています。 次の例では、最初に 30 度回転し、次に y 方向に 2 の係数でスケーリングし、x 方向に 5 単位を平行移動する複合変換の行列を作成します。

Matrix myMatrix;
myMatrix.Rotate(30.0f);
myMatrix.Scale(1.0f, 2.0f, MatrixOrderAppend);
myMatrix.Translate(5.0f, 0.0f, MatrixOrderAppend);

以下の図は、この行列を示したものです。

三角関数として表される値を持つ行列と、それらの関数の近似値を持つ行列を示す図