2013-02-05 78 views
0

这检查是否某些点位于一个矩形内,并且每当它运行时,它都会使我的程序减慢很多。我们如何改变它以提高效率?如何加快此功能?

def draw_grid(self, box): 
    for element in self.map_layout.all_map_objects: 
     if element not in self.build_grid and box.area.collidepoint(element.checkpoint): 
      self.build_grid.append(element) 
     elif not box.area.collidepoint(element.checkpoint): 
      if element in self.build_grid: 
       self.build_grid.remove(element) 
+0

'build_grid'的顺序是否重要? – mgilson

+0

@mgilson完全没有! –

+0

然后,我肯定会考虑将'self.build_grid'更改为集合(只要它包含的元素是可散列的) – mgilson

回答

3

一个变化,这是小事做是存储box.area.collidepoint结果:

def draw_grid(self, box): 
    for element in self.map_layout.all_map_objects: 
     collidepoint = box.area.collidepoint(element.checkpoint) 
     if element not in self.build_grid and collidepoint: 
      self.build_grid.append(element) 
     elif not collidepoint: 
      if element in self.build_grid: 
       self.build_grid.remove(element) 

其他的变化依赖于你所需要的数据结构。例如,self.build_grid似乎是list__contains__(在运营商)在列表上是一个O(N)操作平均而如果你能通过与set,得到它将是O(1)!。同样的事情会与list.remove - 在这里你可以使用try-except子句从紧的循环,如果该元素是通常列表可能有助于消除一个O(N)操作:

 elif not collidepoint: 
      try: 
       self.build_grid.remove(element) 
      except ValueError: 
       pass 
1

只有在移动元素而不是绘图时才能检查碰撞等情况吗?

此外,您可能调用box.area.collidepoint(element.checkpoint):element in self.build_grid:两次,一次为if,另一次为elseif。如果它的计算成本很高,你能缓存那个答案吗?

+0

box.area绑定到鼠标位置,并且当draw_grid处于活动状态时,我们必须跟随鼠标移动。 –

1

如果您保持这些点在一些有序的数据结构中,你不需要检查每一个。按Y排序,找到矩形的Y范围内的所有内容,然后按X排序新列表,并在矩形的X范围内找到所有内容。

+0

如果我明白这一点,那么pygame函数collidepoint就是这样做的。 –

+0

我认为他引用了一个四叉树,这是不同的。它减少了可能的冲突总量。 – ninMonkey