Rhoana / pyrtree

An R-Tree implementation
35 stars 19 forks source link

3d coordinates xyz #6

Open petrasvestartas opened 10 months ago

petrasvestartas commented 10 months ago

Can this repository be used for 3d coordinates because the source code covers only xy coordinates?

jules-vanaret commented 2 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.

petrasvestartas commented 2 months ago

@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
jules-vanaret commented 2 months ago

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.

petrasvestartas commented 2 months ago

In some cases it works in some not. I am wonder why:

Screenshot from 2024-04-25 23-16-41 Screenshot from 2024-04-25 23-16-14

jules-vanaret commented 2 months ago

I am not familiar with your use case. Should the red rectangle collide with other grey rectangles, or the opposite ?

petrasvestartas commented 2 months ago

Red rectangle is the one that searches, transparent collisions, grey not colliding.

Veryfing again...

petrasvestartas commented 2 months ago

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?

jules-vanaret commented 2 months ago

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 ?

petrasvestartas commented 2 months ago

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?

jules-vanaret commented 2 months ago

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.

petrasvestartas commented 2 months ago

I think something is wrong. Could you try as well? To check if I am doing something wrong...