Example #1
0
        /// <summary>
        /// 指定ノードに葉ノードを追加する
        /// </summary>
        /// <param name="root">追加先ノード</param>
        /// <param name="leaf">追加する葉ノード</param>
        private void InsertLeaf(Node root, LeafNode leaf)
        {
            if (_Root == null)
            {
                // ツリーが空なら追加ノードをルートとする
                _Root       = leaf;
                leaf.Parent = null;
            }
            else
            {
                // 兄弟となる葉ノードを探す、境界ボリュームの距離が近い方へ辿っていく
                LeafNode   sibling = root.AsLeaf;
                BranchNode branch  = root.AsBranch;
                if (branch != null)
                {
                    var volume = leaf.Volume;
                    while (true)
                    {
                        var c = branch.GetChild(Select(volume, branch.Child1.Volume, branch.Child2.Volume));
                        sibling = c.AsLeaf;
                        if (sibling != null)
                        {
                            break;
                        }
                        branch = c.AsBranch;
                    }
                }

                // 追加ノードと兄弟ノードの親となるノードを作成
                var prev = sibling.Parent;
                branch = new BranchNode(prev, sibling, leaf);

                if (prev != null)
                {
                    // 見つかった兄弟ノードに親があるなら、親ノードの子をすり替えて根に向かって境界ボリュームを計算し直す
                    prev.SetChild(sibling.Index, branch);
                    sibling.Parent = branch;
                    leaf.Parent    = branch;
                    do
                    {
                        if (prev.Volume.Contains(branch.Volume))
                        {
                            break;
                        }
                        prev.UpdateVolume();
                        branch = prev;
                    } while (null != (prev = branch.Parent));
                }
                else
                {
                    // 見つかった兄弟ノードに親が無いなら、作成した親ノードをルートとする
                    sibling.Parent = branch;
                    leaf.Parent    = branch;
                    _Root          = branch;
                }
            }
        }