# -*- Mode: Python -*- def split ((lo, hi)): w2 = (hi - lo)/2 return ((lo, lo + w2), (lo + w2, hi)) def contains ((la, ra), (lb, rb)): return la <= lb and ra >= rb def intersects ((la, ra), (lb, rb)): return ra >= lb and rb >= la # L,T,R,B class node (object): __slots__ = ('l', 'r', 'objects') def __init__ (self): self.l = None self.r = None self.objects = None def get (self, i): if i == 0: if self.l is None: self.l = node() return self.l else: if self.r is None: self.r = node() return self.r def insert (self, seg, needle): segs = split (seg) for i in (0, 1): s = segs[i] if contains (s, needle): return self.get(i).insert (s, needle) if self.objects is None: self.objects = [needle] else: self.objects.append (needle) def delete (self, seg, needle): segs = split (seg) for i in (0, 1): s = segs[i] if contains (s, needle): return self.get(i).delete (s, needle) try: self.objects.remove (needle) return True except ValueError: pass def search_apply (self, seg, needle, fun): if self.objects is not None: for ob in self.objects: if intersects (ob, needle): fun (ob) segs = split (seg) for i in (0, 1): s = segs[i] if contains (s, needle): return self.get(i).search_apply (s, needle, fun) def dump (self, line, depth): print ' ' * depth, line, if self.objects: print self.objects else: print l, r = split (line) if self.l: self.l.dump (l, depth+1) if self.r: self.r.dump (r, depth+1) class bsp: def __init__ (self, line=(0,1024)): self.tree = node() self.line = line self.size = 0 def __repr__ (self): return '' % ( self.size, self.line ) def dump (self): self.tree.dump (self.line, 0) def insert (self, line): while 1: if contains (self.line, line): self.tree.insert (self.line, line) break else: n = node() ll, lr = line sl, sr = self.line w = sr - sl if ll < sl: # outside to the left self.line = sl - w, sr n.r, self.tree = self.tree, n else: self.line = sl, sr + w n.l, self.tree = self.tree, n self.size += 1 def delete (self, needle): return self.tree.delete (self.line, needle) def search (self, needle): r = [] self.tree.search_apply (self.line, needle, r.append) return r def search_apply (self, needle, fun): self.tree.search_apply (self.line, needle, fun) def t0(): t = bsp() t.insert ((0, 200)) t.insert ((180, 280)) t.insert ((3000, 4000)) t.insert ((3050, 3060)) t.insert ((1000, 1500)) t.insert ((1400, 1800)) t.dump() t.delete ((3050, 3060)) t.delete ((180, 280)) t.dump() return t