【ゲーム数学】第二回 p5.jsで学ぶゲーム数学「三角関数」

スポンサーリンク
PC創作
マイケル
マイケル
みなさんこんばんは!
マイケルです!
エレキベア
エレキベア
クマ〜〜〜〜
マイケル
マイケル
今日も前回に引き続いてゲーム数学シリーズを進めるよ!
エレキベア
エレキベア
勉強はこりごりクマ〜〜〜
やりたくないクマ〜〜〜〜
マイケル
マイケル
第二回は「三角関数」!!
まだまだ基礎の基礎ですが張り切っていきましょう!
エレキベア
エレキベア
(完全スルークマ・・・。)
スポンサーリンク

参考書籍と開発言語

マイケル
マイケル
勉強にするにあたっては前回同様、下記参考書を参考にしました!

ゲームを動かす数学・物理 R

グラフィックスプログラミング入門

マイケル
マイケル
どちらも高校数学の基礎から解説しているため、しばらく数学から離れている方でも読みやすいと思います!
エレキベア
エレキベア
一読してみるクマ
マイケル
マイケル
そしてサンプルプログラムの実装としては p5.js を使用しています!
気になった方はこちらも使用してみてくださいね!
Screenshot 2021 01 16 23 15 46

p5.js ダウンロードページ

エレキベア
エレキベア
グラフィックス特化のJavaScriptライブラリクマね
スポンサーリンク

三角関数

マイケル
マイケル
それでは本編に入っていきましょう!

三角関数について

マイケル
マイケル
まずは三角関数について!
sin、cos、tanは覚えているかな?
エレキベア
エレキベア
サイン・コサイン・タンジェントクマね
マイケル
マイケル
その通り!懐かしい響きだね・・・。
直角三角形がある時に、下記のように成り立つ式のことだったね!
Screenshot 2021 01 31 17 46 18↑三角関数の計算式
マイケル
マイケル
これは、座標等の位置情報を管理するゲームプログラミングでは非常によく使われるんだ!
エレキベア
エレキベア
使うことはないだろうと思ってたクマが役に立つクマね
マイケル
マイケル
具体的な使用例でいうと、
ショットを30°上方向に特定の長さだけ放つ場合とかだね!
JavaScriptでは、角度(0°〜360°)をangleとすると、下記のように使用できるよ!
sin(radians(angle));
cos(radians(angle));
tan(radians(angle));
マイケル
マイケル
度数からラジアンに変換して、メソッドに渡してあげる感じだね!
エレキベア
エレキベア
簡単クマ〜〜〜〜
マイケル
マイケル
それじゃ0°〜360°の変化で、それぞれどのように値が変わるかみてみよう!

See the Pen
0131_01
by masarito617 (@masarito617)
on CodePen.


↑三角関数の値の変化

マイケル
マイケル
見ての通り、0°や180°などX軸に近づくほどcosの値は大きくなって
90°や270°などY軸に近づくほどsinの値は大きくなっているね!
エレキベア
エレキベア
-1〜1の間で変化しているクマね
マイケル
マイケル
このことから、
cosはX方向の比、sinはY方向の比であると考えてもよさそうだね!

逆三角関数について

マイケル
マイケル
そして三角関数とは逆に、
辺の比から角度を求める関数のことを逆三角関数と言うよ!
Screenshot 2021 01 31 17 46 38↑逆三角関数の計算式
エレキベア
エレキベア
三角関数を逆にして-1を付けたクマね
マイケル
マイケル
読み方はそれぞれ
アークサイン、アークコサイン、アークタンジェント と読むよ!
プログラムでは下記のように使用します!
sin_angle = asin(y/l);
cos_angle = acos(x/l);
tan_angle = atan(y/x);
マイケル
マイケル
これも辺の比を関数に渡すだけだから、使う分には簡単だね!
下記に一例でシミュレータを作ったので触ってみてください!

See the Pen
0131_02
by masarito617 (@masarito617)
on CodePen.


↑逆三角関数の値変化(※スライダーで辺の長さを調整できます。)

エレキベア
エレキベア
簡単に角度が求められるクマ〜〜〜
arctanの活用
マイケル
マイケル
これで角度が自由に求められる・・・と言いたいところだけど、
ゲーム開発の実装では少し不便なところがあるんだ。
エレキベア
エレキベア
これで充分じゃないクマ?
マイケル
マイケル
それは、
 arcsin、arctan → -90°〜90°
 arccos → 0°〜180°
