進め、自分。

ゲームプログラマがC++のことなどを。

角度クラス 構想

環境整備もなかなか進まないので、
取り敢えず家にいなくてもできる事ってことで、
このブログで書きたかった事を進めることにしようかと。

まず1つ目にやりたかった、角度クラスについて。

ゲーム開発でも、浮動小数でradianやdegreeを扱って、
必要に応じて deg2rad や rad2deg とかって関数で変換するのが多いです。
で、よく問題になるのが、関数はradianを要求しているのに、間違ってdegreeを渡してしまうとか、
そもそも関数がどっちを要求してんだよ!ってことですね。

radianとdegreeの扱いについて、↓の様な記事もあります。
魔導書に触発されてRadian⇔Degree変換をやってみた - C++でゲームプログラミング
角度のstrong typedef - Faith and Brave - C++で遊ぼう

で、自分がやりたいのは、radianかdegreeかをあまり気にしなくて済むことです。
この関数はどっちを要求してるの?とか、この変数はどっち?とか。
なので、radianとdegreeは暗黙的に変換してほしい。

例えば、

// Radianクラスを引数にとるサイン関数
float sin( Radian rad ) {...}

// Degreeクラスを渡すと、暗黙的にRadianに変換してくれる。
Degree deg( 180 );
float s = sin( deg );

という感じで。

あと、クラス化して幾つかメソッドも追加したいですね。
0度~360度に正規化するメソッドや、
2つの角度間で最小の角度差を求めるとか。
そもそも三角関数も、角度クラスのメソッドにあってもいいかもしれないですね。

ここまでが、結構前から考えてた角度クラスの実装です。

で、ちょっと前に思いついたのが、
そもそも角度をradianとdegreeで扱うのってどうなの?ということ。
1周を360度とか円周率x2で扱わなくていいんじゃないかと。
もちろん、それが必要な時もあるけど、途中の計算で必要になることってあまりない。

プログラム中で 180 とか 360 って書くのは、
普通なら「マジックナンバー使うな!」と起こられるようなことだし、
円周率みたいな無理数を扱うのって冷静に考えたらあんまり良くない。

で、どうするかって言うと、1周を 1.0 として扱ってしまう。
これ、すごく自然だと思うんですよね。
180度は0.5、90度は0.25。
30度とかは流石に直値では書けないので、30 / 360.f って書くのがわかりやすいだろうけど。
まあ、これはradianで計算している時も一緒ですね。

一周が1.0だから正規化するのも楽だし、
例えば「30フレームかけて2回転させる」とかって、
「2.0 / 30.f * time」
みたいな計算だけでOK。
degreeだと「360 * 2.0 / 30.f * time」って計算になっちゃいますね。

使い方は↓みたいな感じで。

// Angleクラスを引数にとるサイン関数
float sin( Angle angle ) {...}

Angle angle( 0.5f ); // 180度
float s = sin( angle );

sin( Degree(180) ); // degreeの方がわかりやすい時はこんな感じで

以上がざっくりとした構想です。

さ、これからこの実装を進めて行きますよ。進め、自分。