Point-in-Shape Tests

Half of all collision queries are about a single point. Is the mouse cursor over this button? Is the player standing in the lava trigger? Did this particle land inside the goal zone? The overlap tests answered "do two shapes touch?"; here we shrink one of them to a point and ask the cleaner question: is this point inside that region? Three shapes cover almost every case.

Point in a box and a sphere, line by line

Step 1 — point in an AABB: between min and max on every axis. A point \vec{p} is inside the axis-aligned box [\vec{m}, \vec{M}] exactly when each of its coordinates falls in that axis's interval — and it must hold on all axes at once:

\vec{m} \le \vec{p} \le \vec{M} \iff m_x \le p_x \le M_x \ \text{and}\ m_y \le p_y \le M_y \ \text{and}\ m_z \le p_z \le M_z.

Six comparisons, no arithmetic. The instant a coordinate falls outside its interval, the point is out and you stop — the same early-out as the box overlap test.

Step 2 — point in a sphere: compare the squared distance. A point is inside the sphere (\vec{c}, r) when it is no farther from the centre than the radius. Test the squared distance so no square root is needed:

\lVert \vec{p} - \vec{c}\rVert^2 \le r^2 \iff (p_x - c_x)^2 + (p_y - c_y)^2 + (p_z - c_z)^2 \le r^2.

One subtraction, three squares, a sum, one comparison against a precomputed r^2. This is the cheapest trigger-zone in any game.

Point in a triangle, line by line

Boxes and spheres are easy because they are defined by inequalities already. A triangle takes one more idea — the same one a ray tracer uses to hit a mesh face.

Step 3 — write the point in barycentric coordinates. Given a triangle A, B, C, any point in its plane is a weighted blend of the corners with weights summing to one — its barycentric coordinates (u, v, w):

\vec{p} = u\,A + v\,B + w\,C, \qquad u + v + w = 1.

Step 4 — inside means all three weights are non-negative. Each weight is "how much of that corner" is in the mix. A negative weight means the point has stepped past the edge opposite that corner, out of the triangle. So:

\vec{p} \text{ is inside } \triangle ABC \iff u \ge 0,\ v \ge 0,\ w \ge 0.

Step 5 — the equivalent same-side test, with cross products. There is a dual view that needs no division. The point is inside iff it lies on the same side of all three directed edges. Walking the triangle A \to B \to C, the 2-D cross product (the signed area, z-component) of an edge with the vector from the edge's start to \vec{p} must have a consistent sign:

(B - A)\times(\vec{p} - A), \quad (C - B)\times(\vec{p} - B), \quad (A - C)\times(\vec{p} - C) \quad\text{all share one sign.}

Each sign says "\vec{p} is to the left (or right) of this edge"; all the same sign means the point is boxed in by all three edges — inside. These cross products are, up to a scale by the triangle's area, exactly the barycentric weights of Step 4, so the two tests agree. (And it is the same separating-axis instinct again: a single edge with the wrong sign separates the point from the triangle.)

A point \vec{p} is inside:

Every click in a user interface is a point-in-shape test. A rectangular button is an AABB in screen space: the cursor (p_x, p_y) hits it iff m_x \le p_x \le M_x and m_y \le p_y \le M_y — the six-comparison test of Step 1, run on every mouse move to decide what to highlight. A round button or a radar blip is the squared sphere test instead.

In the world, designers paint invisible trigger volumes — a box around a doorway, a sphere around a campfire, a polygon outlining a capture zone — and the engine asks, each frame, "is the player's position inside?". A box trigger is Step 1, a proximity trigger is Step 2, and an irregular region is tessellated into triangles tested by Step 4. The same three inequalities decide whether a cutscene fires, whether you take fire damage, and whether the level even loads the next room. Hit-testing isn't a UI nicety — it is the same point math everywhere.