I am writing code that requires me to find all points within circle on certain parts of the screen hundreds of times per frame. I wrote a quadtree for this and have 1 method called query_circle that looks like this:
def query_circle(self, center, radius, lis=None):
'''
Uses given bounds of center and radius and
creates AABB to search all quadtrees that intersect that region for
the in that region
'''
bounds = [center[0] - radius, center[1] - radius, radius * 2, radius * 2]
x1, y1 = (bounds[0], bounds[1])
x2, y2 = (bounds[0] + bounds[2], bounds[1] + bounds[3])
if lis == None:
lis = []
if self.nodes:
if y1 <= self.center[1]:
if x1 <= self.center[0]:
self.nodes[0].query_circle(center, radius, lis)
if x2 > self.center[0]:
self.nodes[1].query_circle(center, radius, lis)
if y2 > self.center[1]:
if x1 <= self.center[0]:
self.nodes[2].query_circle(center, radius, lis)
if x2 > self.center[0]:
self.nodes[3].query_circle(center, radius, lis)
for point in self.points:
if (point.x - center[0]) ** 2 + (point.y - center[1]) ** 2 <= radius**2:
lis.append(point)
return lis
What is happening is I create an AABB for the circle and then find all the QuadTrees that are intersecting with the AABB and using those QuadTrees to check if the points inside of them are within the circle. Unfortunately, the animation was running at less than 3 frames per second and the root cause was this method. I profiled the method and found this: As you can seet the last 4 lines of code where I check if the point is inside the circle and append it to a list are what are slowing down the method the most. Is there any technique I can use to considerably speed up that process?
**
may be calling inefficiently a method. That will likely not save you, but try something like this instead:if (point.x - center[0]) * (point.x - center[0]) + (point.y - center[1]) * (point.y - center[1]) <= cached_radius_sq:
where you've computedcached_radius_sq
before entering the loop. \$\endgroup\$