はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX スクリーン座標

数学が苦手なはかせです。

昔から数学系って公式とかは割とすぐわかるんですけど
実際に使おうとするとわからなくなるんですよね・・
応用力ってのが足りないってことなんでしょうね。

今回は画面外を検出したいと思い、スクリーン座標を取ろうとした話です。
スクリーン座標が取れれば画面内か外か判断できるので。

ただ数学が苦手な私にとって行列計算と実際にそれを使って
座標を求めるのが大変難しかったです。
なので今回はそれだけ書きます。

行列計算の話

まずは行列計算の公式です
↓①
f:id:hakase0274:20181104200806p:plain

見る限り素直に縦と横の対応する要素の積の総和を求めるっぽいです。
では次に実際に私が計算したいなと思った行列計算の式に近いものです。
↓②
f:id:hakase0274:20181104203231p:plain

・・・うんわからんw(第一印象)
なんで数学ってこうパッと見てわかりづらいんですかね

なにやらこうなった時は以下のルールがあるそうです
①左の列数と右の行数が同じでなければ計算できない
②左の行が右の列に対応する
③計算結果は左行の右列の行列になる

今回の例だと
①左が2行4列、右が4行1列ということで計算可能です
abcdxyztに、efghxyztに対応します
(自分はここを理解するのに大分時間がかかりました)
③結果は2行1列になります

この計算のルールと結果を理解するためだけに
また土日の2日間を丸々潰しました。

ネットで調べたら情報自体はたくさん出るのですが
自分が計算したかった②の例や計算方法が
分かりやすく説明されているサイトが中々見つからず
(というか見つけられず)

実際に値を入れて計算して間違ってを繰り返して
やっとこんなかなとなりました。

私の場合は幸いなことに渡す値と出てくる値の両方が分かっていたため
上記の方法で勉強できましたがどちらかがわかってない状態で
勉強していたらと思うとぞっとしますw

実際にスクリーン座標に変換してみる

↓スクリーン座標に変換する行列
f:id:hakase0274:20181104202852p:plain
どうやらこの行列に座標(x,y,z,w)をかけると
スクリーン座標に変換できるそうです。

DirectX11的に画面上の座標は中心を(0,0)とし
左上が(-1,1)、右下が(1,-1)らしいです。

それに対してスクリーン座標では左上は(0,0)
右下は(ウィンドウ横幅,ウィンドウ縦幅)
今回はウィンドウ横幅が1920、
ウィンドウ縦幅が1080なので(1920,1080)になります。

あとはDirectX的画面上の座標を渡し
対応するスクリーン座標が出てくるよう計算するだけです。

ちなみにDirectXにはXMVector3Transformっていう
ベクトルと行列をかけてベクトル返してくれるっていう
素敵関数があり実際にこの計算を自前で書くことはありませんでした(ノД`)シクシク

今回作ったものはgithubに上げました
https://github.com/hakase0724/DirectX/tree/Shooting