三次元変換行列(9)
2008/05/14 20:45 - AS3.0
以前、三次元変換行列で最低限必要なメソッドは以下の五つであると書きました。
- 平行移動(translate)
- 拡大縮小(scale)
- 軸回転(rotateAxis)
- 行列合成(concat)
- 行列複製(clone)
すまん、ありゃウソだ(おい)。
えー、半分は正しくて半分は間違ってます。
行列の更新に関する処理はこれらのメソッドで事足ります。 しかしこのクラスは三次元『変換』行列です。
このクラスの一番肝心な機能は、更新した行列の内容を三次元座標に反映させ、新しい座標値を得ること。 行列と座標を計算して、新しい座標を求めるためのメソッドが必要なのです。
始めは flash.geom.Transform に倣って、Transform3D みたいなクラスを作り、そっちに委譲すればいいのかなぁと思っていました。
しかし LiveDocs で flash.geom.Matrix の項を見ていたら、Matrix.transformPoint() というメソッドがあるじゃあありませんか。
Matrix オブジェクトで表現される図形変換を、指定されたポイントに適用したことによって値を返します。
パラメータ
point:Point 行列変換の結果として得られるポイントです。
戻り値
Point 行列変換を適用した結果のポイントです。
まさにコレ。
Matrix クラス同様、Matrix3D クラスに transformPoint3D() というメソッドを持たせることにします。
「コンピュータゲームの数学」のP76やP82に書かれていることから推察するに、三次元変換行列の内容を三次元座標に反映させて、新しい三次元座標を得るには以下の計算をおこなうようです。
| nx | | a b c tx | | x | | ny | = | d e f ty | * | y | | nz | | g h i tz | | z | | 1 | | 0 0 0 1 | | 1 |
それを素直に ActionScript に落とし込んだのが以下のコード。
public function transformPoint3D( p:Point3D ):Point3D { var nx:Number = _a * p.x + _b * p.y + _c * p.z + _tx; var ny:Number = _d * p.x + _e * p.y + _f * p.z + _ty; var nz:Number = _g * p.x + _h * p.y + _i * p.z + _tz; return new Point3D( nx, ny, nz ); }
で、今までのコードをまとめた as ファイルがコレ。 ついでに toString() メソッドも実装しときました。