Skip to main content

contain: AABB Point Containment Test

Axis-Aligned Boundary Testing for Spatial Queries

The AABB containment function determines whether a point lies within the bounds of an axis-aligned bounding box. This fundamental spatial query operation enables collision detection, spatial partitioning, and geometric filtering.

Given an AABB with bounds [bmin,bmax][\vec{b_{\min}}, \vec{b_{\max}}] and test point p\vec{p}, the containment test evaluates:

contained=(bmin,x<pxbmax,x)(bmin,y<pybmax,y)(bmin,z<pzbmax,z)\text{contained} = (b_{\min,x} < p_x \leq b_{\max,x}) \land (b_{\min,y} < p_y \leq b_{\max,y}) \land (b_{\min,z} < p_z \leq b_{\max,z})

The function uses inclusive bounds on the maximum side and exclusive bounds on the minimum side, following standard interval notation (min,max](\text{min}, \text{max}].

Boundary Conventions

The asymmetric boundary treatment prevents double-counting at shared edges when multiple AABBs tile a space:

  • Points exactly on minimum boundaries are considered outside
  • Points exactly on maximum boundaries are considered inside
  • This convention ensures consistent spatial partitioning behavior

Performance Characteristics

AABB containment testing provides optimal computational efficiency:

  • Time Complexity: O(1)O(1) constant time per query
  • Memory Access: Sequential coordinate comparison
  • Branching: Minimal conditional logic suitable for SIMD processing
Live Editor
const fragment = () => Scope(() => {
      const t = iTime.mul(0.4)
      const p = uv.mul(4).sub(2)
      const box = AABB({
              minBounds: vec3(t.sin().mul(1.5).sub(0.3), t.mul(1.2).cos().mul(1.2).sub(0.4), 0),
              maxBounds: vec3(t.mul(0.9).sin().mul(1.3).add(0.5), t.mul(0.7).cos().mul(1.1).add(0.6), 0)
      })
      const testPoint = vec3(p, 0)
      const inside = aabbContain(box, testPoint)
      const distFromCenter = length(p.sub(aabbCentroid(box).xy))
      const gradient = smoothstep(0.5, 1.5, distFromCenter)
      const baseColor = vec3(0.1, 0.2, 0.4).select(vec3(0.8, 0.4, 0.1), inside)
      const edgeX = p.x.sub(box.minBounds.x).abs()
               .min(p.x.sub(box.maxBounds.x).abs())
      const edgeY = p.y.sub(box.minBounds.y).abs()
               .min(p.y.sub(box.maxBounds.y).abs())
      const edge = edgeX.min(edgeY)
      const wireframe = smoothstep(0.02, 0.05, edge).oneMinus()
      return vec4(baseColor.mul(gradient.oneMinus().add(0.3)).add(wireframe.mul(0.6)), 1)
})