CG理論 #3 変換 [Devlog #008]

Table of Contents

CG屋さんのバイブル:Real Time Rendering Fourth Edition を読んで理解したことについてを要約します(内容の転載を避け、詳しく説明しすぎないように配慮します)

変換

変換(transform)


線形変換はベクトル加算とスカラー乗算を保存するもの $$ \textbf{f}(\textbf{x}) + \textbf{f}(\textbf{y}) = \textbf{f}(\textbf{x}+\textbf{y}) $$ $$ k\textbf{f}(\textbf{x}) = \textbf{f}(k\textbf{x}) $$ これが満たされれば線形であるといえる

スケール変換回転変換など、3要素ベクトルに対するすべての線形変換は3×3行列で表せる
線形変換は原点を不動点とする変換であり、原点は変換されずにそのままの位置に残る

3要素ベクトル $\textbf{x}$ への写像 $\textbf{f}(\textbf{x}) = \textbf{x} + (7, 3, 2)$ のような平行移動は線形ではない
平行移動は、原点の位置が変わるという特性がある

線形変換と平行移動の結合は、一般に4×4行列で格納されるアフィン変換を使って表す

同次表記は点と方向(ベクトル)を同じ形式で扱うことを可能にする

同次座標系では、 $n$ 次元空間における点を $n+1$ に拡張し、例えば3次元点 $(x,y,z)$ はベクトル $(x,y,z,1)$ と表現する

$$ \textbf{v} = \begin{pmatrix} x & y & z & 1\ \end{pmatrix}^T $$

方向(ベクトル)についても、$n$ 次元空間であれば $n+1$ に拡張し、3次元ベクトル $(v_x,v_y,v_z)$ はベクトル $(v_x,v_y,v_z,0)$ と表現する

$$ \textbf{v} = \begin{pmatrix} v_x & v_y & v_z & 0\ \end{pmatrix}^T $$

ここでの $0$ は、ベクトルが原点に固定されないことを示す

基本的な変換

平行移動

ある位置から別の位置への移動変化は ベクトル $\textbf{t}=(t_x,t_y,t_z)$ を用いて平行移動行列 $\textbf{T}$ で表される $$ \textbf{T}(\textbf{t}) = \textbf{T}(t_x,t_y,t_z) =\begin{pmatrix} 1 & 0 & 0 & t_x \\\ 0 & 1 & 0 & t_y \\\ 0 & 0 & 1 & t_z \\\ 0 & 0 & 0 & 1 \end{pmatrix} $$ 点 $\textbf{p}$ の平行移動の例: $$ \text{新しい点} \textbf{p}^\prime =\textbf{T}(\textbf{t})\textbf{p} =\begin{pmatrix} 1 & 0 & 0 & t_x \\\ 0 & 1 & 0 & t_y \\\ 0 & 0 & 1 & t_z \\\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} p_x \\\ p_y \\\ p_z \\\ 1 \end{pmatrix} =\begin{pmatrix} p_x+t_x \\\ p_y+t_y \\\ p_z+t_z \\\ 1 \end{pmatrix} $$

平行移動行列の逆行列は $\textbf{T}^{-1}(\textbf{t})=\textbf{T}(-\textbf{t})$ となり、ベクトル $\textbf{t}$ の符号反転になる

行列をメモリに格納する際の配置は表記法によって異なり、ここでは変換の順序が左から右になる列優先形式で表されている(OpenGLはこれ)(平行移動ベクトルが最右列)

一方、DirectXなどは右から左の順序で変換する行優先形式が使われる(平行移動ベクトルが最下行) $$ \text{新しい点} \textbf{p}^\prime =\textbf{p}\textbf{T}(\textbf{t}) =\begin{pmatrix} p_x & p_y & p_z & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 1 & 0 \\\ t_x & t_y & t_z & 1 \end{pmatrix} $$ $$ =\begin{pmatrix} p_x+t_x & p_y+t_y & p_z+t_z & 1 \end{pmatrix} $$

以降、列優先(OpenGLと同じ形式)を考慮する

回転

回転変換は、ベクトル(位置や方向)を与えられた原点を通る軸の周りに与えられた角度で回転する

