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); }
public CoverNode <T> AddRectangle(SpatialObj <T> rect, bool reorganize = true) { CoverNode <T> deepest_field = FindContainingField(rect, rootNode); if (deepest_field.IsFull() && !deepest_field.HasChildren()) { PartitionField(deepest_field); CoverNode <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); }
public bool CanSink(SpatialObj <T> rect) { Rectangle OperatingBounds = GetOperatingBounds(); Rectangle ActualBounds = GetActualBounds(); return((rect.boundingBox.Width <= OperatingBounds.Width / 2) && (rect.boundingBox.Height <= OperatingBounds.Height / 2) && Math.Min(ActualBounds.Height, ActualBounds.Width) > 1); }
private SpatialObj <T> RemoveRectangle(SpatialObj <T> rect, CoverNode <T> node) { if (node.DeleteRectangle(rect)) { Count -= 1; } MergeEmptyChildren(node); return(rect); }
private Size DetermineBoundingSize(SpatialObj <T> obj) { int size = 1; while (size < Math.Max(obj.boundingBox.Width, obj.boundingBox.Height)) { size *= 2; } return(new Size(size, size)); }
public bool DeleteRectangle(SpatialObj <T> rect, bool overflow_only = false) { int oldCount = Count(); if (!overflow_only) { StoredObjs.RemoveAll(x => x.objInstance.Equals(rect.objInstance)); } OverflowObjs.RemoveAll(x => x.objInstance.Equals(rect.objInstance)); return(oldCount > Count()); }
private Dictionary <CoverNode <T>, SpatialObj <T> > FindNearestRectToPoint(Point p, CoverNode <T> node) { Dictionary <CoverNode <T>, SpatialObj <T> > answer_dict = new Dictionary <CoverNode <T>, SpatialObj <T> >(); SimplePriorityQueue <CoverNode <T> > searching_nodes = new SimplePriorityQueue <CoverNode <T> >(); searching_nodes.Enqueue(node, 0); SpatialObj <T> answer = default(SpatialObj <T>); CoverNode <T> answer_node = null; bool used = false; double min_distance_sq = rootNode.GetMaxDistance(); while (searching_nodes.Count > 0) { CoverNode <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 (CoverNode <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); }
public bool StoreRectangle(SpatialObj <T> rect) { if (CanSink(rect)) { OverflowObjs.Add(rect); } else { StoredObjs.Add(rect); } return(IsOverflown()); }
public SpatialObj <T> FindNearestObjAndRemove(Point p) { SpatialObj <T> obj = default(SpatialObj <T>); CoverNode <T> node = null; foreach (KeyValuePair <CoverNode <T>, SpatialObj <T> > entry in FindNearestRectToPoint(p, rootNode)) { obj = entry.Value; node = entry.Key; } if (node != null) { return(RemoveRectangle(obj, node)); } return(obj); }
public SpatialObj <T> RemoveObject(SpatialObj <T> rect) { CoverNode <T> node = null; foreach (KeyValuePair <CoverNode <T>, SpatialObj <T> > entry in FindNearestRectToPoint(rect.boundingBox.Center, rootNode)) { if (entry.Value.Equals(rect)) { node = entry.Key; } } if (node != null) { return(RemoveRectangle(rect, node)); } return(rect); }
public CoverNode <T> FindContainingField(SpatialObj <T> rect, CoverNode <T> starting_node) { if (starting_node.IsPointInNode(rect.boundingBox.Center)) { bool contained_in_node = starting_node.IsObjectInNode(rect); if (contained_in_node && !starting_node.CanSink(rect)) { return(starting_node); } foreach (CoverNode <T> child in starting_node.GetChildren()) { var potential_node = FindContainingField(rect, child); if (potential_node != null) { return(potential_node); } } if (contained_in_node) { return(starting_node); } } return(null); }
public void SetObj(SpatialObj <T> o) { obj = o; isNode = false; }
public bool IsObjectInNode(SpatialObj <T> obj) { return(GetOperatingBounds().ContainsRect(obj.boundingBox)); }
/// <summary> /// Finds and removes the given object from the tree. /// </summary> /// <param name="obj">Spatial object to be removed from the tree.</param> public void Remove(T obj) { SpatialObj <T> s_obj = new SpatialObj <T>(obj); fieldTree.RemoveObject(s_obj); }
/// <summary> /// Adds an object to the tree. /// </summary> /// <param name="obj">Spatial type object to be added to the tree. Must implement ISpatial interface.</param> public void Add(T obj) { SpatialObj <T> s_obj = new SpatialObj <T>(obj); fieldTree.AddRectangle(s_obj); }