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 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);
                    }
                }
            }
        }