平行移動行列と同様に剛体変換である(点の間の距離と座標系の向きを保存する)

姿勢行列は、空間中の姿勢(カメラビューやオブジェクトの上と前の方向)を定義する回転行列である

2次元空間において、ベクトル $\textbf{v}=(v_x,v_y)$ があるとすると、 $$ \textbf{v}=(v_x,v_y)=(rcos(\theta),rsin(\theta)) $$ とパラメータ化できる

このベクトルを反時計回りに $\phi$ ラジアン回転することを考えると、 $$ \textbf{u} =\begin{pmatrix} rcos(\theta+\phi) \\\ rsin(\theta+\phi) \end{pmatrix} =\begin{pmatrix} r(cos\theta cos\phi-sin\theta sin\phi) \\\ r(sin\theta cos\phi+cos\theta sin\phi) \end{pmatrix} $$ $$ =\begin{pmatrix} cos\phi & -sin\phi \\\ sin\phi & cos\phi \end{pmatrix} \begin{pmatrix} rcos\theta \\\ rsin\theta \end{pmatrix} =\textbf{R}(\phi)\textbf{v} $$ と、うまいこと行列の計算に変換できる

これを3次元空間に拡張すると、 $x$ 軸、 $y$ 軸、 $z$ 軸の周りに $\phi$ ラジアン回転する回転行列を $\textbf{R}_x(\phi)$ 、 $\textbf{R}_y(\phi)$ 、 $\textbf{R}_z(\phi)$ と表すことができる

$$ \textbf{R}_x(\phi) =\begin{pmatrix} 1 & 0 & 0 & 0 \\\ 0 & cos\phi & -sin\phi & 0 \\\ 0 & sin\phi & cos\phi & 0 \\\ 0 & 0 & 0 & 1 \end{pmatrix} $$ $$ \textbf{R}_y(\phi) =\begin{pmatrix} cos\phi & 0 & sin\phi & 0 \\\ 0 & 1 & 0 & 0 \\\ -sin\phi & 0 & cos\phi & 0 \\\ 0 & 0 & 0 & 1 \end{pmatrix} $$ $$ \textbf{R}_z(\phi) =\begin{pmatrix} cos\phi & -sin\phi & 0 & 0 \\\ sin\phi & cos\phi & 0 & 0 \\\ 0 & 0 & 1 & 0 \\\ 0 & 0 & 0 & 1 \end{pmatrix} $$

最下行と最右列を削った3×3行列 $\textbf{R}$ のトレースは回転の角度 $\phi$ に関連している(剛体の回転運動の解析に使える) $$ \textbf{R} =\begin{pmatrix} r_{11} & r_{12} & r_{13} \\\ r_{21} & r_{22} & r_{23} \\\ r_{31} & r_{32} & r_{33} \end{pmatrix}, \quad tr(\textbf{R})=r_{11} + r_{22} + r_{33} = 1+2cos\phi $$

回転行列は直交し、行列式は1となる(回転変換をいくつ連結しても成り立つ)

回転行列の逆行列は、 $\textbf{R}_i^{-1}(\phi)=\textbf{R}_i(-\phi)$ となり、同じ軸での反対方向の回転となる


【点の周りの回転の例】

点 $\textbf{p}$ を回転の中心として、オブジェクトを $z$ 軸周りで $\phi$ ラジアン回転させる $$ \textbf{X}=\textbf{T}(\textbf{p})\textbf{R}_z(\phi)\textbf{T}(-\textbf{p}) $$

  1. $\textbf{p}$ が原点と一致するように平行移動 $\textbf{T}(-\textbf{p})$
  2. 回転 $\textbf{R}_z(\phi)$
  3. 元の位置に平行移動で戻す $\textbf{T}(\textbf{p})$

拡大縮小(スケール)

(編集中)

せん断

変換の連結

剛体変換

法線の変換

逆行列の計算

特殊な行列変換と操作

オイラー変換

オイラー変換からのパラメータ抽出

行列の分解

任意の軸の周りの回転

クォータニオン

クォータニオン

クォータニオン変換

行列への変換

球面線形補間

頂点ブレンド

モーフィング

ジオメトリーキャッシュの再生

投影

正投影

透視投影