예제 #1
0
        /// <summary>
        /// Adds the given item to the given box.
        /// </summary>
        /// <param name="leaf"></param>
        /// <param name="box"></param>
        /// <param name="item"></param>
        /// <param name="minimumSize"></param>
        /// <param name="maximumSize"></param>
        private static Node Add(Node leaf, BoxF2D box, T item, int minimumSize, int maximumSize)
        {
            if (box == null)
            {
                throw new ArgumentNullException("box");
            }
            if (leaf == null)
            {
                throw new ArgumentNullException("leaf");
            }

            Node ll = null;

            if (leaf.Boxes.Count == maximumSize)
            { // split the node.
                // add the child.
                leaf.Boxes.Add(box);
                leaf.Children.Add(item);

                Node[] split = RTreeMemoryIndex <T> .SplitNode(leaf, minimumSize);

                leaf.Boxes    = split[0].Boxes;
                leaf.Children = split[0].Children;
                RTreeMemoryIndex <T> .SetParents(leaf);

                ll = split[1];
            }
            else
            {
                // add the child.
                leaf.Boxes.Add(box);
                leaf.Children.Add(item);
            }

            // adjust the tree.
            Node n  = leaf;
            Node nn = ll;

            while (n.Parent != null)
            {                                           // keep going until the root is reached.
                Node p = n.Parent;
                RTreeMemoryIndex <T> .TightenFor(p, n); // tighten the parent box around n.

                if (nn != null)
                {     // propagate split if needed.
                    if (p.Boxes.Count == maximumSize)
                    { // parent needs to be split.
                        p.Boxes.Add(nn.GetBox());
                        p.Children.Add(nn);
                        Node[] split = RTreeMemoryIndex <T> .SplitNode(
                            p, minimumSize);

                        p.Boxes    = split[0].Boxes;
                        p.Children = split[0].Children;
                        RTreeMemoryIndex <T> .SetParents(p);

                        nn = split[1];
                    }
                    else
                    { // add the other 'split' node.
                        p.Boxes.Add(nn.GetBox());
                        p.Children.Add(nn);
                        nn.Parent = p;
                        nn        = null;
                    }
                }
                n = p;
            }
            if (nn != null)
            { // create a new root node and
                var root = new Node();
                root.Boxes = new List <BoxF2D>();
                root.Boxes.Add(n.GetBox());
                root.Boxes.Add(nn.GetBox());
                root.Children = new List <Node>();
                root.Children.Add(n);
                n.Parent = root;
                root.Children.Add(nn);
                nn.Parent = root;
                return(root);
            }
            return(null); // no new root node needed.
        }
예제 #2
0
        private static RTreeMemoryIndex <T> .Node Add(RTreeMemoryIndex <T> .Node leaf, BoxF2D box, T item, int minimumSize, int maximumSize)
        {
            if (box == null)
            {
                throw new ArgumentNullException("box");
            }
            if (leaf == null)
            {
                throw new ArgumentNullException("leaf");
            }
            RTreeMemoryIndex <T> .Node node1 = (RTreeMemoryIndex <T> .Node)null;
            if (leaf.Boxes.Count == maximumSize)
            {
                leaf.Boxes.Add(box);
                leaf.Children.Add((object)item);
                RTreeMemoryIndex <T> .Node[] nodeArray = RTreeMemoryIndex <T> .SplitNode(leaf, minimumSize);

                leaf.Boxes    = nodeArray[0].Boxes;
                leaf.Children = nodeArray[0].Children;
                RTreeMemoryIndex <T> .SetParents(leaf);

                node1 = nodeArray[1];
            }
            else
            {
                leaf.Boxes.Add(box);
                leaf.Children.Add((object)item);
            }
            RTreeMemoryIndex <T> .Node child = leaf;
            RTreeMemoryIndex <T> .Node node2 = node1;
            RTreeMemoryIndex <T> .Node parent;
            for (; child.Parent != null; child = parent)
            {
                parent = child.Parent;
                RTreeMemoryIndex <T> .TightenFor(parent, child);

                if (node2 != null)
                {
                    if (parent.Boxes.Count == maximumSize)
                    {
                        parent.Boxes.Add(node2.GetBox());
                        parent.Children.Add((object)node2);
                        RTreeMemoryIndex <T> .Node[] nodeArray = RTreeMemoryIndex <T> .SplitNode(parent, minimumSize);

                        parent.Boxes    = nodeArray[0].Boxes;
                        parent.Children = nodeArray[0].Children;
                        RTreeMemoryIndex <T> .SetParents(parent);

                        node2 = nodeArray[1];
                    }
                    else
                    {
                        parent.Boxes.Add(node2.GetBox());
                        parent.Children.Add((object)node2);
                        node2.Parent = parent;
                        node2        = (RTreeMemoryIndex <T> .Node)null;
                    }
                }
            }
            if (node2 == null)
            {
                return((RTreeMemoryIndex <T> .Node)null);
            }
            RTreeMemoryIndex <T> .Node node3 = new RTreeMemoryIndex <T> .Node();

            node3.Boxes = new List <BoxF2D>();
            node3.Boxes.Add(child.GetBox());
            node3.Boxes.Add(node2.GetBox());
            node3.Children = (IList) new List <RTreeMemoryIndex <T> .Node>();
            node3.Children.Add((object)child);
            child.Parent = node3;
            node3.Children.Add((object)node2);
            node2.Parent = node3;
            return(node3);
        }