# 箱(AABB)と球の当たり判定

## 箱(AABB)と球の当たり判定 by チョコミント

こんにちは、チョコミントです。  
今回は****箱(AABB)と球****の当たり判定についてです。

### AABB,OBBとは

AABBとOBBについて聞きなれてない人も多いと思うので簡単に説明します。

- AABBとは****軸平行境界ボックス****といって****箱の各面の法線が座標軸と平行****なものです。  
    箱の横と縦と奥へのベクトルそれぞれがXYZと平行ということですね。
- OBBとは****有向境界ボックス****といって****箱の各面の法線が座標軸と平行ではない****も のです。  
    なんとなく理解できたでしょうか。  
    AABBとOBBでは****当たり判定をする際の処理速度****がかなり変わってきます。  
    OBBについての当たり判定もいつか記事に書く予定です。

### AABBと点の距離

さて本題に入っていきましょう。

![画像6.png](https://bookstack.yz-learning.com/uploads/images/gallery/2025-05/scaled-1680-/6.png)

上の図にある通り、AABBと球の当たり判定を行うには****AABBと点の距離****が分かればいいのです。(図に書いてあるdです)  
AABBと点の距離を調べるには、****AABBの各軸(XYZ)で点がどのくらいAABBからはみ出ているか****を調べればいいのです。

![画像8.png](https://bookstack.yz-learning.com/uploads/images/gallery/2025-05/scaled-1680-/8.png)上の図ではAABBのX軸、Y軸で点がはみ出ている分、vx、vyでベクトルを作ってみました。  
あれこの形どこかで見たことある人いませんか??  
そうです、****点と点の距離を求めるのとそっくり****ですね。  
つまり****vx、vy、vz(図にはない3Dの場合)の合成ベクトルを求めればAABBと点の距離****になるのです！！簡単ですね！！

```c++
//AABBの各軸
    XMVECTOR boxX = { 1,0,0 };
    XMVECTOR boxY = { 0,1,0 };
    XMVECTOR boxZ = { 0,0,1 };

    //AABBの各軸の大きさ
    float boxXSize = 0.5f;
    float boxYSize = 0.5f;
    float boxZSize = 0.5f;

    //AABBの中点と点の位置
    XMFLOAT3 boxPos = { 0,0,0 };
    XMFLOAT3 pointPos = { 1,1,1 };

    //各軸での距離を調べる
    float x = fabs(boxPos.x - pointPos.x);
    float y = fabs(boxPos.y - pointPos.y);
    float z = fabs(boxPos.z - pointPos.z);
     
    //最終的な距離を表すベクトル
    XMVECTOR dis = XMVectorZero();

    //各軸のはみだし距離をdisに加算
    if(x > boxXSize)
        dis += boxX * (x - boxXSize);
    if(y > boxYSize)
        dis += boxY * (y - boxYSize);
    if(z > boxZSize)
        dis += boxZ * (z - boxZSize);

    //disの長さがAABBと点の距離
    return XMVectorGetX(XMVector3Length(dis));
```

サンプルコードです。  
ここまでくればAABBと球の当たり判定はちょこっとたすだけです！  
****AABBと点の距離が球体の半径以下だったら衝突している****ことになりますね！！

```c++
//半径以下なら
if (radius >= XMVectorGetX(XMVector3Length(dis))
{
    //衝突している
}
```

これでAABBと球の当たり判定は完璧です！

### 最後に

今回はAABBと球の当たり判定についての記事でした。  
分からないことや質問などがあれば気軽にコメント待っています！！