/// <summary> /// Recursively searches the tree for all intersecting entries. /// Calls the passed function when a matching entry is found. Return if the passed function returns false; /// </summary> /// <param name="r"></param> /// <param name="v"></param> /// <param name="n"></param> /// <returns></returns> // TODO rewrite this to be non-recursive. private bool intersects(Rectangle r, Func<Rectangle, bool> v, NodeBase n) { for (int i = 0; i < n.entryCount; i++) { if (r.Intersects(ref n.entries[i])) { if (n.IsLeaf) { if (!v(n.entries[i].Value)) { return false; } } else { NodeInternal nodeInternal = n as NodeInternal; NodeInternal childNode = nodeInternal.childNodes[i] as NodeInternal; if (!intersects(r, v, childNode)) { return false; } } } } return true; }
/// <summary> /// Finds all rectangles contained by the passed rectangle /// </summary> /// <param name="r">The rectangle for which this method finds contained rectangles.</param> /// <param name="v">if return true, continue seach</param> public void Contains(Rectangle r, Func<Rectangle, bool> v) { // find all rectangles in the tree that are contained by the passed rectangle written to be non-recursive (should model other searches on this?) parents.Clear(); parents.Push(rootNode); parentsEntry.Clear(); parentsEntry.Push(-1); // TODO: possible shortcut here - could test for intersection with the MBR of the root node. If no intersection, return immediately. while (parents.Count > 0) { NodeBase n = parents.Peek(); int startIndex = parentsEntry.Peek() + 1; if (!n.IsLeaf) { NodeInternal nodeInternal = n as NodeInternal; // go through every entry in the index node to check if it intersects the passed rectangle. If so, it could contain entries that are contained. bool intersects = false; for (int i = startIndex; i < n.entryCount; i++) { if (r.Intersects(ref n.entries[i])) { parents.Push(nodeInternal.childNodes[i]); parentsEntry.Pop(); parentsEntry.Push(i); // this becomes the start index when the child has been searched parentsEntry.Push(-1); intersects = true; break; // ie go to next iteration of while() } } if (intersects) { continue; } } else { // go through every entry in the leaf to check if it is contained by the passed rectangle for (int i = 0; i < n.entryCount; i++) { if (r.Contains(n.entries[i].Value)) { if (!v(n.entries[i].Value)) { return; } } } } parents.Pop(); parentsEntry.Pop(); } }