座標系を制限した型を考えたのですが自分でも「コレどうなの?」ってなる

いくつかの「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//型名が長ったらしいので using25using 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; //←その演算の意味は何なの?

みたいなのがコンパイルを通らなくなるのは大変素敵なのではなかろうか? と.

……が,他方では
「理由ははっきりしないが,なんだか馬鹿馬鹿しい(仰々しい?)コードと思える」
「そんなの変数名とかで表現すれば十分じゃね? 不足ならコメントでも書けと」
みたいな気もしてきます.

↑のようなコード,どう思いますか?
(「意見交換」ならこんな雑な聞き方をしても良いと思っている)

コメントを投稿

0 コメント