私は自分に3D数学を教えており、その過程で自分の基本的なエンジン(一種)を構築しています。私のC ++マトリックスクラスを構造化する最良の方法は何だろうと思っていました。いくつかのオプションがあります:
個別のメンバー変数:
struct Mat4 { float m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; // methods }
多次元配列:
struct Mat4 { float[4][4] m; // methods }
ベクトルの配列
struct Mat4 { Vec4[4] m; // methods }
それぞれに良い面と悪い面があると思います。
以下からのグラフィックスとゲーム開発のための3D数学入門、第2版の P.155:
行列は1ベースのインデックスを使用するため、最初の行と列には1の番号が付けられます。たとえば、
a12
(a
「a
12」ではなく「1つ2つ」と読む)は、最初の行、2列目の要素です。これは、0ベースの配列インデックスを使用するC ++やJavaなどのプログラミング言語とは異なることに注意してください。行列には列0または行0がありません。実際の配列データ型を使用して行列が格納されている場合、このインデックスの違いにより混乱が生じる可能性があります。このため、幾何学的な目的で使用される型の固定サイズの小さな行列を格納するクラスでは、float a11
floatなどの言語のネイティブ配列サポートを使用する代わりに、各要素にのような独自の名前付きメンバー変数を与えるのが一般的ですelem[3][3]
。
つまり、メソッド1に対する1票です。
これは本当に受け入れられる方法ですか?唯一の利点が従来の数学表記に固執することであるならば、それはかなり扱いにくいようです。
2
最初にマトリックスのインターフェイス(パブリックメンバー関数)について考えます。たとえば、GetRowまたはGetForwardVectorが必要になる場合があります。それらを最も効率的に実装する方法を考えてから、内部データ構造が自然に配置されます
—
Maik Semder
C ++では、配列とメンバー変数の両方を同時に使用できますが、Union :)
—
API-Beast
多くの線形代数では、行列にいくつかの特定のセルが必要なので、私は間違いなく方法1を選びます。配列には必要な配列だけが含まれることはないため、上記の前方ベクトルのように、単純な質問では常に複数の配列にインデックスを付ける必要があります。これは、MicrosoftがXNAフレームワークでそれを行う方法でもあります(もちろん、1つの会社がそれを行うことは最善の議論ではありません)
—
Roy T.
私は間違いなくゼロインデックス配列にこだわるでしょう-私は多くの科学計算を行っており、数学とコードの間を移動するときにインデックスを変換することは、コード内で矛盾するよりもはるかに混乱しにくいです。オプション2または3を使用する場合、ルーチンが任意のサイズの行列で動作するようにする方が簡単です。これは、最終的に何かが必要になる可能性があります(たとえば、おそらく行列乗算ルーチンがあり、行列行列または行列ベクトルに使用できます)。
—
ジェームズ