このページでは、プログラミングにおける「三角関数の重要性」について解説していきます!
数学で三角関数(sin
・cos
・tan
)を習って「これいつ使うんだろ…?」って疑問に思った方も多いのではないでしょうか?
実際、三角関数を全く使わずに日常を過ごしている人も多いと思います。
ですが、プログラミングしてると結構三角関数を使う場面は多いです。特にゲームや画像など、座標を扱うプログラムを作成する場合は、三角関数が大活躍します!
このページでは、実際に三角関数が活躍する場面を紹介しながら、三角関数の重要性について解説していきたいと思います。
Contents
三角関数のおさらい
まずは簡単に三角関数のおさらいをしていきたいと思います(このページでは三角関数としては sin
・cos
・tan
の3つのみ扱っていきます)。
三角関数
下の図で表す底辺の長さ a
、高さ b
、斜辺の長さ r
の直角三角形において、
斜辺と底辺とがなす角の角度 θ
を用いて、sinθ
・cosθ
・tanθ
は直角三角形の各辺の比により下記のように表すことが出来ます。
sinθ
=b
/r
cosθ
=a
/r
tanθ
=b
/a
三角関数を習ったことがある方であれば、この辺りはなんとなく覚えているという方も多いのではないでしょうか?
スポンサーリンク
三角関数の便利なところ
この三角関数の便利なところは、直角三角形における「直角以外の角度1つ」と「辺の長さ1つ」さえ分かれば、他の辺の長さが求められるところです。
例えば、斜辺と底辺とがなす角の角度 θ
と底辺の長さ a
が判明しているのであれば、他の辺の長さである r
と b
は下記により得ることが出来ます。
r
=a
/cosθ
b
=a
*tanθ
また、斜辺と底辺とがなす角の角度 θ
と斜辺の長さ r
が判明しているのであれば、他の辺の長さである a
と b
は下記により得ることが出来ます。
a
=r
*cosθ
b
=r
*sinθ
このように三角関数を利用すれば、直角三角形における「直角以外の角度1つ」と「辺の長さ1つ」さえ分かれば、他の辺の長さを簡単に求めることが可能です。
特に上記の式はプログラミングでよく使う式になります。
これは、プログラミングで座標を扱う場合、斜め方向の長さや角度ではなく、x
座標(横方向の座標)と y
座標(縦方向の座標)で扱うことが多いからです。
例えばゲームのキャラクターがある座標 (x1
, y1
) に存在し、このキャラクターを角度 θ
の方向に距離 r
だけ移動しようと思うと、この移動を実現するためには x
座標における長さ a
と y
座標における長さ b
をまず求める必要があります。
で、この a
と b
を求める際に三角関数が活躍します。
前述の通り、三角関数を利用すれば、直角三角形における「直角以外の角度1つ」と「辺の長さ1つ」さえ分かっていれば他の辺の長さを求めることが出来ます。
角度 θ
と距離 r
に関しては、キャラクターをどのように移動させたいかによってあなた自身が決めることが出来ますので、直角三角形における「直角以外の角度1つ」と「辺の長さ1つ」は既に分かっているものとなります。
そのため、直角三角形における底辺の長さとなる a
と高さとなる b
の2つは三角関数を用いて求めることができることになります。
具体的には、先ほども登場した下記の式により求めることが出来ます。
a
=r
*cosθ
b
=r
*sinθ
したがって、座標 (x1
, y1
) にいるキャラクターを角度 θ
の方向に距離 r
だけ移動させるためには、キャラクターを (x1
+ r
* cosθ
, y1
+ r
*sinθ
) に移動させれば良いことになります。
こんな感じで、斜辺の角度と長さから x
座標の長さおよび y
座標の長さを求める際には三角関数が活躍します。
三角関数が活躍する場面
三角関数のおさらいが済んだところで、次は三角関数が実際に活躍する場面を紹介していきます!
特定の方向に弾を発射する
前述でも少し触れましたが、三角関数をよく使う例はキャラクターや物体の移動時です。
まずはキャラクターに特定の方向に弾を発射させる例について考えてみましょう!アクションゲームやシューティングゲームで活用できそうな動作ですね!
このような動作は、三角関数の便利なところ で紹介したキャラクターの斜め方向の移動とほぼ同じ計算により実現することが出来ます。キャラクターではなく弾を移動させるようにし、さらにその移動を一定間隔で繰り返し行えば良いだけです。
弾を角度 θ
の方向に距離 r
移動させる処理は、下の図のように、現在の弾の座標から x
座標に対して dx
、y
座標に dy
を加算することで実現することが出来ます。
また、上の図より青で色をつけた部分は直角三角形となっていますので、cosθ
は dx
/ r
、sinθ
は dy
/ r
によって求まることになります。
そのため、結局 dx
と dy
は下記の式によって求めることができることになります。
dx
=r
*cosθ
dy
=r
*sinθ
つまり、dx
と dy
を上記の式から求め、求めた dx
を弾が存在する位置の x
座標に、求めた dy
を弾が存在する位置の y
座標にそれぞれ加算することで、弾を角度 θ
の方向に距離 r
だけ移動することが出来ます。
さらに、この加算を一定間隔で定期的に実行すれば、弾がどんどん角度 θ
の方向に移動していくことになりますね!
あとは、最初に弾が存在する位置をキャラクターの座標としてやれば、キャラクターから弾が発射したように表現することが出来ます。
ここまで解説してきた内容をプログラムっぽく書けば、下記の関数 move
のようになります。
move
を一回実行すれば、角度 θ
の方向に弾が距離 r
だけ移動します。そして、これを定期的に繰り返し実行するようにすれば、キャラクターから球がどんどん離れていき、弾を発射したように見せることが出来ます。
関数 move:
x を r * cosθ 増加
y を r * sinθ 増加
座標 (x, y) に弾を移動
また、下記のように距離 r
を増加させていくことでも同様の動作を実現することが出来ます。
関数 move:
r を一定量増加
x = r * cosθ
y = r * sinθ
座標 (x, y) に弾を移動
前述の通り、キャラクターから弾を発射するように表現する場合は、x
と y
は事前にキャラクターが存在する位置の座標に初期化しておく必要があります。
実際にプログラミングする際は、cos
関数や sin
関数に与える角度の単位はラジアンであったり、y
軸の正方向が下方向であったりする場合もあるので注意してください
スポンサーリンク
キャラクターに円上を回転させる
次は円上を回転するキャラクターを実現することを考えてみましょう!アクションゲームの敵キャラの動きに活用できそうですね!
このようなキャラクターの移動に関しても 三角関数の便利なところ で紹介した計算を利用することで実現可能です。
例えば、下の図のようにキャラクターが存在する位置の座標を (x
, y
)、円の中心座標を (0
, 0
)、座標 (0
, 0
) から座標 (x
, y
) を結ぶ直線と x
軸とが正方向になす角の角度を θ
、さらに座標 (0
, 0
) から座標 (x
, y
) を結ぶ直線の長さを r
としましょう。
この時、座標 (0
, 0
) から座標 (x
, y
) を結ぶ直線の長さが常に r
となるように x
と y
を移動させていけば、キャラクターは常に円上に存在することになります。これは、円上の点の座標は全て、円の中心からの距離が等しいからです。
ですので、上の図において r
を固定したまま θ
を少しずつ変化させ、それに伴いキャラクターを移動させていけば、円上を回転するキャラクターを実現することが出来ます。
ただし、座標としては x
座標と y
座標が必要になりますし、角度 θ
に応じてこれらの座標は変化しますので、θ
が変化する度に x
座標と y
座標の計算および座標 (x
, y
) へのキャラクターの移動が必要になります。
で、この x
座標と y
座標を計算する際に三角関数を利用します!
上の図における青で色をつけた部分は直角三角形になっていますので、三角関数の便利なところ でも紹介した下記の計算式により x
座標と y
座標を求めることが出来ます。
x
=r
*cosθ
y
=r
*sinθ
あとは、一定間隔に定期的に θ
を変化させて上式で x
座標と y
座標を求め、その座標にキャラクターを移動させていくことで、円上を回るキャラクターが実現できます。
ここまで解説してきた内容をプログラムっぽく書けば、下記の関数 move
のようになります。move
を一回実行すればキャラクターが 10
度分だけ回転し、これを定期的に繰り返し実行するようにすれば、キャラクターに円上を回転させることができるようになります。
関数 move:
角度 θ を 10 増加
x = r * cosθ
y = r * sinθ
座標 (x, y) にキャラクターの画像を移動
既にお気づきかもしれませんが、キャラクターに円上を回転させる動作の実現にも、前述の 特定の方向に弾を発射する で紹介した動作の実現にも下記の式を利用しています。
r
*cosθ
r
*sinθ
今回のキャラクターに円上を回転させる動作は、角度 θ
を定期的に増加させることで実現しました。このように、上式において r
を固定したまま θ
を変化させることで、原点からの距離を保ったまま角度だけ移動した位置にキャラクター等を移動させるようなことが出来ます。
また 特定の方向に弾を発射する のように、上式において θ
を固定したまま r
を変化させることで、特定の方向に向かってキャラクターを移動させるようなことが出来ます。
r
と θ
両方をうまく変化させれば、いろんな方向に弾を発射するような動作や、螺旋状にキャラクターが移動するような動作も実現可能です。
また、今回は円上を回転させるために角度 θ
の変化に伴いキャラクターの x
座標と y
座標の両方を変化させましたが、y
座標を変化させずに固定した場合は下のアニメのようにキャラクターが水平方向にのみ動作するようになります。
単に等間隔でキャラクターが移動するのではなく、キャラクターが端付近に近づいた時に移動速度が遅くなり、感覚的に自然にキャラクターが向きを切り替えるような動作が実現できます(GIF アニメ化しているのでちょっと分かりにくいですが…)。
こんな感じで、キャラクターや物体の様々な動作を実現する際にも結構便利な式なので、上式および 、x
座標 は r
* cosθ
を利用して表せること、y
座標 は r
* sinθ
を利用して表せることは覚えておくと良いと思います!
マウスカーソルを追いかける
次は、キャラクターをマウスカーソルが存在する方向に移動させる処理の実現について考えてみましょう!
基本は 特定の方向に弾を発射する と同様に、x
座標を r
* cosθ
、y
座標を r
* sinθ
だけ定期的に増加させていくことで、キャラクターを角度 θ
方向に距離 r
ずつ移動させることが出来ます。
ただし、今回はキャラクターをマウスカーソルの方向に移動させる必要があります。つまり、キャラクターの位置の座標とマウスカーソルが存在する位置の座標から θ
を求め、その θ
を用いて上記のようにキャラクターを移動させる必要があります。
このように角度を求めるときに便利なのが、tan
の逆関数である atan
(より具体的に言えば atan2
)です。
tan
は角度 θ
から直角三角形の斜辺の傾き、すなわち 高さ / 底辺の長さ
を求める三角関数になります。
逆に atan
では「斜辺の傾き」から斜辺と底辺とがなす角の角度 θ
を求めることが出来ます(三角関数には逆関数が存在し、atan
は tan
に対する逆関数となります)。
さらに、atan2
では「座標」から角度 θ
を求める関数になります。
この atan
と atan2
の違いは下記のページで解説していますので、詳しく知りたい方は下記ページを参照しただければと思います(C言語向けのページですが、他の言語を学んでおられる方でも atan
と atan2
の違いについては理解できると思います)。
atan2
では座標から角度 θ
を求めることが出来ますので、キャラクターから見たマウスカーソルの座標 (x1
, y1
) を求め、さらに (x1
, y1
) を atan2
に与えれば、キャラクターから見たマウスカーソルの方向(角度 θ
)を求めることが出来ます。
あとは、この求めた角度 θ
を用いて 特定の方向に弾を発射する と同様にキャラクターの座標を変化させれば、マウスカーソルの方向にキャラクターが移動する動作を実現することが出来ます。
ただし、この角度 θ
はマウスカーソルの位置に応じて変化させる必要がありますので、マウスカーソルの位置が変化したときに毎回角度 θ
を atan2
で求める必要があります。
ここまで解説してきた内容をプログラムっぽく書けば、下記の関数 motion
および move
のようになります。座標 (x
, y
) にキャラクターが存在することを想定した作りの関数になっています。
また、関数 motion
はキャラクターから見たマウスカーソルの方向 θ
を求める関数であり、マウスカーソルが移動するたびに実行されることを想定しています。
さらに、関数 move
を一回実行すればキャラクターが角度 θ
の方向に距離 r
だけ移動し、これを定期的に繰り返し実行するようにすればキャラクターがマウスカーソルを追いかける形で移動することになります。
関数 motion:
x1 = マウスカーソルのx座標 - x
y1 = マウスカーソルのy座標 - y
θ = atan2(y1, x1)
関数 move:
x を r * cosθ 増加
y を r * sinθ 増加
座標 (x, y) にキャラクターを移動
座標から角度を求めたいということは結構多いです。そのような状況になった際には、まず atan2
の利用を検討してみましょう!おそらくほとんどのプログラミング言語で用意されている関数になると思います。
はっきりいって atan2
はめちゃめちゃ便利な関数です。
画像を回転させる
ここまで特にゲーム開発で使いそうなユースケースにおいて三角関数が活躍する場面を紹介してきましたが、画像を扱う場合にも三角関数は活躍します。
例えば画像を回転させる場合にも三角関数が活躍します。
画像は色の付いた点の集まりであり、この点のことを画素と呼びます。1つ1つの画素は小さいですが、さまざまな色の画素が大量に集まることで、絵などの画像を表現することが出来ます。
で、画像の座標 (x
, y
) の画素を下記の演算において求まる (X
, Y
) の位置に移動させれば、
X
=x
*cosθ
–y
*sinθ
Y
=x
*sinθ
+y
*sinθ
その画素が角度 θ
だけ回転した位置に移動することになります。
ですので、この画素の移動を画像の全ての座標の画素に対して繰り返し行えば、画像全体が角度 θ
だけ回転することになります。
普段何気なく画像の回転を行なっているかもしれませんが、実はこの画像の回転でも三角関数が活躍しています。
また、回転だけでなく、三角関数を利用することで下の図のように画像を歪ませるようなことも可能です(剪断・スキュー)。
スポンサーリンク
三角関数はプログラミングで必須か?
ここまで紹介してきたように、三角関数はプログラムやアプリの中の様々な場面で活躍してくれています。
割と皆さんが体験したことのあるような動作や利用したことのある機能を例にして紹介をしてきたので、三角関数をちょっと身近に感じていただけたのではないかなぁと思います。
今回はゲームと画像に関するものばかりを、さらに凄く簡単な例のみを示してきましたが、もっともっと多くのプログラムやアプリで三角関数は活用されています。
では、プログラミングを行う上で三角関数の知識や利用が必須になるかというと、別にそういうわけではありません。
三角関数が不要なケース
分野として三角関数を扱わないような機能や製品などのプログラムを作成するのであれば三角関数を利用することもないですし、実際私は仕事で三角関数を使ったプログラミングをしたことはないです。
さらに、今回例に挙げたゲームや画像等を扱うプログラムやアプリを開発するプログラマーになった場合であっても、おそらく三角関数を使わない人も多いんじゃなかなぁと思います。
例えばですが、画像を回転させるプログラムやアプリを作成したことのある人はそれなりに多いと思うのですが、その時に 画像を回転させる で紹介したように三角関数を利用して画像の回転を実現させた経験のある人って少ないんじゃないかなぁと思うんですよね。
なぜかというと、画像を回転させる機能が既にライブラリとして用意されていることが多いからです。例えば Python であれば PIL の rotate
メソッドを利用すれば、角度のパラメータさえメソッドに与えてやれば sin
や cos
なんか使わなくても画像の回転が実現できてしまいます。
同様にゲームに関しても、ゲームエンジンやライブラリが充実していますので、わざわざ三角関数を利用しなくてもキャラクターの様々な動作が実現できるようになっていると思います(私はほぼゲームエンジン使ったことないので想像になってしまいますが…)。
なので、結局ゲームエンジンやライブラリを “使用する側” の立場のプログラマーであれば、三角関数を実際に使用する機会は少ない可能性は高いと思います。そのため、たとえゲームや画像を扱うプログラムの開発者であっても三角関数が必須でない場合が多いと思います(知識を持っていることは望まれるとは思いますが…)。
三角関数が必須のケース
ただ、ゲームエンジンやライブラリ側を “開発する側” の立場のプログラマーであれば、三角関数を始めとする数学の知識が要求され、実際に三角関数を使用しながらプログラミングする機会は多いと思います。もちろん今回紹介したような簡単な使い方ではなく、もっと高度な使い方も要求されると思います。
例えば、既存のゲームエンジンに足りない機能を実現したい場合(例えば今までにないキャラクターの動作を実現したいような場合)、ゲームエンジン側をカスタマイズ or ゲームエンジンに頼らずにそのキャラクラーの動作を実現する必要があります。そんな時には三角関数を使うことが必須になるかもしれないですね!
ですので、結局三角関数が必須であるかどうかは、どんな分野の製品やアプリの開発に携わるか、どのモジュールの開発を担当するかに依存します。
まぁでも、三角関数を始めとする数学の知識、例えば統計や線形代数などの知識があるとプログラミングで実現できることが大幅に広がるので、個人的にはこれらは知っておいて損はないとは思います!
スポンサーリンク
プログラミングと一緒だと三角関数も楽しく学べる
また、ゲームエンジンやライブラリ側の開発を行いたいけど三角関数は苦手という人もおられるかもしれません。
でも大丈夫です!たとえ三角関数が苦手だという人であっても、プログラミングと一緒に復習したら三角関数も楽しく学べます。
数学で学んだ時は、どちらかというと用途も分からずに公式等を頭に詰め込んだだけという方も多いのではないでしょうか?もしかしたら最近はそうでもないかもしれないですが、少なくとも私が三角関数を学んだときはテストで点を取るためだけに学んでいるという印象が強かったです。それだけが原因ではないですが、とりあえず私は三角関数好きじゃなかったですし、苦手でしたね…。
ただ、プログラミングの中で三角関数を利用してみれば、三角関数の実用性や三角関数で実現できることを実感しながら三角関数を学ぶことが出来ます。三角関数を使いこなしてる感があって充実感もありますし、今回紹介したゲームや画像に対して三角関数を利用した処理を実現すれば三角関数の効果を視覚的に確認しながら楽しく三角関数を学べます。
なので、今はもしかしたら三角関数は苦手かもしれないですが、プログラミングと一緒に学ぶことで三角関数が好きになる・得意になる可能性は十分あります。
もしこのページを読んで三角関数に興味を持ってくださった方がいるのであれば、今回紹介したようなゲームでのキャラクターの移動や画像の変形等に挑戦してみても良いと思いますし、まだ興味が持てなかったとしても、実際に三角関数が必要になった際に苦手意識を捨てて三角関数を学ぶことに挑戦してみていただければ良いと思います!
ちなみに、私個人としては単に数式を解いて答えを出すだけではなく、三角関数が活躍する場面 で紹介したような視覚的に動作が確認できるようなゲームや画像で三角関数を利用したプログラミングの実践をすることをオススメします。おそらくこっちの方が楽しく学べると思います。
三角関数が活躍する場面 の中でアニメーションで紹介したものは全て、Python の tkinter を利用して作成したアプリのものであり、tkinter を利用すれば画像や図形等を実際に動かして動作を視覚的に確認するようなことが簡単に実現できます。
例えば、私のサイトでは下記のように三角関数を利用して作成したアプリのサンプルも紹介していますので、これらを真似て作ってみるだけでも三角関数の実践ができると思います。
【Python/tkinter】マウスカーソルを追いかけるキャラクターを実現 【Python/tkinter】ブロック崩しゲームの作り方 【Python/tkinter】アナログ時計の作り方 【Python/tkinter】惑星の周りを衛星に回転させてキャンバスの”奥行き”の重要性を理解する 【Python/tkinter】”目” をマウスカーソルの方向に移動させるアプリの作り方おそらく、ここまで記事を読み進めていただいた方であれば、各ページの最初に紹介しているアニメーションやページの題名、アイキャッチ画像等を見れば、どのように三角関数を利用すれば各アプリが実現できるかの予想はつくのではないかと思います。
また、tkinter の使い方についても tkinter の使い方 で紹介をしています。興味のある方は是非この辺りのページも参考にしていただければと思います。もちろん、Python や tkinter にこだわる必要はないですが、視覚的に動作が確認できる方がプログラミングを学ぶのは楽しいと思いますので、そういったライブラリを活用することをお勧めします!
まとめ
このページでは、三角関数が活躍する場面を例に「プログラミングにおける三角関数の重要性」について解説しました!
割と身近なアプリやゲームでも三角関数が利用されていることが伝わったのではないかと思います。
実際にキャラクターを移動させるようなゲームを自身で作ってみると三角関数が必要になることも多く、三角関数の重要性も実感できると思います。また、実際に三角関数の効果を視覚的に確認しながら楽しく三角関数についても学べる(復習できる)ので、三角関数について学びたい方は簡単なゲームを実際にプログラムで作ってみるのがオススメです。
特に角度から座標を算出したり、座標から角度算出したりする必要のある場合は、まず三角関数や逆三角関数で算出できないかどうかを検討してみると良いと思います!
ゲームの仕組みを知りたい方にオススメの書籍(PR)
また、今回紹介したような例だけでなく、ゲームの中でのキャラクター等の動作の実現方法を知りたい方は下記の「Pythonでつくるゲームプログラミング入門」がオススメです。
みなさんがゲームプレイ時に実際に体験したゲームの動作がどんな演算や処理によって実現されているかを知ることが出来ます。
今回紹介した「弾の発射」や「キャラクターの移動」だけでなく、「衝突判定」や「キャラクターのジャンプ」などの動作を実現する仕組みについて知ることができます。もちろんこのページで紹介したような三角関数を利用した動作についても紹介されています。
Python で Pyglet を利用したサンプルプログラムも紹介されており、実際に動きを確認しながら演算や処理の効果を視覚的に確認できるのでオススメです(ただ Python 入門書というわけではないので注意してください)。
数学を学びたい人にオススメの本(PR)
また、プログラミングのために数学を学びたいという方には下記の「プログラミングのための数学」がオススメです!
「数学」をプログラミングで実際に体験しながら学んでいくことが出来ます!
単に数式を眺めたり、数式を解いたりするよりも、その数式の意味をプログラムの動作で理解しながら学習を進めることができるので、より深く数学について学べます。
プログラミング言語としては Python が使用されているので、ある程度 Python を使ったことのある人に特にオススメです。ライブラリ等の使い方も解説されていますので、Python の学習と数学の復習を両方同時に進めていくこともできます。