プチメタ3.0

刺激を受けた物事に対する感想や考察、資産運用や英語学習、自己成長に関することなど。


ベクトルの内積を使って角度を求める仕組み


ゲーム中に出てくる判定や敵AIの処理では
角度の情報が必要になることが多い。


2Dゲームの場合は回転方向が左右しかないので
タンジェントを利用するだけでなんとかなるが、
3Dゲームの場合は横にも縦にも回転できるので
ベクトルの内積を利用する必要が出てくる。


3Dゲーム開発をする上で内積は避けられないため、
早い段階で理解してしまう方がいい。

ベクトルの内積とは

内積の計算には必ず2本のベクトルが関係するので、
ここでは3つの座標のうち2つを結ぶベクトルを考える。



点Aと点Bを結ぶベクトルを \vec{AB}
点Aと点Cを結ぶベクトルを \vec{AC} と表現し、
2本のベクトルの向きは46度ズレているとする。


\vec{AB} を求めるには座標Bから座標Aを引き算するだけでいい。
2ヶ所の座標を引き算すると
 その2点を結ぶベクトルが手に入る

というのはベクトル計算の基本だ。


内積というのは2本のベクトルから求めたひとつの値を指し、
\vec{AB}\vec{AC} の内積は \vec{AB}\cdot\vec{AC} と表現するが、
この求め方に2種類あるのがミソだ。

内積の計算方法その1

ひとつがベクトルの長さとコサインを利用する方法だ。


  \displaystyle\vec{AB}\cdot\vec{AC}=|\vec{AB}||\vec{AC}|cos\theta


|\vec{AB}|\vec{AB} の長さを表しているので、
上記の式は「 \vec{AB} の長さ」と「 \vec{AC} の長さ」と「コサインθ」を
すべて掛け合わせた値を求めていることになる。




ベクトルの長さ三平方の定理で求められるので、この図でいえば


  \displaystyle\begin{align}|\vec{AB}|&=\sqrt{(5-3)^2+(17-10)^2+(6-4)^2}\\&=\sqrt{2^2+7^2+2^2}\\&=\sqrt{57}\end{align}


  \displaystyle\begin{align}|\vec{AC}|&=\sqrt{(7-3)^2+(12-10)^2+(5-4)^2}\\&=\sqrt{4^2+2^2+1^2}\\&=\sqrt{21}\end{align}


となり、コサイン46度は約0.694なので、
それらを踏まえて計算すると


  \displaystyle\begin{align}\vec{AB}\cdot\vec{AC}&=|\vec{AB}||\vec{AC}|cos46^\circ\\&=\sqrt{57}\times\sqrt{21}\times\ 0.694\\&=24\end{align}


となる。

内積の計算方法その2

もうひとつがベクトルの成分を使う方法だ。


\vec{AB} の成分を (AB_1,\ AB_2,\ AB_3)
\vec{AC} の成分を (AC_1,\ AC_2,\ AC_3) と表現すると、


  \displaystyle\vec{AB}\cdot\vec{AC}=AB_1\ AC_1+AB_2\ AC_2+AB_3\ AC_3


という計算で内積を求めることができる。



ベクトルの成分というのはXYZ方向それぞれの長さであり、
終点から始点を引き算すればいいので、この図でいえば


  \displaystyle\begin{align}\vec{AB}&=(5-3,\ 17-10,\ 6-4)\\&=(2, 7, 2)\end{align}


  \displaystyle\begin{align}\vec{AC}&=(7-3,\ 12-10,\ 5-4)\\&=(4, 2, 1)\end{align}


となるので、これを踏まえて計算すると


  \displaystyle\begin{align}\vec{AB}\cdot\vec{AC}&=2\times\ 4+7\times\ 2+2\times\ 1\\&=24\end{align}


となり、もう一方の計算方法で求めた値と同じ結果になる。

内積の値から角度を求める

さて、内積をうまく利用すると
2本のベクトルの間の角度を求めることができる。


先ほどは角度の値を添えていたが、
実際にはその情報がわからないことが多く、
そこを内積を利用して求めていくのだ。


一旦、内積を求める2つの計算方法を並べてみる。


  \displaystyle\vec{AB}\cdot\vec{AC}=|\vec{AB}||\vec{AC}|cos\theta
  \displaystyle\vec{AB}\cdot\vec{AC}=AB_1\ AC_1+AB_2\ AC_2+AB_3\ AC_3


どちらの計算方法でも同じ値が求まるわけだが、
1つ目の式はベクトルの長さとコサイン値、
2つ目の式はベクトルの成分が必要になる。


ベクトルの成分というのは要するに座標であり、
ゲームプログラムでは必ず保持している情報だ。
つまり、2つ目の式ならいつでも計算できる。
それに対して角度がわからない状況では1つ目の式は使えない。


しかし AB_1\ AC_1+AB_2\ AC_2+AB_3\ AC_3 の計算で求めた内積は
|\vec{AB}||\vec{AC}|cos\theta と同じ値なわけだから、角度がわからなくても
\vec{AB} の長さ」と「 \vec{AC} の長さ」と「コサインθ」を
掛け合わせた値を求めることができるということだ。


