Matrices

Chapter3

Matrix4x4

3D グラフィクスで使う行列は主に 4x4 行列なので、汎用性のある作りにするのではなく、4x4 行列専用の構造体を用意する。

4x4 行列は内部的に 1 次元の配列で持つ。

pub struct Matrix4x4 {
    m: [f32; 16],
}

その場合、並びの順序には row-major と column-major の 2通りが考えられるが、今回は row-major でいくことにする。つまり、以下の順序で並んでいるとみなす。


  \begin{pmatrix}
    0 & 1 & 2 & 3 \\\
    4 & 5 & 6 & 7 \\\
    8 & 9 & 10 & 11 \\\
    12 & 13 & 14 & 15
  \end{pmatrix}

よって、ij 列にアクセスしたい場合には、配列の

 i * 4 + j

番目の要素にアクセスする。

    pub fn at(&self, row: usize, column: usize) -> f32 {
        debug_assert!(row < 4 && column < 4);

        self.m[row * 4 + column]
    }

行列式

行列の実装は素直に行っていることもあり、とりたてて書くことはあまりない。複雑なことをやっているのは逆行列の計算くらいで、この計算には一旦行列式を求める必要がある。

4x4 の行列式を直接計算するのは複雑ということで、余因子展開を利用してよりサイズの小さい行列から計算している。実際のところ 3x3 行列なら行列式の計算もそこまで複雑ではないけれど、本の記述に倣って 3x3 行列に対しても 2x2 の行列式から求めるようにする。

その際、内部的に Matrix3x3Matrix2x2 を用意する。これは逆行列の計算にのみ利用するものであり、他から使われることはない。よって pub は不要。

f:id:mtXTJocj:20191117204404p:plain

余談

今回はじめてはてなブログで数式を書いたのだけれど、おそろしく使いにくかった。& が勝手に "amp;" にされてしまい、解決するのに結構時間を使ってしまった。

こういうどうでも良いことに時間を使わされると、徒労感がすごいよね。得るものも何もないし。