public Node(GeometricTree <TItem, TVector, TBound> tree, TBound bounds, int depth, int maxDepth) { _tree = tree; _depth = depth; _maxDepth = maxDepth; Bounds = bounds; }
private int RemoveRecursive(TBound bounds, Predicate <Member> predicate, bool removeSingle) { //We want to skip this node if the boundary doesn't intersect it... unless it's the root which can contain items outside it's boundary! if (!_tree.Intersects(Bounds, ref bounds) && !_tree._root.Equals(this)) { return(0); } int removed = 0; //Either we're removing the first item which matches the predicate, or all items which match if (removeSingle) { // Find single item and remove it, then exit instantly var index = Items.FindIndex(predicate); if (index != -1) { Items.RemoveAt(index); return(1); } } else { //We're removing all predicate matches removed += Items.RemoveAll(predicate); } //Remove items from children (and aggregate total removed count) if (Children != null) { foreach (var child in Children) { removed += child.RemoveRecursive(bounds, predicate, removeSingle); //Early exit if we can if (removed > 0 && removeSingle) { return(removed); } } } return(removed); }
public IEnumerable <Member> Intersects(TBound bounds) { var nodes = new List <Node>(50) { this }; var root = true; while (nodes.Count > 0) { //Remove node var n = nodes[nodes.Count - 1]; nodes.RemoveAt(nodes.Count - 1); //Skip nodes we do not intersect (unless this is the root, in which case we always want to check it) if (!root && !_tree.Intersects(n.Bounds, ref bounds)) { continue; } //yield items as appropriate foreach (var member in n.Items) { if (_tree.Intersects(member.Bounds, ref bounds)) { yield return(member); } } //push children onto stack to be checked if (n.Children != null) { nodes.AddRange(n.Children); } root = false; } }
public int Remove(TBound bounds, Predicate <TItem> pred) { var predInner = new Predicate <Member>(a => pred(a.Value)); return(RemoveRecursive(bounds, predInner, false)); }
public int Remove(TBound bounds, TItem item) { var pred = new Predicate <Member>(a => a.Value.Equals(item)); return(RemoveRecursive(bounds, pred, true)); }
/// <summary> /// быстрая сортировка для узлов по их MBR. axe - ось по которой происходит сортировка, bound - граница по которой происходит сортировка (левая/правая) /// </summary> /// <param name="List"></param> /// <param name="iLo"></param> /// <param name="iHi"></param> /// <param name="axe"></param> /// <param name="bound"></param> #region private void QuickSort(int[] List, int iLo, int iHi, TAxis axe, TBound bound) { //Console.WriteLine("QuickSort2 work"); int Lo = iLo, Hi = iHi; int T; double Mid = 0.0; switch (bound) { case TBound.Left: { switch (axe) { case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.X; break; case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.Y; break; } } break; case TBound.Right: { switch (axe) { case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.X; break; case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.Y; break; } } break; } do { switch (bound) { case TBound.Left: { switch (axe) { case TAxis.X: { while (FNodeArr[List[Lo]].mbr.Left.X < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Left.X > Mid) { Hi--; } } break; case TAxis.Y: { while (FNodeArr[List[Lo]].mbr.Left.Y < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Left.Y > Mid) { Hi--; } } break; } } break; case TBound.Right: { switch (axe) { case TAxis.X: { while (FNodeArr[List[Lo]].mbr.Right.X < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Right.X > Mid) { Hi--; } } break; case TAxis.Y: { while (FNodeArr[List[Lo]].mbr.Right.Y < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Right.Y > Mid) { Hi--; } } break; } } break; } if (Lo <= Hi) { T = List[Lo]; List[Lo] = List[Hi]; List[Hi] = T; Lo++; Hi--; } } while (Lo <= Hi); if (Hi > iLo) { QuickSort(List, iLo, Hi, axe, bound); } if (Lo < iHi) { QuickSort(List, Lo, iHi, axe, bound); } }