Beispiel #1
0
        /// <summary>
        /// This is a recursive method which is responsible for integration the specified
        /// node inside the tree.
        /// </summary>
        private void IntegrateTerminalNodeRecurse(SphereTreeNode <T> nodeToIntegrate, SphereTreeNode <T> parentNode)
        {
            // If this node still has room for children, we will add the integration node here. This 'if' statement
            // will also handle the special case in which only the root node currently exists inside the tree.
            if (parentNode.NumberOfChildren < _numberOfChildNodesPerNode)
            {
                // Add the node as a child of the parent node and ensure that the root node encapsulates it
                parentNode.AddChild(nodeToIntegrate);
                parentNode.EncapsulateChildNode(nodeToIntegrate);
            }
            else
            {
                // If there is no more room, we will proceed by choosing one of the parent's children which
                // is closest to the node that we want to integrate. We choose the closest node because when
                // the node will be added as a child of it, we want the parent to grow as little as possible.
                List <SphereTreeNode <T> > children     = parentNode.Children;
                SphereTreeNode <T>         closestChild = FindClosestNode(children, nodeToIntegrate);
                if (closestChild == null)
                {
                    return;
                }

                // If the closest child is not a terminal node, recurse.
                if (!closestChild.IsTerminal)
                {
                    IntegrateTerminalNodeRecurse(nodeToIntegrate, closestChild);
                }
                else
                {
                    // If we reached a terminal node, we create a new node which encapsulates 'closestChild' and 'nodeToIntegrate'
                    // and then we replace 'closestChild' with this new node. The first step is to create the sphere of this
                    // new node. It doesn't matter how big this sphere is initially because we will call 'EncapsulateChildNode'
                    // later.
                    Sphere newNodeSphere = closestChild.Sphere;

                    // Create the node using the sphere we just calculated
                    SphereTreeNode <T> newNode = new SphereTreeNode <T>(newNodeSphere, this, default(T));
                    newNode.SetFlag(SphereTreeNodeFlags.SuperSphere);

                    // Replace 'closestChild' with the new node and add both 'closestChild' and 'nodeToIntegrate' as children of it
                    parentNode.RemoveChild(closestChild);
                    parentNode.AddChild(newNode);
                    newNode.AddChild(nodeToIntegrate);
                    newNode.AddChild(closestChild);

                    // Encapsulate the children inside the new node
                    newNode.EncapsulateChildNode(closestChild);
                    newNode.EncapsulateChildNode(nodeToIntegrate);

                    // Ensure that the new node is fully contained inside the parent node
                    parentNode.EncapsulateChildNode(newNode);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates the tree nodes from the specified list of serialized nodes.
        /// </summary>
        /// <returns>
        /// The tree root node.
        /// </returns>
        private SphereTreeNode <T> CreateTreeNodesFromSerializedNodes <SerializableNodeType>(List <SerializableNodeType> serializedNodes) where SerializableNodeType : SerializableSphereTreeNode <T>, new()
        {
            var allNodes = new List <SphereTreeNode <T> >();

            foreach (var serializedNode in serializedNodes)
            {
                // Create the actual node instance and store it in the node list
                var node = new SphereTreeNode <T>(new Sphere(serializedNode.SphereCenter, serializedNode.SphereRadius), this, serializedNode.NodeData);
                node.SetFlag(serializedNode.Flags);
                allNodes.Add(node);

                // If the node has a parent, establish the parent-child relationship
                if (serializedNode.ParentNodeIndex >= 0)
                {
                    SphereTreeNode <T> parentNode = allNodes[serializedNode.ParentNodeIndex];
                    parentNode.AddChild(node);
                }
            }

            // Return the root node
            return(allNodes[0]);
        }