しかし3つの値を掛け合わせた計算結果から
ひとつの要素だけを取り出すことはできない。
6\times\ 4\times\ 5 の合計が 120 だと計算するのは簡単だが、
120 という値から 65 という値を導き出すのは無理だろう。


つまり |\vec{AB}| \times\ |\vec{AC}| \times\ cos\theta の合計がわかっても
そこから角度 \theta を取り出すことはできない。
すべての原因は3つの要素が混ざっているためだ。


そこで |\vec{AB}||\vec{AC}|1 にすることを考える。


ベクトルの向きを変えずに
長さを1にすることを「正規化(せいきか)」と呼ぶが、
ベクトル成分を長さで割るだけで実現できる。
\vec{AB} を正規化したものは \hat{AB} と表現する。


  \displaystyle\hat{AB}=\dfrac{\vec{AB}}{|\vec{AB}|}=\dfrac{(2,\ 7,\ 2)}{\sqrt{57}}=(0.264,\ 0.927,\ 0.264)


  \displaystyle\hat{AC}=\dfrac{\vec{AC}}{|\vec{AC}|}=\dfrac{(4,\ 2,\ 1)}{\sqrt{21}}=(0.872,\ 0.436,\ 0.218)



内積を求める式は


  \displaystyle\vec{AB}\cdot\vec{AC}=|\vec{AB}||\vec{AC}|cos\theta


だったので、 \hat{AB}\hat{AC} の内積は


  \displaystyle\hat{AB}\cdot\hat{AC}=|\hat{AB}||\hat{AC}|cos\theta


となるはずだが、正規化しているため |\hat{AB}||\hat{AC}|1 なので、


  \displaystyle\hat{AB}\cdot\hat{AC}=|\hat{AB}||\hat{AC}|cos\theta=1\times\ 1\times\ cos\theta=cos\theta


となる。
つまり、内積を計算する前に2本のベクトルを正規化しておけば
内積=コサイン値になるわけだ。


角度からコサイン値を求める場合はコサイン関数を使うが、
コサイン値から角度を求める場合は
コサインの逆関数であるアークコサインを使う。


 \displaystyle\theta=arccos(\hat{AB}\cdot\hat{AC})


これが内積を使って角度を割り出す仕組みだ。


実際のプログラムではベクトルの正規化も内積の計算も
アークコサインも専用の関数が用意されているので、
自分で計算する必要はまずない。

2本のベクトルを見出せれば角度がわかる


内積を使って角度を求める仕組みさえわかれば
あとは自分が欲しい角度を挟む2本のベクトルを
きちんと見出せるかどうかにかかっている。


敵が攻撃する角度、旋回する方向、画面に表示する方角など
3Dゲームを構成するあらゆる場面で内積が役に立つし、
早めに理解して苦手意識をなくした方が武器になる。



mclover.hateblo.jp

mclover.hateblo.jp

mclover.hateblo.jp

mclover.hateblo.jp

バスケ部がランニングでやってた謎の掛け声


私の中学のバスケットボール部は
ウォーミングアップのランニングのときに
謎の掛け声をする慣習があった。


キャプテンが「イ~チ、ニ~、イチ、ニ、」と呼びかけると
後ろの部員全員が「ワッショイ!!」と両腕を上げて応じるのだ。


最初に見たときは「バスケ部は変なことやってるなー」と思ったが、
走りながら声を出して両腕まで上げるのはかなりキツそうだったので、
トレーニングという意味では一定の効果があったのかもしれない。

会社員の時給を求める計算フォームを作ってみた


年収:万円


労働時間:時間 / 日 平均残業時間:時間 / 月


年間休日:
 土日 祝日 有給休暇日 / 年


時給:


アルバイトを選ぶときは当たり前のように時給を気にするのに
月給制の会社員になるとあまり意識することがなくなってしまう。


しかし、ある作業が割に合っているのかを判断するには
自分の時給を知っておく必要がある。
1年間の収入を休日を差し引いた労働時間で割れば
自分が1時間あたりに稼いでいる金額がわかる。


これを見ると普通の会社員になるだけで
一般的なアルバイトを大きく上回る稼ぎになることがわかる。
就活が面倒だからとフリーターを目指すのは
あまりいい選択とは言えないだろう。


また、数百円の得になるからといって作業に30分もかけてしまうと
自分の時給を下回って結果的に損をしていることになる。
社内で大勢の人間を集めて開いた1時間の会議は
それぞれの時給を合計しただけのコストがかかっているということだ。


時間の価値を実感する意味でも
一度、時給で考えてみるといいだろう。



mclover.hateblo.jp

詩がうまく書けない思いをそのままゲーム化した作品が斬新


sunsetdandan.itch.io


詩が書けない悩みがそのままゲームに仕上げた
詩が書けなかった日」が斬新。


日本語のちょっとした表現が
そのまま具現化されたステージになっていて
文章を読みながらプレイするアクションゲームになっている。
ブラウザ上でそのまま遊べる手軽さもいい。
(Wキーもジャンプ操作なので両手プレイに便利)


死んだときに結構戻されてしまうのが残念だが、
数分間でクリアできるボリュームなので
何度かチャレンジしてがんばってみて欲しい。

総アクセス数