# Collision detection 3d rectangles using SAT

This question builds on a previous post asked by griffinHeart nov 2012. See link below.

How many and which axes to use for 3D OBB collision with SAT

Refering to the explanation/answer by Ken. What if the yellow cube had a rotation so the gap was hidden. This scenario does not necessarily mean that there is a collision/interception. The scenario would look something like this:

Which of the 9 edge - edge vectors would then show that there is no collision.

I am trying to implement an anti- coll algo between two 3d rectangles that might have a rotation around any axis (x, y, z). I am struggling with the projection part. How to project the points onto the face normals.

Hope someone can give me an answer that could lead to a solution. Thanks!

• If I'm reading this right, the gap would never be "hidden" when a shape is rotated. SAT tests are relative to the shapes being tested. Here, that's the the black arrow. Rotating the yellow cube would rotate the corresponding axis, such that this viewpoint we're looking at remains the same relative to the yellow cube, regardless of orientation. (Man, having an actual little rotating 3D model would be really handy here.)
– Anko
May 22, 2014 at 1:06

Quoting the answer to the linked question, the axes you need to test are:

• 3 axes from object A (face normals)
• 3 axes from object B (face normals)
• 9 axes from all the pairs of edges of A and edges of B (3x3)
=15 in total

Emphasis added. The black arrow formed in the diagram above is generated by the cross product of a pair of edges: the vertical edge of the yellow cube and the horizontal edge of the blue prism.

A property of the cross product is that the result vector is always perpendicular to both input vectors.

So, when you try to turn the cube A to hide the separation, you also turn the vertical edge used as input to construct the projection axis, which then turns the projection axis to remain perpendicular to that edge. So the projection moves to exactly compensate for your attempt to hide the separation. That's why we choose these particular edges and use the cross product in this way: to always reveal a separation if one exists.

Vector[] axes = new Vector[shape.vertices.length];
// loop over the vertices
for (int i = 0; i < shape.vertices.length; i++) {
// get the current vertex
Vector p1 = shape.vertices[i];
// get the next vertex
Vector p2 = shape.vertices[i + 1 == shape.vertices.length ? 0 : i + 1];
// subtract the two to get the edge vector
Vector edge = p1.subtract(p2);
// get either perpendicular vector
Vector normal = edge.perp();
// the perp method is just (x, y) => (-y, x) or (y, -x)
axes[i] = normal;
}


Note this only works with convex shapes but you should be able to use a convex decomposition on your concave shapes.

• This code shows how to test the vertices against a given edge. It does not show how to select the axes to test, and identify the axis of separation, which is what the question asks. May 30, 2018 at 13:31
• @DMGregory ah sorry editing question
– user116458
May 30, 2018 at 13:37