Exemple #1
0
        /// <summary>
        /// Splits the given node in two other nodes.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="minimumSize"></param>
        /// <returns></returns>
        private static Node[] SplitNode(Node node, int minimumSize)
        {
            bool leaf = (node.Children is List <T>);

            // create the target nodes.
            var nodes = new Node[2];

            nodes[0]       = new Node();
            nodes[0].Boxes = new List <BoxF2D>();
            if (leaf)
            {
                nodes[0].Children = new List <T>();
            }
            else
            {
                nodes[0].Children = new List <Node>();
            }
            nodes[1]       = new Node();
            nodes[1].Boxes = new List <BoxF2D>();
            if (leaf)
            {
                nodes[1].Children = new List <T>();
            }
            else
            {
                nodes[1].Children = new List <Node>();
            }

            // select the seed boxes.
            int[] seeds = RTreeMemoryIndex <T> .SelectSeeds(node.Boxes);

            // add the boxes.
            nodes[0].Boxes.Add(node.Boxes[seeds[0]]);
            nodes[1].Boxes.Add(node.Boxes[seeds[1]]);
            nodes[0].Children.Add(node.Children[seeds[0]]);
            nodes[1].Children.Add(node.Children[seeds[1]]);

            // create the boxes.
            var boxes = new BoxF2D[2]
            {
                node.Boxes[seeds[0]], node.Boxes[seeds[1]]
            };

            node.Boxes.RemoveAt(seeds[0]); // seeds[1] is always < seeds[0].
            node.Boxes.RemoveAt(seeds[1]);
            node.Children.RemoveAt(seeds[0]);
            node.Children.RemoveAt(seeds[1]);

            while (node.Boxes.Count > 0)
            {
                // check if one of them needs em all!
                if (nodes[0].Boxes.Count + node.Boxes.Count == minimumSize)
                { // all remaining boxes need te be assigned here.
                    for (int idx = 0; node.Boxes.Count > 0; idx++)
                    {
                        boxes[0] = boxes[0].Union(node.Boxes[0]);
                        nodes[0].Boxes.Add(node.Boxes[0]);
                        nodes[0].Children.Add(node.Children[0]);

                        node.Boxes.RemoveAt(0);
                        node.Children.RemoveAt(0);
                    }
                }
                else if (nodes[1].Boxes.Count + node.Boxes.Count == minimumSize)
                { // all remaining boxes need te be assigned here.
                    for (int idx = 0; node.Boxes.Count > 0; idx++)
                    {
                        boxes[1] = boxes[1].Union(node.Boxes[0]);
                        nodes[1].Boxes.Add(node.Boxes[0]);
                        nodes[1].Children.Add(node.Children[0]);

                        node.Boxes.RemoveAt(0);
                        node.Children.RemoveAt(0);
                    }
                }
                else
                { // choose one of the leaves.
                    int leafIdx;
                    int nextId = RTreeMemoryIndex <T> .PickNext(boxes, node.Boxes, out leafIdx);

                    boxes[leafIdx] = boxes[leafIdx].Union(node.Boxes[nextId]);

                    nodes[leafIdx].Boxes.Add(node.Boxes[nextId]);
                    nodes[leafIdx].Children.Add(node.Children[nextId]);

                    node.Boxes.RemoveAt(nextId);
                    node.Children.RemoveAt(nextId);
                }
            }

            RTreeMemoryIndex <T> .SetParents(nodes[0]);

            RTreeMemoryIndex <T> .SetParents(nodes[1]);

            return(nodes);
        }
Exemple #2
0
        private static RTreeMemoryIndex <T> .Node[] SplitNode(RTreeMemoryIndex <T> .Node node, int minimumSize)
        {
            int num1 = node.Children is List <T>? 1 : 0;

            RTreeMemoryIndex <T> .Node[] nodeArray = new RTreeMemoryIndex <T> .Node[2]
            {
                new RTreeMemoryIndex <T> .Node(),
                null
            };
            nodeArray[0].Boxes    = new List <BoxF2D>();
            nodeArray[0].Children = num1 == 0 ? (IList) new List <RTreeMemoryIndex <T> .Node>() : (IList) new List <T>();
            nodeArray[1]          = new RTreeMemoryIndex <T> .Node();

            nodeArray[1].Boxes    = new List <BoxF2D>();
            nodeArray[1].Children = num1 == 0 ? (IList) new List <RTreeMemoryIndex <T> .Node>() : (IList) new List <T>();
            int[] numArray = RTreeMemoryIndex <T> .SelectSeeds(node.Boxes);

            nodeArray[0].Boxes.Add(node.Boxes[numArray[0]]);
            nodeArray[1].Boxes.Add(node.Boxes[numArray[1]]);
            nodeArray[0].Children.Add(node.Children[numArray[0]]);
            nodeArray[1].Children.Add(node.Children[numArray[1]]);
            BoxF2D[] nodeBoxes = new BoxF2D[2]
            {
                node.Boxes[numArray[0]],
                node.Boxes[numArray[1]]
            };
            node.Boxes.RemoveAt(numArray[0]);
            node.Boxes.RemoveAt(numArray[1]);
            node.Children.RemoveAt(numArray[0]);
            node.Children.RemoveAt(numArray[1]);
            while (node.Boxes.Count > 0)
            {
                if (nodeArray[0].Boxes.Count + node.Boxes.Count == minimumSize)
                {
                    int num2 = 0;
                    while (node.Boxes.Count > 0)
                    {
                        nodeBoxes[0] = nodeBoxes[0].Union(node.Boxes[0]);
                        nodeArray[0].Boxes.Add(node.Boxes[0]);
                        nodeArray[0].Children.Add(node.Children[0]);
                        node.Boxes.RemoveAt(0);
                        node.Children.RemoveAt(0);
                        ++num2;
                    }
                }
                else if (nodeArray[1].Boxes.Count + node.Boxes.Count == minimumSize)
                {
                    int num2 = 0;
                    while (node.Boxes.Count > 0)
                    {
                        nodeBoxes[1] = nodeBoxes[1].Union(node.Boxes[0]);
                        nodeArray[1].Boxes.Add(node.Boxes[0]);
                        nodeArray[1].Children.Add(node.Children[0]);
                        node.Boxes.RemoveAt(0);
                        node.Children.RemoveAt(0);
                        ++num2;
                    }
                }
                else
                {
                    int nodeBoxIndex;
                    int index = RTreeMemoryIndex <T> .PickNext(nodeBoxes, (IList <BoxF2D>) node.Boxes, out nodeBoxIndex);

                    nodeBoxes[nodeBoxIndex] = nodeBoxes[nodeBoxIndex].Union(node.Boxes[index]);
                    nodeArray[nodeBoxIndex].Boxes.Add(node.Boxes[index]);
                    nodeArray[nodeBoxIndex].Children.Add(node.Children[index]);
                    node.Boxes.RemoveAt(index);
                    node.Children.RemoveAt(index);
                }
            }
            RTreeMemoryIndex <T> .SetParents(nodeArray[0]);

            RTreeMemoryIndex <T> .SetParents(nodeArray[1]);

            return(nodeArray);
        }
Exemple #3
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.
        }
Exemple #4
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);
        }