0
3
いくつかの「XXX座標系」という概念がある状況での話です.
例えば,3次元のグラフィクスを扱うような場面では,よく{ワールド座標系,カメラ座標系}といった概念が出てきますよね.そういう話です.
(以下,コード例では簡便さのため2次元で書きますが)
例えば
C++
1// 2//行列やベクトルの型とか演算は残念なことに C++ 標準で用意されていないから 3//自前でこんなのを書いて(あるいは既存の何かを持ってきて)使う 4// 5class Vec2{ ... }; //2次元のベクトル用の型 6class Mat2x2{ ... }; //2x2 の行列の型 7 8// 9int main() 10{ 11 //なんかベクトルと行列を用いた演算 12 Vec2 V{ 10, 20 }; 13 Mat2x2 TransMat{ {0,1}, {-1,0} }; 14 Vec2 TransedVec = TransMat * V; //(こういう operator の実装もあるのだとして) 15}
みたいなコードがあるとして,この main()
内のコードは
「何らかの座標変換をしているんじゃないかな感」はある(と思う)のですが,
「どの座標系の量をどの座標系の量に変換しているのか」は全くわかりません.
それ以前にベクトル V
とはどの座標系での量として定義している つもり/ハズ なのか? といったことも謎です.
で,私くらいの馬〇になると,これ系の演算を実装するときに
その辺の事柄を取り違えたり間違ったりしてしまうことが割とあって,その結果は(当たり前ですが)全く意味不明な演算結果になります.
そういう場合のデバッグは結構厄介です.
(特に「分かり切っている」つもりの箇所でやらかしてたりすると気づきにくい)
そこで,↑の Vec2
とか Mat2x2
とかいう型を
「ベクトルです」「マトリクスです」という単純な(汎用な)存在とするのではなくて,
「ワールド座標系でのベクトルです」とか「ワールド座標系からカメラ座標系への変換行列です」とかいう専用の型にしてしまえば
間違いを事前抑止できる可能性があるのではなかろうか? とか夢想したわけです.
扱う座標系の種類の個数が定まっているのであれば,
C++
1//座標系の種類 2enum class CoordinateSystem{ World, Camera }; 3 4//特定の座標系におけるベクトル 5template< CoordinateSystem CS > 6class Vec2 7{ 8public: 9 //各種演算は同じ座標系のベクトル同士じゃないとできない 10 Vec2 &operator +=( const Vec2 &rhs ); 11 Vec2 &operator -=( const Vec2 &rhs ); 12 double Dot( const Vec2 &rhs ) const; 13}; 14 15//From座標系の量(ベクトル)を To座標系での量に変換するマトリクス 16template< CoordinateSystem From, CoordinateSystem To > 17class Mat2x2 18{ 19public: 20 //乗じるベクトルは From座標系で,乗じた結果は To座標系 21 Vec2<To> operator *( const Vec2<From> &V ) const; 22}; 23 24//型名が長ったらしいので using 25using WorldVec = Vec2< CoordinateSystem::World >; 26using CameraVec = Vec2< CoordinateSystem::Camera >; 27using W2CMat = Mat2x2< CoordinateSystem::World, CoordinateSystem::Camera >;
とかしてしまえば,
変数を 宣言/定義 する際には必ず座標系を明確に意識せねばならず,馬鹿みたいな間違いを抑制できるのではないかな,と.
また,
C++
1WorldVec V1{ 1,2 }; 2CameraVec V2{ 3,4 }; 3auto V3 = V1 + V2; //←その演算の意味は何なの?
みたいなのがコンパイルを通らなくなるのは大変素敵なのではなかろうか? と.
……が,他方では
「理由ははっきりしないが,なんだか馬鹿馬鹿しい(仰々しい?)コードと思える」
「そんなの変数名とかで表現すれば十分じゃね? 不足ならコメントでも書けと」
みたいな気もしてきます.
↑のようなコード,どう思いますか?
(「意見交換」ならこんな雑な聞き方をしても良いと思っている)
回答10件
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。