2013-02-05 112 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