の間でしか検知できない、
つまり 360°検知ができないということなんだ!
エレキベア
エレキベア
ええ〜〜〜なんでクマ?!
マイケル
マイケル
計算結果を関数に渡しているから 各辺の正負まで判断できないんだね・・・。
エレキベア
エレキベア
一体どうすればいいクマ・・・。
マイケル
マイケル
しかしそんな時に役立つのがアークタンジェント!!
tan_angle = atan(y / x);
tan2_angle = atan2(y, x);
マイケル
マイケル
上記で使用している atan2() と言う関数にはX、Yそれぞれの値を渡すことができるから360°検知も可能なんだ!!
エレキベア
エレキベア
計算結果ではなく各辺を渡すクマね・・・。
でもなんでタンジェントだけそんな関数があるクマ??
マイケル
マイケル
例えばだけど、下記のようなキャラ同士の角度を求める場合を考えてみよう!
Screenshot 2021 01 31 17 46 49
マイケル
マイケル
この場合、カラスの座標は正負の情報を持つけど、
カラスまでの長さは正負の情報を持たない
Screenshot 2021 01 31 17 46 55
マイケル
マイケル
つまり、斜線部を使わずX、Yの座標で角度を求めることのできる
アークタンジェントだけが360°の検知が可能
ということなんだ!
エレキベア
エレキベア
目から鱗クマ・・!!
アークタンジェントなんて一生使わないと思ってたけど大活躍クマ・・・!!
マイケル
マイケル
下記にatan2()含むそれぞれの検出結果のシミュレータを作成したので、
よければ触って挙動を確かめてみてくださいね!

See the Pen
0131_03
by masarito617 (@masarito617)
on CodePen.


↑逆三角関数での角度検出結果(※マウスドラッグで座標の移動が可能)

エレキベア
エレキベア
確かにatan2()だけが-180°〜180°で360°検知できているクマ・・・!
マイケル
マイケル
感動だね・・・。

内積

マイケル
マイケル
そして最後は内積についてだ!
エレキベア
エレキベア
なんだか難しそうクマ〜〜〜
マイケル
マイケル
難しそうに聞こえるけど、計算内容はすごく簡単!
下記のように2つのベクトルがあるとき、各ベクトルを正規化して掛け合わせたものがcosθと一致する式のことなんだ!
Screenshot 2021 01 31 17 55 58↑内積の計算
マイケル
マイケル
つまり2つのベクトル情報から角度も求めることができるということだね!
プログラムでは下記のように計算するよ!
// 内積から角度を取得
angle = acos(dot(normalize(v1), normalize(v2)));

// ベクトルの正規化
function normalize(v) {
  // ベクトルの大きさで割る
  let v_l = sqrt(v.x**2 + v.y**2);
  return new Vec(v.x/v_l, v.y/v_l);
}

// ベクトルの内積
function dot(v1, v2) {
  return v1.x*v2.x + v1.y*v2.y;
}
エレキベア
エレキベア
確かに手軽だしそこまで難しくないクマね
マイケル
マイケル
一つ注意なのは、アークコサインを使用しているため0°〜180°の間でしか検知できないということ!
先ほどのtan2()関数とうまく使い分けましょう!
マイケル
マイケル
内積の計算結果のシミュレータは以下になります!

See the Pen
vYyELWj
by masarito617 (@masarito617)
on CodePen.


↑内積の計算結果(※マウスドラッグで座標の移動が可能)

エレキベア
エレキベア
これもうまく角度の検知ができているクマ〜〜〜
マイケル
マイケル
内積を使用する際は正規化するのを忘れないようにしましょう!
スポンサーリンク

おわりに

マイケル
マイケル
というわけで今回は三角関数についてでした!
どうだったかな??
エレキベア
エレキベア
現実だとなかなか使わないことを活かすことができて感動だったクマ〜〜〜〜
マイケル
マイケル
実際にプログラミングして動きを確かめながらだと中々楽しいよね!
それじゃ今後も少しずつ勉強していこう!
マイケル
マイケル
それでは今日はこの辺で!
アデュー!!
エレキベア
エレキベア
クマ〜〜〜〜〜〜

【ゲーム数学】第二回 p5.jsで学ぶゲーム数学「三角関数」 〜完〜

コメント