Open petrasvestartas opened 10 months ago
I have created a fork with a 3D implementation at https://github.com/jules-vanaret/pyrtree. There's a special RTree3D
class that can be imported from rtree3d.py
.
I do not guarantee that it works 100%, but it gave sensible results when I tried it.
@jules-vanaret Nice!
I tested it. Is it true that it does not check for duplicates?
For instance if you insert random 100 Rect3D with the same cases, it would trigger this assert error:
def create_leaf(cls, rooto, leaf_obj, leaf_rect):
rect = RTreeBox(leaf_rect.x,leaf_rect.y,leaf_rect.z,leaf_rect.xx,leaf_rect.yy,leaf_rect.zz)
rect.swapped_x = True # Mark as leaf by setting the xswap flag.
res = NodeCursor.create(rooto, rect)
idx = res.index
res.first_child = rooto.leaf_count
rooto.leaf_count += 1
res.next_sibling = 0
rooto.leaf_pool.append(leaf_obj)
res._save_back()
res._become(idx)
assert(res.is_leaf())
return res
I have to say, I have no idea ! I just took the 2D implementation and (hopefully) meticulously replaced every line about 2D stuff with its 3D counterpart. So I guess if the base implementation does not check for duplicates, this one does not either.
In some cases it works in some not. I am wonder why:
I am not familiar with your use case. Should the red rectangle collide with other grey rectangles, or the opposite ?
Red rectangle is the one that searches, transparent collisions, grey not colliding.
Veryfing again...
Yup, there are issues with code. This is a test set I use that fails:
from compas.geometry import Box
rtree = RTree3D()
rtree_boxes = []
n = 20
for i in range(n):
x0 = random.random()*10
y0 = random.random()*10
z0 = random.random()*10
x1 = random.random()*10
y1 = random.random()*10
z1 = random.random()*10
if x0 != x1 and y0 != y1 and z0 != z1:
rtree_boxes.append(Rect3D(x0,y0,z0,x1,y1,z1))
for i in range(len(rtree_boxes)):
rtree.insert(i, rtree_boxes[i])
# Search first line:
indices = []
for x in rtree.query_rect( rtree_boxes[0]):
indices.append(x.index-1)
print("Found line %d" % x.index, x.rect.coords())
new_boxes.pop(0)
indices.pop(0)
print(indices)
the first item of found element seems to be the bounding box of all boxes.
Any ideas what could be wrong?
I am not sure. First, are you allowed to provide x1,y1,z1 that are potentially smaller than x0,y0,z0 like is the case in your example (since they are generated randomly) ? Does this specific test work with the 2D implementation ?
Yes I do in parallel this:
min_x = min(x0, x1)
max_x = max(x0, x1)
min_y = min(y0, y1)
max_y = max(y0, y1)
min_z = min(z0, z1)
max_z = max(z0, z1)
did not try for 2d case though
hmmm.
Do you have a test case to test?
If you try the same test with the 2D case and it also fails there is nothing I can do I am afraid, as I don't have enough knowledge about the core package to find an error.
I think something is wrong. Could you try as well? To check if I am doing something wrong...
Can this repository be used for 3d coordinates because the source code covers only xy coordinates?