One of the simplest methods of pre-checking whether two objects intersect in space is to check collisions of their bounding objects, in particular AABB (Axis Aligned Bounding Box).
Although the AABB collision check is not very accurate, since it does not take into account the shape of objects at all, it allows excluding objects that are obviously not intersecting from further, more accurate and more expensive checks. This is especially useful when checking complex scenes with many objects.
Consider checking intersections for two parallelograms. The AABB for the parallelogram matches its actual shape, which gives us the ability to visually track their intersections.
Add two cubes to the scene and resize them a bit so that they turn into parallelograms. We can access them from bpy.data:
1 2 |
obj1 = bpy.data.objects['Cube'] obj2 = bpy.data.objects['Cube.001'] |
Translate the coordinates of their points into the global coordinate system to take into account their translations and transformations:
1 2 |
obj1_w = [obj1.matrix_world @ vertex.co for vertex in obj1.data.vertices] obj2_w = [obj2.matrix_world @ vertex.co for vertex in obj2.data.vertices] |
And calculate AABB for each of them using the _aabb() function.
1 2 3 4 5 |
aabb1 = _aabb(obj1_w) aabb2 = _aabb(obj2_w) # {'min_x': -1.272713541984558, 'min_y': -4.576056480407715, 'min_z': ...} # {'min_x': -3.163292646408081, 'min_y': -6.7881975173950195, 'min_z': ...} |
Let’s define a function that will check two AABBs for intersection.
Our function will return True if there is an intersection between the two AABB passed in the parameters, or False if there is no intersection between the AABBs passed in the parameters.
1 2 3 4 5 6 7 8 9 10 |
def collision_aabb(aabb_1, aabb_2): if aabb_1['min_x'] < aabb_2['max_x'] \ and aabb_1['max_x'] > aabb_2['min_x'] \ and aabb_1['min_y'] < aabb_2['max_y'] \ and aabb_1['max_y'] > aabb_2['min_y'] \ and aabb_1['min_z'] < aabb_2['max_z'] \ and aabb_1['max_z'] > aabb_2['min_z']: return True else: return False |
Now we can check if the AABBs for our scene objects intersect:
1 2 3 4 |
col = collision_aabb(aabb1, aabb2) print('YES' if col else 'NO') # NO |
If there are no intersections of two AABBs, we can guarantee that the objects do not intersect and do not waste time and computer power on more accurate and expensive tests.