C++で三角関数を使う場合は、主に標準ライブラリの数学関数を利用します。
代表的なものには、サインを求める sin、コサインを求める cos、タンジェントを求める tan があります。
これらは、角度を使った計算や、座標計算、ゲーム開発、グラフィックス、物理シミュレーション、波形処理などでよく使われます。
C++の三角関数を理解するうえで特に重要なのは、角度の単位が「度」ではなく「ラジアン」であるという点です。
この点を間違えると、期待した計算結果にならないため注意が必要です。
C++で使う主な三角関数
サインを求める関数
サインは、三角形や円運動における縦方向の成分を求めるときによく使われます。
数学的には、直角三角形において「斜辺に対する向かい側の辺の比」を表します。
例えば、角度が30度の場合、サインの値は0.5になります。
ただし、C++で計算する場合は30度をそのまま渡すのではなく、30度をラジアンに変換してから計算する必要があります。
コサインを求める関数
コサインは、横方向の成分を求めるときによく使われます。
直角三角形では、「斜辺に対する隣り合う辺の比」を表します。
円運動や座標計算では、サインとコサインを組み合わせることで、円周上の位置や物体の移動方向を求めることができます。
タンジェントを求める関数
タンジェントは、角度に対する傾きを求めるときに使われます。
直角三角形では、「隣り合う辺に対する向かい側の辺の比」を表します。
ただし、タンジェントには注意点があります。
90度や270度のように、コサインが0になる角度では数学的に定義されません。
C++では浮動小数点の近似によって非常に大きな値が返ることがありますが、数学的には未定義に近い扱いになるため注意が必要です。
C++の三角関数はラジアンで扱う
度ではなくラジアンを使う
C++の三角関数で最も重要なのは、角度をラジアンで指定することです。
日常的には、角度を30度、45度、90度、180度のように「度」で考えることが多いです。
しかし、C++の三角関数では、これらをそのまま渡しても意図した結果にはなりません。
例えば、90度のサインを求めたい場合に、単純に90という値を渡すと、C++はそれを90度ではなく90ラジアンとして扱います。
そのため、度で考えている角度は、必ずラジアンに変換してから三角関数に渡す必要があります。
度とラジアンの対応関係
代表的な角度とラジアンの関係は次のようになります。
| 度 | ラジアン |
|---|---|
| 0度 | 0 |
| 30度 | π / 6 |
| 45度 | π / 4 |
| 60度 | π / 3 |
| 90度 | π / 2 |
| 180度 | π |
| 360度 | 2π |
C++で三角関数を使うときは、この対応関係を意識することが大切です。
度からラジアンへの変換
度をラジアンに変換するには、角度に円周率を掛けて180で割ります。
つまり、度数法の角度をラジアンに変えるには、次の考え方を使います。
ラジアン = 度 × π ÷ 180
例えば、180度はπラジアン、90度はπ ÷ 2ラジアン、45度はπ ÷ 4ラジアンになります。
ラジアンから度への変換
逆に、ラジアンを度に変換したい場合もあります。
その場合は、ラジアンに180を掛けて円周率で割ります。
度 = ラジアン × 180 ÷ π
三角関数の計算自体はラジアンで行いますが、結果を人間が読みやすい角度として表示したい場合は、ラジアンから度へ変換すると分かりやすくなります。
円周率の扱い方
C++20以降では標準の円周率定数を使える
C++20以降では、標準ライブラリに円周率を表す定数が用意されています。
そのため、C++20以降の環境であれば、自分で円周率を定義しなくても、標準で用意された円周率を使うことができます。
これは、C++で三角関数を扱ううえで便利な機能です。
C++17以前では自分で円周率を定義することが多い
C++17以前では、C++20のように標準の円周率定数をそのまま使えないため、自分で円周率を定義することがよくあります。
この場合、十分な桁数を持つ円周率を定数として用意しておけば、通常の学習や一般的なアプリケーション開発では問題なく使えます。
M_PIは環境依存なので注意する
C++のコード例では、M_PI という円周率の定数を見かけることがあります。
しかし、M_PI はC++標準で必ず使えるものではありません。
環境によっては使える場合もありますが、別の環境では使えないことがあります。
そのため、移植性を考えるなら、C++20以降では標準の円周率定数を使い、C++17以前では自分で円周率を定義する方法が安全です。
逆三角関数について
アークサイン
アークサインは、サインの値から角度を求めるための関数です。
例えば、サインの値が0.5になる角度を求めたい場合に使います。
ただし、アークサインに渡せる値は基本的に-1から1の範囲です。
この範囲を超える値を渡すと、数学的に定義できないため注意が必要です。
アークコサイン
アークコサインは、コサインの値から角度を求めるための関数です。
こちらもアークサインと同じように、渡せる値は基本的に-1から1の範囲です。
実務では、浮動小数点誤差によって、本来1になるはずの値がわずかに1を超えることがあります。
そのような値をそのままアークコサインに渡すと、意図しない結果になることがあります。
特に、ベクトルの内積から角度を求める処理では、この点に注意が必要です。
アークタンジェント
アークタンジェントは、タンジェントの値から角度を求めるための関数です。
ただし、方向角を求める場合は、単純なアークタンジェントよりも、次に説明する2引数のアークタンジェントを使う方が適しています。
方向角を求める場合はatan2が便利
2点間の角度や、座標から向きを求めたい場合は、2引数のアークタンジェントを使うのが一般的です。
これは、横方向と縦方向の差をもとに、正しい象限を考慮して角度を求めてくれる関数です。
通常のアークタンジェントでは、値の比だけを見るため、点がどの象限にあるのかを正しく判定しにくい場合があります。
一方、2引数のアークタンジェントは、x方向とy方向の符号を見て、角度が第1象限、第2象限、第3象限、第4象限のどこにあるかを判断できます。
そのため、ゲーム開発や座標計算では非常に重要です。
三角関数でよくある間違い
度をそのまま渡してしまう
最も多い間違いは、度で表した角度をそのまま三角関数に渡してしまうことです。
例えば、90度のサインを求めたいときに、90という数値をそのまま使うと、C++では90ラジアンとして扱われます。
90度と90ラジアンはまったく異なる角度です。
そのため、結果も期待したものとは大きく異なります。
C++で三角関数を使うときは、常に「この角度はラジアンか」を確認することが大切です。
計算結果が完全な0や1にならない
数学では、180度のサインは0です。また、90度のサインは1です。
しかし、C++で計算すると、理論上は0になるはずの値が、非常に小さい数値として表示されることがあります。
これは、コンピュータが小数を完全に正確に表現できないためです。
円周率も厳密な無限小数ではなく、コンピュータ上では近似値として扱われます。
そのため、数学的には0であっても、計算結果としては0に非常に近い値になることがあります。
このような浮動小数点誤差は、C++に限らず多くのプログラミング言語で発生します。
小数を完全一致で比較してしまう
三角関数の計算結果を比較するときに、完全一致で判定するのは避けた方がよいです。
例えば、「計算結果が0と等しいか」をそのまま判定すると、浮動小数点誤差の影響で期待通りに動かないことがあります。
実務では、完全に0かどうかではなく、「十分に0に近いかどうか」で判断するのが一般的です。
この考え方は、三角関数だけでなく、C++で小数を扱うとき全般に重要です。
タンジェントの特異点を考慮していない
タンジェントは、90度や270度のような角度で定義されません。
正確には、コサインが0になる角度ではタンジェントの値が定義できません。
C++では、円周率や角度が近似値として扱われるため、実際には非常に大きな有限値が返ることがあります。
しかし、それを通常の数値として扱うと、計算結果が不安定になる可能性があります。
タンジェントを使う場合は、その角度が特異点に近くないか注意する必要があります。
三角関数の実用例
円運動の座標計算
三角関数は、円運動の座標を求めるときによく使われます。
円の中心、半径、角度が分かっていれば、サインとコサインを使って円周上の位置を求めることができます。
一般的には、横方向の位置にはコサイン、縦方向の位置にはサインを使います。
この考え方は、時計の針の位置、円形メニュー、回転アニメーション、ゲーム内の弾の軌道などで利用されます。
物体の移動方向を計算する
ある角度に向かって物体を移動させたい場合にも、三角関数が使われます。
角度と速度が分かっていれば、コサインで横方向の移動量を、サインで縦方向の移動量を求めることができます。
例えば、キャラクターを60度の方向に進ませたい場合、速度を横成分と縦成分に分解する必要があります。
このとき、三角関数を使うことで自然に移動量を計算できます。
ゲーム開発や物理シミュレーションでは、非常によく使われる考え方です。
2点間の角度を求める
2つの点があるとき、一方の点からもう一方の点がどの方向にあるかを求めたい場合があります。
このような場合は、2点間のx方向の差とy方向の差を使って、方向角を求めます。
このときに便利なのが、2引数のアークタンジェントです。
通常のアークタンジェントでは象限の判定が難しいですが、2引数のアークタンジェントなら、座標の位置関係を踏まえて適切な角度を返してくれます。
波や振動を表現する
サインやコサインは、波や振動を表すときにも使われます。
例えば、上下にゆっくり揺れるアニメーション、音声波形、周期的な明るさの変化などは、三角関数で表現できます。
サイン波は周期的に値が変化するため、自然な揺れや反復運動を作るのに適しています。
座標系による注意点
数学座標と画面座標は向きが違う
三角関数を座標計算に使う場合、座標系の向きに注意が必要です。
数学で使う一般的な座標系では、x軸は右方向、y軸は上方向に増えます。
一方、画面座標では、x軸は右方向に増えることが多いですが、y軸は下方向に増えることが一般的です。
そのため、数学的な考え方をそのまま画面上の座標に適用すると、上下が逆になることがあります。
画面座標ではy方向の符号に注意する
画面上で円運動や移動方向を表現する場合、y方向の符号を反転させる必要があることがあります。
数学座標ではサインの値が正なら上方向を意味することがありますが、画面座標では下方向に進むことがあります。
そのため、ゲームやGUIで三角関数を使う場合は、自分が扱っている座標系でy軸がどちら向きに増えるのかを確認することが大切です。
型と精度について
基本的にはdoubleを使うことが多い
C++の三角関数では、float、double、long double などの浮動小数点型を扱えます。
学習用途や一般的な開発では、基本的に double を使うことが多いです。
double は精度と扱いやすさのバランスがよく、多くの場面で十分な精度を持っています。
floatやlong doubleも使える
より軽量な計算をしたい場合や、グラフィックス処理などで大量の数値を扱う場合は、float が使われることもあります。
一方、より高い精度が必要な場合には、long double を使うこともあります。
ただし、通常のアプリケーション開発や学習用途では、まずは double を使えば十分です。
整数を渡すときの注意点
三角関数に整数を渡すこともできますが、その場合も角度はラジアンとして扱われます。
整数の90を渡しても、それは90度ではなく90ラジアンです。
型の問題よりも、角度の単位を間違えないことの方が重要です。
角度の正規化
角度が範囲外になることがある
角度を扱っていると、370度や-30度のような値が出てくることがあります。
これらは間違いではありませんが、処理によっては0度から360度の範囲に収めた方が扱いやすい場合があります。
例えば、370度は10度と同じ向きです。-30度は330度と同じ向きです。
度を0度から360度に収める考え方
度で角度を扱う場合は、360度で割った余りを使うことで、角度を一定の範囲に収めることができます。
ただし、負の角度の場合は、余りを取ったあとに360度を足すなどの調整が必要になることがあります。
このように角度を一定範囲にそろえる処理を、角度の正規化と呼ぶことがあります。
ラジアンを0から2πに収める考え方
ラジアンで角度を扱う場合は、360度に相当する値が2πです。
そのため、ラジアンを正規化する場合は、2πを基準にして範囲をそろえます。
角度の正規化は、回転処理や方向判定、アニメーションなどで便利です。
C++で三角関数を使うときのポイント
角度の単位を必ず確認する
C++の三角関数で最も重要なのは、角度がラジアンであることです。
度で考えた値をそのまま渡すと、期待した結果になりません。
三角関数を使う前には、今扱っている角度が度なのかラジアンなのかを必ず確認しましょう。
浮動小数点誤差を前提にする
三角関数の計算結果には、浮動小数点誤差が含まれることがあります。
数学的には0や1になる値でも、C++ではわずかにずれた値になることがあります。
そのため、計算結果を比較するときは、完全一致ではなく、許容誤差を考慮することが重要です。
atan2を積極的に使う
座標から角度を求める場合は、通常のアークタンジェントよりも2引数のアークタンジェントを使う方が安全です。
2引数のアークタンジェントは、x方向とy方向の符号をもとに、正しい象限を考慮して角度を求められます。
2点間の角度や、物体の向き、マウスカーソルの方向などを求める場合に便利です。
画面座標ではy軸の向きに注意する
ゲームやGUIでは、画面座標のy軸が下向きに増えることが多いです。
数学の座標系とは上下が逆になるため、サインを使った縦方向の計算では符号に注意する必要があります。
三角関数の式そのものが間違っていなくても、座標系の違いによって見た目の動きが逆になることがあります。
まとめ
C++の三角関数は、角度や座標を扱ううえで非常に重要な機能です。
基本的には、サイン、コサイン、タンジェントを使って、角度に応じた値を計算します。
特に、円運動、方向ベクトル、物体の移動、波や振動の表現などでよく利用されます。
ただし、C++の三角関数では、角度を度ではなくラジアンで扱う点に注意が必要です。
90度や180度といった日常的な角度をそのまま渡しても、期待した結果にはなりません。
また、三角関数の計算結果には浮動小数点誤差が含まれることがあります。
数学的には0になる値でも、C++では非常に小さい値として表示されることがあります。
そのため、小数を比較するときは完全一致ではなく、誤差を考慮する必要があります。
さらに、座標計算で三角関数を使う場合は、数学座標と画面座標の違いにも注意しましょう。
特に画面上ではy軸が下向きに増えることが多いため、サインを使った縦方向の計算で符号が逆になる場合があります。
C++で三角関数を正しく使うためには、次のポイントを押さえておくことが大切です。
- 三角関数の引数はラジアンで指定する
- 度を使う場合はラジアンに変換する
- 円周率の扱いに注意する
- 浮動小数点誤差を考慮する
- タンジェントの特異点に注意する
- 座標計算では座標系の向きを確認する
- 方向角を求める場合は2引数のアークタンジェントを使う
これらを理解しておけば、C++で三角関数を使った計算をより正確に扱えるようになります。
以上、C++の三角関数についてでした。
最後までお読みいただき、ありがとうございました。
