ベクトルの内積
2本の矢印の「向きの近さ」を1つの数値にする
Layer 1 — 直感・シミュレーター
上のシミュレーターで青と赤の矢印の先端をドラッグしてみよう。2本が同じ方向を向くほど内積は大きくなり、直角(90°)でちょうど0になり、反対方向を向くと負になる。まずは数式抜きで、この「向きの近さのメーター」としての感覚をつかもう。
= (3.00, 1.00) — 大きさ 3.16
= (1.00, 2.00) — 大きさ 2.24
= 5.00
= 0.71(θ ≈ 45.0°)
↑ 矢印の先端をドラッグして、2本のベクトルの向きと大きさを自由に変えてみよう。内積の値と、なす角の関係を確認できる。
Layer 2 — 定義・受験・証明
定義
2つのベクトル の内積(ドット積)は、成分計算では次のように定義される。
これは幾何的には、なす角 を使って次のようにも表せる。
この2つの式が一致することが、内積の最も重要な性質である。
公式
証明・導出
余弦定理を使うと成分表示と幾何表示が一致することを示せる。 の始点をそろえたとき、終点間の距離を とすると余弦定理より
一方で成分計算からも が導けるため、両辺を比較すると
が得られ、幾何表示と成分表示が一致することが証明される。
押さえておきたいポイント
- 内積が正 → 2つのベクトルは90°未満(似た方向)を向いている
- 内積が0 → 2つのベクトルは直交している(垂直)
- 内積が負 → 2つのベクトルは90°より開いた方向を向いている
- より、内積からなす角を逆算できる
Layer 3 — 工学応用・現場実装
ゲーム制作の視野角判定 (FOV: Field of View)
敵キャラクターが「プレイヤーが自分の視野角の中に入っているか」を判定する処理は、内積を使うと数行で書ける。敵の向きベクトルとプレイヤーへの方向ベクトルの内積からなす角の余弦を求め、視野角の半分の余弦と比較するだけでよい。平方根や三角関数を使わずに高速に判定できるのが実務上のポイント。
1type Vec2 = { x: number; y: number };23function normalize(v: Vec2): Vec2 {4 const len = Math.hypot(v.x, v.y) || 1;5 return { x: v.x / len, y: v.y / len };6}78function dot(a: Vec2, b: Vec2): number {9 return a.x * b.x + a.y * b.y;10}1112/**13 * 敵の視野角(fovDegrees, 全体角度)の中にターゲットが入っているか判定する。14 * 平方根や atan2 を避け、cos の比較だけで済ませるのがポイント。15 */16function isInFieldOfView(17 enemyPos: Vec2,18 enemyFacing: Vec2, // 正規化済みの向きベクトル19 targetPos: Vec2,20 fovDegrees: number,21): boolean {22 const toTarget = normalize({23 x: targetPos.x - enemyPos.x,24 y: targetPos.y - enemyPos.y,25 });2627 const cosTheta = dot(enemyFacing, toTarget);28 const cosHalfFov = Math.cos((fovDegrees / 2) * (Math.PI / 180));2930 // cosThetaが大きいほど「正面に近い」。しきい値以上ならFOV内。31 return cosTheta >= cosHalfFov;32}3334// 使用例: 敵は右(1,0)向き、視野角90度35const enemy = { x: 0, y: 0 };36const facing: Vec2 = { x: 1, y: 0 };37const player = { x: 5, y: 3 };3839console.log(isInFieldOfView(enemy, facing, player, 90)); // true / false