# あいつは自分から見て右にいるの？左にいるの？

## 🌟目的

自分の向いている方向から見て、「ターゲットが右にいるのか、左にいるのか」を判断し、その方向に回転させたい。

---

## 🧭前提知識

### <span style="white-space: pre-wrap;">1. </span>`<span class="editor-theme-code">atan2(y, x)</span>`<span style="white-space: pre-wrap;"> の意味</span>

<span style="white-space: pre-wrap;">ベクトル </span>`<span class="editor-theme-code">(x, y)</span>`<span style="white-space: pre-wrap;"> の</span>****角度（ラジアン）を、原点から見たときのx軸との角度****<span style="white-space: pre-wrap;">として返します。範囲は </span>`<span class="editor-theme-code">[-π, π]</span>`。

### 2. 基準ベクトル

<span style="white-space: pre-wrap;">自分が向いている方向をベクトル </span>`<span class="editor-theme-code">forward</span>`<span style="white-space: pre-wrap;"> とし、右方向を基準にする場合は、通常 </span>`<span class="editor-theme-code">right = {1, 0}</span>`<span style="white-space: pre-wrap;"> などとします（右向き単位ベクトル）。</span>

---

## 🧮方法1：`<span class="editor-theme-code">atan2</span>`による角度の差で判断

```cpp
// 自分の向きとターゲット方向
Vec2 forward = 自分の向きベクトル;     // 例: {1, 0} → 右向き
Vec2 toTarget = targetPos - selfPos;    // 自分からターゲットへのベクトル

// それぞれの角度を求める
float angleForward = atan2(forward.y, forward.x);
float angleToTarget = atan2(toTarget.y, toTarget.x);

// 差を求める（-π〜π の範囲に自動でなる）
float delta = angleToTarget - angleForward;

// 回転方向を判断
if (delta > 0) {
    // 左にターゲットがある（左回りに回転すべき）
} else if (delta < 0) {
    // 右にターゲットがある（右回りに回転すべき）
}
```

### ✅この方法のメリット：

角度を厳密に扱える。滑らかに回転アニメーションしたいときに使いやすい。

---

## <span style="white-space: pre-wrap;">🧮方法2：右向きベクトルとの </span>****外積 or 内積****<span style="white-space: pre-wrap;"> を使って右左判定</span>

### 2Dにおける\*\*外積（cross product）\*\*で符号を利用する方法：

```cpp
float cross = forward.x * toTarget.y - forward.y * toTarget.x;
```

- `<span class="editor-theme-code">cross > 0</span>`<span style="white-space: pre-wrap;"> → 左側</span>
- `<span class="editor-theme-code">cross < 0</span>`<span style="white-space: pre-wrap;"> → 右側</span>
- `<span class="editor-theme-code">cross == 0</span>`<span style="white-space: pre-wrap;"> → 同一直線上</span>

### または、****右向きベクトルと角度比較****

<span style="white-space: pre-wrap;">基準として右向きのベクトル </span>`<span class="editor-theme-code">right = {1, 0}</span>`<span style="white-space: pre-wrap;"> を使って、ターゲットとの角度を見る：</span>

```cpp
Vec2 right = {1, 0};
float angleToTarget = atan2(toTarget.y, toTarget.x);
float angleRight = atan2(right.y, right.x); // = 0

// 結果的に angleToTarget だけ見れば良い
if (angleToTarget > 0) {
    // ターゲットは上（左回り）
} else {
    // ターゲットは下（右回り）
}
```

---

## 🎯補足：`<span class="editor-theme-code">atan2</span>`<span style="white-space: pre-wrap;"> と外積の使い分け</span>

<table id="bkmrk-%E6%96%B9%E6%B3%95%E7%89%B9%E5%BE%B4%E5%9B%9E%E8%BB%A2%E6%96%B9%E5%90%91%E5%88%A4%E5%AE%9A%E5%9B%9E%E8%BB%A2%E9%87%8F%E5%8F%96%E5%BE%97atan2"><colgroup><col></col><col></col><col></col><col></col></colgroup><tbody><tr><th>方法

</th><th>特徴

</th><th>回転方向判定

</th><th>回転量取得

</th></tr><tr><td>`<span class="editor-theme-code">atan2</span>`

<span style="white-space: pre-wrap;"> 差分</span>

</td><td>正確な角度取得。平滑回転に◎

</td><td>◎

</td><td>◎（角度そのもの）

</td></tr><tr><td>外積（2D）

</td><td>軽量。方向判定だけなら高速

</td><td>◎（符号）

</td><td>×（角度は出せない）

</td></tr></tbody></table>