예제 #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);
        }
예제 #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);
        }