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);
        }
示例#3
0
        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));
        }
示例#6
0
        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);
        }
示例#8
0
 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;
 }
示例#13
0
 public bool IsObjectInNode(SpatialObj <T> obj)
 {
     return(GetOperatingBounds().ContainsRect(obj.boundingBox));
 }
示例#14
0
        /// <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);
        }
示例#15
0
        /// <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);
        }