def add(self, item, bounds, data=None): """ Add an item to the tree. If an item already exists, its bounds are updated and the item is moved to the right bucket. Data can be used to add some extra info to the item """ # Clip item bounds to fit in top-level bucket # Keep original bounds in _ids, for reference clipped_bounds = rectangle_clip(bounds, self._bucket.bounds) if item in self._ids: old_clip = self._ids[item][2] if old_clip: bucket = self._bucket.find_bucket(old_clip) assert item in bucket.items # Fast lane, if item moved just a little it may still reside # in the same bucket. We do not need to search from top-level. if ( bucket and clipped_bounds and rectangle_contains(clipped_bounds, bucket.bounds) ): bucket.update(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds) return elif bucket: bucket.remove(item) if clipped_bounds: self._bucket.find_bucket(clipped_bounds).add(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds)
def add(self, item, bounds): """ Add an item to the quadtree. The bucket is split when nessecary. Items are otherwise added to this bucket, not some sub-bucket. """ assert rectangle_contains(bounds, self.bounds) # create new subnodes if threshold is reached if not self._buckets and len(self.items) >= self.capacity: x, y, w, h = self.bounds rw, rh = w / 2.0, h / 2.0 cx, cy = x + rw, y + rh self._buckets = [ QuadtreeBucket((x, y, rw, rh), self.capacity), QuadtreeBucket((cx, y, rw, rh), self.capacity), QuadtreeBucket((x, cy, rw, rh), self.capacity), QuadtreeBucket((cx, cy, rw, rh), self.capacity), ] # Add items to subnodes items = list(self.items.items()) self.items.clear() for i, b in items: self.find_bucket(b).add(i, b) self.find_bucket(bounds).add(item, bounds) else: self.items[item] = bounds
def add(self, item: T, bounds: Bounds) -> None: """Add an item to the quadtree. The bucket is split when necessary. Items are otherwise added to this bucket, not some sub-bucket. """ assert rectangle_contains(bounds, self.bounds) if self._buckets or len(self.items) < self.capacity: self.items[item] = bounds return x, y, w, h = self.bounds rw, rh = w / 2.0, h / 2.0 if w == rw and h == rh: self.items[item] = bounds return cx, cy = x + rw, y + rh self._buckets = [ QuadtreeBucket((x, y, rw, rh), self.capacity), QuadtreeBucket((cx, y, rw, rh), self.capacity), QuadtreeBucket((x, cy, rw, rh), self.capacity), QuadtreeBucket((cx, cy, rw, rh), self.capacity), ] items = list(self.items.items()) self.items.clear() for i, b in items: self.find_bucket(b).add(i, b) self.find_bucket(bounds).add(item, bounds)