public List <SpatialObj <T> > WindowQuery(Rectangle window) { // Finds objects within a Rectangular range (window) List <SpatialObj <T> > answer = new List <SpatialObj <T> >(); Queue <BUCoverNode <T> > searching_nodes = new Queue <BUCoverNode <T> >(); searching_nodes.Enqueue(rootNode); while (searching_nodes.Count > 0) { BUCoverNode <T> current_node = searching_nodes.Dequeue(); if (current_node.IntersectsWith(window)) { answer.AddRange(current_node.GetRangeQueryObj(window)); if (current_node.HasChildren()) { foreach (BUCoverNode <T> child in current_node.GetChildren()) { if (!searching_nodes.Contains(child)) { searching_nodes.Enqueue(child); } } } } } return(answer); }
public BUCoverNode <T> AddRectangle(SpatialObj <T> rect, bool reorganize = true) { BUCoverNode <T> deepest_field = null; if (rootNode == null) { Size nodeSize = DetermineBoundingSize(rect); rootNode = new BUCoverNode <T>(new Rectangle(rect.boundingBox.Center, nodeSize), Capacity, 0, pVal, null); deepest_field = rootNode; } else { while (deepest_field == null) { deepest_field = FindContainingField(rect, rootNode); if (deepest_field == null) { if (!rootNode.GetActualBounds().ContainsPoint(rect.boundingBox.Center)) { rootNode = rootNode.CreateParent(rect.boundingBox.Center); } else { foreach (var corner in rect.boundingBox.GetCorners()) { if (!rootNode.GetActualBounds().ContainsPoint(corner)) { rootNode = rootNode.CreateParent(corner); break; } } } } } } if (deepest_field.IsFull() && !deepest_field.HasChildren()) { PartitionField(deepest_field); BUCoverNode <T> node = AddRectangle(rect); if (reorganize) { ReorganizeOverflownNodes(); } if (node != null) { return(node); } } else { bool overflown = deepest_field.StoreRectangle(rect); } if (deepest_field != null) { Count += 1; } return(deepest_field); }
private void MergeEmptyChildren(BUCoverNode <T> node) { if (node.HasChildren() && node.AreExistingChildrenEmpty()) { node.MergeEmptyChildren(); } if (node.IsRootNode() && IsEmpty()) { rootNode = null; return; } if (node.IsRootNode() || !node.IsEmpty() || node.HasChildren()) { return; } MergeEmptyChildren(node.GetParent()); }
public Tuple <BUCoverNode <T>, SpatialObj <T> > IncrementalNNFindNext() { if (incrNN_queue is null) { return(null); } while (incrNN_queue.Count > 0) { NodeOrObj current_element = incrNN_queue.Dequeue(); while (incrNN_queue.Count > 0 && incrNN_queue.First().Equals(current_element)) { incrNN_queue.Dequeue(); } if (current_element.IsObj()) { return(Tuple.Create(current_element.GetNode(), current_element.GetObj())); } else { BUCoverNode <T> current_node = current_element.GetNode(); double current_dist = current_node.GetDistanceToPointSq(incrNN_origin); if (!current_node.IsEmpty()) { foreach (SpatialObj <T> obj in current_node.GetAllObjects()) { double distance = obj.boundingBox.GetDistanceSqToPoint(incrNN_origin); if (distance >= current_dist) { NodeOrObj obj_nodeOrObj = new NodeOrObj(); obj_nodeOrObj.SetNode(current_node); obj_nodeOrObj.SetObj(obj); incrNN_queue.Enqueue(obj_nodeOrObj, (float)distance); } } } if (current_node.HasChildren()) { foreach (BUCoverNode <T> child_node in current_node.GetChildren()) { double distance = child_node.GetDistanceToPointSq(incrNN_origin); if (distance >= current_dist) { NodeOrObj node_nodeOrObj = new NodeOrObj(); node_nodeOrObj.SetNode(child_node); incrNN_queue.Enqueue(node_nodeOrObj, (float)distance); } } } } } return(null); }
private Dictionary <BUCoverNode <T>, SpatialObj <T> > FindNearestRectToPoint(Point p, BUCoverNode <T> node) { Dictionary <BUCoverNode <T>, SpatialObj <T> > answer_dict = new Dictionary <BUCoverNode <T>, SpatialObj <T> >(); SimplePriorityQueue <BUCoverNode <T> > searching_nodes = new SimplePriorityQueue <BUCoverNode <T> >(); searching_nodes.Enqueue(node, 0); SpatialObj <T> answer = default(SpatialObj <T>); BUCoverNode <T> answer_node = null; bool used = false; double min_distance_sq = rootNode.GetMaxDistance(); while (searching_nodes.Count > 0) { BUCoverNode <T> current_node = searching_nodes.Dequeue(); Dictionary <SpatialObj <T>, double> nearest_rect = current_node.GetNearestRectangle(p); if (nearest_rect.Count > 0) { foreach (KeyValuePair <SpatialObj <T>, double> entry in nearest_rect) { if (entry.Value <= min_distance_sq || entry.Value < Statics.EPSILON) { min_distance_sq = entry.Value; answer = entry.Key; answer_node = current_node; used = false; if (min_distance_sq < Statics.EPSILON) { answer_dict.Add(answer_node, answer); used = true; } } } } if (current_node.HasChildren()) { foreach (BUCoverNode <T> child in current_node.GetChildren()) { double field_dist = child.GetDistanceToPointSq(p); if (field_dist <= min_distance_sq) { searching_nodes.Enqueue(child, (float)field_dist); } } } } if (!used) { answer_dict.Add(answer_node, answer); } return(answer_dict); }
private void ReorganizeNode(BUCoverNode <T> node) { // After adding objects and creating new partitions, checks to see if any of the upper level objects can go deeper into the tree. Queue <BUCoverNode <T> > all_nodes = new Queue <BUCoverNode <T> >(); all_nodes.Enqueue(node); while (all_nodes.Count > 0) { List <SpatialObj <T> > rects_removed = new List <SpatialObj <T> >(); BUCoverNode <T> current_node = all_nodes.Dequeue(); foreach (SpatialObj <T> rect in current_node.GetOverflowObjs()) { BUCoverNode <T> deepest_field = FindContainingField(rect, current_node); if (!deepest_field.Equals(current_node)) { bool overflown = deepest_field.StoreRectangle(rect); rects_removed.Add(rect); } } if (rects_removed.Count > 0) { current_node.DeleteRectangles(rects_removed, true); } if (current_node.HasChildren()) { foreach (BUCoverNode <T> child in current_node.GetChildren()) { all_nodes.Enqueue(child); } } } }
public bool IsEmpty() { return(rootNode == null || (rootNode.IsEmpty() && !rootNode.HasChildren())); }