Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}
Example #5
0
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
}
Example #6
0
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
}