Getting a list of vectors that are within a radius of a predefined vector

This one sounds easy to do, but I’m having a weird problem. I believe that the code below should already work, but when I run it, it crashes the UPBGE. Basically, I want this function to return a list of vectors that are within radius of another vector, which is within the list as well, but I think I might have done something wrong. Thanks any help.

def _radius_system_(self, list, leng):
    result_list = []
    for val in list:
       vec_ = Vector(val[x] for x in range(3)) # vetor atual para comparação dentro da lista
       result_list = [x for x in list if (Vector(x[y] for y in range(3)) - vec_).length < leng] 
    return result_list

Kdtree lib is designed for this

2 Likes

That’ll happen when you have an infinite loop.

Split out your code so its readable and put some print statements in it so you can see the state of “result_list” on each iteration. I’d recommend printing “val” and “list” too.

Btw, “list” is a builtin class (like “str” and “int”), so I’d recommend picking another variable name. No idea if that’s part of what’s going wrong.

1 Like

I agree Kdtree is made for this, it’s very quick and easy to use.

1 Like

Thank you guys. How can I use this kd tree in my project?

I cannot print anything to the console.

I got it, searched and found a tutorial that helped me, thank you guys, really.

def _radius_system_(self, have_vector, have_list, have_leng):
        main_list = np.array([[x[y] for y in range(3)] for x in have_list])
        kd_tree = KDTree(main_list, leaf_size=2)
        list_of_index = kd_tree.query_radius(np.array([have_vector]), r=have_leng)  
        return list_of_index

Mathutils has a kdtree as well,

You can build it one time and reuse it periodically if you store it as a property in a object

from mathutils import kdtree


def build_kdtree(cont):
    
    own = cont.owner

    vector_list = [list with vectors/world positions]
      
    size = len(vector_list)
    kd = kdtree.KDTree(size)

    index = 0
    
    for vec in vector_list:
        kd.insert(vec, index)
        
        index += 1

    kd.balance()
    
    own['kdtree'] = kd   
    
    
    
def use_kdtree(cont):    
    
    own = cont.owner
    
    if not 'kdtree' in own:
        build_kdtree(cont)
        
    vectors_in_range = own['kdtree'].find_range('a vector to search from', 'the search range here')
    
    for co, index, dist in vectors_in_range: 
        print(co, 'distance from search point:', dist, 'position in list:', index)
2 Likes

I’ll try this, thank you.

I still can’t get this to work. When it looks like I’m finished, the project doesn’t open and UPBGE crashes, doesn’t run the project. I’ve basically tried everything to do the following:

I have a pretty big list of vectors:

[Vector((48.68199920654297, 26.025999069213867, 0.9779999852180481)),
 Vector((45.07899856567383, 48.8650016784668, 35.694000244140625)), 
Vector((13.130999565124512, 1.225000023841858, -18.094999313354492)), 
Vector((7.156000137329102, 40.790000915527344, 9.286999702453613)), 
Vector((8.96500015258789, 5.829999923706055, -11.95300006866455)), 
Vector((38.84700012207031, 31.722999572753906, -5.1519999504089355)), 
Vector((12.70199966430664, -2.0199999809265137, -45.00400161743164)), 
Vector((2.055999994277954, 20.923999786376953, -23.702999114990234)), 
Vector((-0.8399999737739563, -2.7320001125335693, -1.5880000591278076)),
 Vector((41.944000244140625, -48.43600082397461, 20.302000045776367))]

In this case, it would be like points within a 3D plane:

But I only want vectors that are a certain distance between the X and Y axes in the world:

PS: This vector list is actually a list of vertex positions, specifically.

Is it possible to get a list with this desired result from this schema?