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.