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