# 3D 碰撞检测

## Axis-aligned bounding boxes（AABB包围盒）

Note: 参考这里使用Three.js进行边界体积碰撞检测。

### 点与 AABB

$f\left(P,B\right)= \left(P_x >= B_\left\{minX\right\} \wedge P_x <= B_\left\{maxX\right\}\right) \wedge \left(P_y >= B_\left\{minY\right\} \wedge P_y <= B_\left\{maxY\right\}\right) \wedge \left(P_z >= B_\left\{minZ\right\} \wedge P_z <= B_\left\{maxZ\right\}\right)$

function isPointInsideAABB(point, box) {
return (point.x >= box.minX && point.x <= box.maxX) &&
(point.y >= box.minY && point.y <= box.maxY) &&
(point.z >= box.minY && point.z <= box.maxZ);
}

### AABB 与 AABB

$f\left(A,B\right) =$

function intersect(a, b) {
return (a.minX <= b.maxX && a.maxX >= b.minX) &&
(a.minY <= b.maxY && a.maxY >= b.minY) &&
(a.minZ <= b.maxZ && a.maxZ >= b.minZ);
}


## 球体碰撞

### 点与球

$\sqrt\left\{\left(A_x - B_x\right) ^ 2\right) + \left(A_y - B_y\right)^2 + \left(A_z - B_z\right)\right\}$ ,我们的公式指出，球体碰撞检测是:

$f\left(P,S\right) = S_\left\{radius\right\} >= \sqrt\left\{\left(P_x - S_x\right)^2 + \left(P_y - S_y\right)^2 + \left(P_z - S_z\right)^2\right\}$

function isPointInsideSphere(point, sphere) {
// we are using multiplications because is faster than calling Math.pow
var distance = Math.sqrt((point.x - sphere.x) * (point.x - sphere.x) +
(point.y - sphere.y) * (point.y - sphere.y) +
(point.z - sphere.z) * (point.z - sphere.z));
}


### 球体与球体

$f\left(A,B\right) = \sqrt\left\{\left(A_x - B_x\right)^2 + \left(A_y - B_y\right)^2 + \left(A_z - B_z\right)^2\right\} <= A_\left\{radius\right\} + B_\left\{radius\right\}$

function intersect(sphere, other) {
// we are using multiplications because it's faster than calling Math.pow
var distance = Math.sqrt((sphere.x - other.x) * (sphere.x - other.x) +
(sphere.y - other.y) * (sphere.y - other.y) +
(sphere.z - other.z) * (sphere.z - other.z));
}

### 球体与AABB

function intersect(sphere, box) {
// get box closest point to sphere center by clamping
var x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
var y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));

// this is the same as isPointInsideSphere
var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) +
(y - sphere.y) * (y - sphere.y) +
(z - sphere.z) * (z - sphere.z));

}



## 使用一个物理引擎

3D physics engines provide collision detection algorithms, most of them based on bounding volumes as well. The way a physics engine works is by creating a physical body, usually attached to a visual representation of it. This body has properties such as velocity, position, rotation, torque, etc., and also a physical shape. This shape is the one that is considered in the collision detection calculations.

We have prepared a live collision detection demo (with source code) that you can take a look at to see such techniques in action — this uses the open-source 3D physics engine cannon.js.

Related articles on MDN:

External resources: