三次元変換行列(4)出直し
2008/05/12 22:00 - AS3.0
今まで作成していた三次元変換行列クラスは、行列プロパティを二次元配列で実装しようとしていました(「三次元変換行列」(4))。
前回のエントリーで、Array でのアクセスの遅さはヤバげという情報を得、二次元配列による行列実装は考え直さなアカンか? でもこのまま目をつぶって先に行くよ、ということで一歩進みました(「三次元変換行列」(5))。
今日、前回見た Array は遅いという記事の検証をなさっているエントリーを発見。 そちらではベンチマークのソースも公開されていたので、それを拝借して自分の三次元変換行列クラスの速度検証をしてみました。検証は以下の2パターンについて。
- 行列を二次元配列で定義(今はこっち)
- 行列の各成分を個別で定義
お話しにならん結果が出ました。
FREQUENCY_OF_TRIAL: 100,000 -------- (translate) array : 228(ms) not array : 97(ms) -------- (scale) array : 490(ms) not array : 93(ms) -------- (rotate) array : 14271(ms) not array : 3640(ms)
平行移動で2.3倍、拡大縮小で5.3倍、回転で3.9倍も余計に時間がかかってます、二次元配列を使うと。
Array アクセスはやっぱりかなり遅そう。
これはいくらなんでもマズいんで針路変更しますよ。 行列は二次元配列ではなく、各成分を個別に設定するパターンでコーディングします。
てなわけで「三次元変換行列」シリーズは五歩すすんで二歩さがりました。 (4)からやり直しですよ。
まず行列の配置ですが、これは変わりません。以下のとおりです。
| a b c tx | | d e f ty | | g h i tz | | 0 0 0 1 |
でコード的には、クラスプロパティとして、各成分を個別に実装します。
private var _a:Number; private var _b:Number; private var _c:Number; private var _d:Number; private var _e:Number; private var _f:Number; private var _g:Number; private var _h:Number; private var _i:Number; private var _tx:Number; private var _ty:Number; private var _tz:Number;
これらのプロパティはセッターとゲッターで外部からアクセスできるようにします。
コンストラクタですが、旧4回のときに考えた基本設計(剪断不要)のままで問題ないと考えてます。
よって行列成分を個別に実装するコードに変更しても、コンストラクタの引数はゼロのコードを踏襲しようと思っていました。
しかし flash.geom.Matrix のようにコンストラクタで行列の全成分を引数としてした方が、clone メソッドをコードする際には楽だし、剪断を意図的に不可能にする正当な理由も特にないしで、今度のコンストラクタは、引数に行列の各成分を取るものとしてコーディングします。
public function Matrix3D( a : Number = 1, b : Number = 0, c : Number = 0, d : Number = 0, e : Number = 1, f : Number = 0, g : Number = 0, h : Number = 0, i : Number = 1, tx : Number = 0, ty : Number = 0, tz : Number = 0 ) { _a = a; _b = b; _c = c; _d = d; _e = e; _f = f; _g = g; _h = h; _i = i; _tx = tx; _ty = ty; _tz = tz; }
引数の規定値として、単位行列になる値を各成分に設定します。
ですんで、このクラスオブジェクトを生成する際には引数なしで new すれば良いと。
続く。