More efficient way to find all intersections using rtree

51 Views Asked by At

I have a list of 3D boxes and i'm trying to find all intersections between them. I am using rtree for this. I have the following code that is not very fast. Is there a more efficient way return all intersections then iterating through every box?

import rtree

#list of boxes
boundingBoxes = [(1, 1, 1, 2, 2, 2), (3, 3, 3, 6, 6, 6), (5, 5, 5, 7, 7, 7), (7, 7, 7, 8, 8, 8)]

#creating rtree
p = rtree.index.Property()
p.dimension = 3
idx3d = rtree.index.Index(properties=p)
for index, bb in enumerate(boundingBoxes):
    idx3d.insert(index, bb)

#to find intersections i iterate through every box and check if they intersect with other boxes
#is there a more efficient way to do this?
colisions = []
for i in range(len(boundingBoxes)):
    intersecting = list(idx3d.intersection(boundingBoxes[i]))
    for j in range(i+1, len(boundingBoxes)):
        if i < j and j in intersecting:
            colision = (boundingBoxes[i], boundingBoxes[j])
            colisions.append(colision)
            print(colision)

1

There are 1 best solutions below

1
vagitus On

I got it working 4 times faster using numpy and scipy:

import numpy as np
from scipy.spatial import cKDTree

boundingBoxes = np.array([(1, 1, 1, 2, 2, 2), (3, 3, 3, 6, 6, 6), (5, 5, 5, 7, 7, 7), (7, 7, 7, 8, 8, 8)])

centers = boundingBoxes[:, :3] + 0.5 * (boundingBoxes[:, 3:] - boundingBoxes[:, :3])

tree = cKDTree(centers)

distances, indices = tree.query(centers, k=3)

colisions = []
for i in range(len(indices)):
    for j in indices[i, 1:]:
        if i < j and not np.all(np.logical_or(boundingBoxes[i, :3] > boundingBoxes[j, 3:], boundingBoxes[i, 3:] < boundingBoxes[j, :3])):
            collision = (boundingBoxes[i], boundingBoxes[j])
            colisions.append(collision)
            print(collision)