func (me *Tree) RemoveIntersect(bounds geom.Rect, collection map[Item]bool) { if !geom.RectsIntersect(bounds, me.UpperBounds) { return } if me.BigElements != nil { for elem := range me.BigElements { if geom.RectsIntersect(elem.Bounds(), bounds) { delete(me.BigElements, elem) if collection != nil { collection[elem] = true } } } } if me.Elements != nil { for elem := range me.Elements { if geom.RectsIntersect(bounds, elem.Bounds()) { delete(me.Elements, elem) if collection != nil { collection[elem] = true } } } } for _, t := range me.Subtrees { if t == nil { continue } t.RemoveIntersect(bounds, collection) } return }
func (me *Tree) Insert(element Item) (inserted bool) { str := "" if geom.RectsIntersect(element.Bounds(), me.UpperBounds) { str = "*" } dbg("inserting in %v%s", me.Bounds, str) if !geom.RectsIntersect(me.UpperBounds, element.Bounds()) { return } defer func(bounds geom.Rect) { me.Bounds.ExpandToContainRect(bounds) me.Count++ }(element.Bounds()) inserted = true //if this element is too big, stop here if me.IsBig(element.Bounds()) { if me.BigElements == nil { me.BigElements = make(map[Item]bool) } me.BigElements[element] = true return } //if we're at the bottom, stop here if me.cfg.Height == 0 { if me.Elements == nil { me.Elements = make(map[Item]bool) } me.Elements[element] = true return } //if we've got enough at this level, break into subtrees if me.Elements != nil && len(me.Elements) == me.cfg.SplitCount { for elem := range me.Elements { me.insertSubTrees(elem) } me.Elements = nil } //if we already have subtrees, insert into them if me.Subtrees[0] != nil { me.insertSubTrees(element) return } //no subtrees, stop here if me.Elements == nil { me.Elements = make(map[Item]bool) } me.Elements[element] = true return }
func (me *Tree) CollectInside(bounds geom.Rect, collection map[Item]bool) { if !geom.RectsIntersect(bounds, me.UpperBounds) { return } if me.BigElements != nil { for elem := range me.BigElements { if bounds.ContainsRect(elem.Bounds()) { collection[elem] = true } } } if me.Elements != nil { for elem := range me.Elements { if bounds.ContainsRect(elem.Bounds()) { collection[elem] = true } } } for _, t := range me.Subtrees { if t == nil { continue } t.CollectInside(bounds, collection) } return }
func (me *Tree) Find(element Item) (found Item, ok bool) { if !geom.RectsIntersect(element.Bounds(), me.UpperBounds) { return } if me.IsBig(element.Bounds()) && me.BigElements != nil { for elem := range me.BigElements { if element.Equals(elem) { found = elem ok = true return } } return } if me.Elements != nil { for elem := range me.Elements { if element.Equals(elem) { found = elem ok = true return } } return } for _, t := range me.Subtrees { if t == nil { continue } found, ok = t.Find(element) if ok { return } } return }
func (me *Tree) Remove(element Item) (removed bool) { dbg("removing %v", element) if Debug { println(element) } Indent++ defer func() { Indent-- }() if !geom.RectsIntersect(me.UpperBounds, element.Bounds()) { dbg("out of bounds") return } defer func() { if removed { me.Count = 0 me.Bounds = geom.NilRect() if me.BigElements != nil { me.Count += len(me.BigElements) for elem := range me.BigElements { me.Bounds.ExpandToContainRect(elem.Bounds()) } } if me.Elements != nil { me.Count += len(me.Elements) for elem := range me.Elements { me.Bounds.ExpandToContainRect(elem.Bounds()) } } if me.Subtrees[0] != nil { for _, t := range me.Subtrees { if t.Count != 0 { me.Count += t.Count me.Bounds.ExpandToContainRect(t.Bounds) } } } } }() dbg("BigElements: %v", me.BigElements) dbg("Elements: %v", me.Elements) if me.BigElements != nil { for elem := range me.BigElements { if element.Equals(elem) { delete(me.BigElements, elem) removed = true } } } if me.Elements != nil { for elem := range me.Elements { if element.Equals(elem) { delete(me.Elements, elem) removed = true } } } for _, t := range me.Subtrees { if t == nil { continue } if t.Remove(element) { removed = true } } return }
func (me *Tree) FindOrInsert(element Item) (found Item, inserted bool) { defer func(bounds geom.Rect) { if inserted { me.Bounds.ExpandToContainRect(bounds) me.Count++ } }(element.Bounds()) if !geom.RectsIntersect(element.Bounds(), me.UpperBounds) { dbg("doesn't belong in %v", me.UpperBounds) return } if me.IsBig(element.Bounds()) { if me.BigElements == nil { me.BigElements = make(map[Item]bool) } for elem := range me.BigElements { //if geom.RectsEqual(elem.Bounds(), element.Bounds()) { if element.Equals(elem) { found = elem inserted = false return } } me.BigElements[element] = true found = element inserted = true return } if me.cfg.Height == 0 { if me.Elements == nil { me.Elements = make(map[Item]bool) } } else { if me.Elements != nil && len(me.Elements) == me.cfg.SplitCount { for elem := range me.Elements { me.insertSubTrees(elem) } me.Elements = nil } } if me.Subtrees[0] != nil { dbg("looking through subtrees") for _, t := range me.Subtrees { if t == nil { continue } foundInSubtree, insertedInSubtree := t.FindOrInsert(element) if foundInSubtree != nil { // if found in the subtree, all subtrees should agree here found = foundInSubtree inserted = insertedInSubtree } } return } if me.Elements != nil { dbg("looking through Element") for elem := range me.Elements { //if geom.RectsEqual(elem.Bounds(), element.Bounds()) { if element.Equals(elem) { found = elem inserted = false return } } } else { me.Elements = make(map[Item]bool) } me.Elements[element] = true found = element inserted = true return }