GJK is the “ultimate” collision detection algorithm for convex shapes. While SAT (Separating Axis Theorem) works great for 2D, GJK is significantly more efficient for 3D and can handle any convex shape (spheres, capsules, boxes, etc.) without needing to check every face normal.
The genius of GJK lies in the Minkowski Difference. If you have two shapes $A$ and $B$, their Minkowski Difference is the set of all points calculated by $a - b$.
Instead of calculating the entire Minkowski Difference shape, GJK tries to build the smallest possible shape (a Simplex) that could potentially enclose the origin.
To build the simplex, we use a Support Function. A support function returns the point in a shape that is furthest in a given direction.
Support(Shape, Direction)
For the Minkowski Difference, the support point in direction $D$ is simply:
Support(A, D) - Support(B, -D)
false.true (Collision).bool GJK(Shape a, Shape b) {
Vector3 d = b.center - a.center; // Initial direction
Simplex s;
s.add(MinkowskiSupport(a, b, d));
d = -s.last(); // Search toward origin
while (true) {
Vector3 a_new = MinkowskiSupport(a, b, d);
if (dot(a_new, d) < 0) return false; // No collision possible
s.add(a_new);
if (s.Solve(d)) return true; // Simplex contains origin
}
}
GJK only tells you if a collision happened. To find the Penetration Depth and Normal (the Minimum Translation Vector needed for physics response), you typically run the EPA (Expanding Polytope Algorithm) using the final simplex from GJK as a starting point.