Simple AABB-ray collision implementation (Slab method)
This is a bounding-box/AABB ray collision detection function implemented in JS. I wrote it during my brief exploration of using JavaScript as a basis for a simple game framework, which I never finished. It makes the following assumptions:
- All input coordinates are represented in world space. Intermediate values are relative.
- The input ray is represented as two 2-dimensional points in global space: start and end.
- It is a member function of a bounding-box class with the following coordinates: x1, x2, y1, y2, hence the this voodoo keyword.
Here is the code.
raycast(start, end) {
let diff = end.subtract(start);
let tx1 = (this.x1 - start.x) / diff.x;
let tx2 = (this.x2 - start.x) / diff.x;
let tminX = Math.min(tx1, tx2);
let tmaxX = Math.max(tx1, tx2);
let ty1 = (this.y1 - start.y) / diff.y;
let ty2 = (this.y2 - start.y) / diff.y;
let tminY = Math.min(ty1, ty2);
let tmaxY = Math.max(ty1, ty2);
let tEnter = Math.max(tminX, tminY);
let tExit = Math.min(tmaxX, tmaxY);
if (tEnter > tExit || tExit < 0 || tEnter > 1) {
return null;
}
let tHit = Math.max(tEnter, 0.0);
return start.add(diff.multiply(tHit));
}
I also return the intersection position if it exists. For consistency with the inputs, it's also in global space. In addition, I use three vector-specific functions:
-
vec2.add- adds two vectors and returns the result vec2.subtract- ditto, but with subtraction-
vec2.multiply- performs scalar multiplication of a vector
I keep this implementation as reference to implement ray casting in my future 2D game engines. If you want more collision functions, you can check out this library.