/// <summary> /// Subdivide this node along the principal axis of its child objects /// </summary> public void Subdivide() { if (_Children != null && _Children.Count > 1) { double max; double min; CoordinateAxis largest = LargestDimension(_Children, out min, out max); int divisions = Math.Min(_Children.Count, Math.Min(_Tree.MaxDivisions, (int)Math.Floor(max - min / _Tree.MinCellSize) + 1)); if (divisions > 1) { _CellSize = (max - min) / (divisions - 1); _Origin = min - _CellSize / 2; _SplitDimension = largest; _Branches = new DDTreeNode <T> [divisions]; //Add all children to branches: foreach (T child in _Children) { AddToBranch(child, false); } //Subdivide children: for (int i = 0; i < _Branches.Length; i++) { DDTreeNode <T> node = _Branches[i]; if (node != null && node.Children.Count < Children.Count) { node.Subdivide(); } } } } }
/// <summary> /// Creates a new DDTree populated with the specified collection of objects /// </summary> /// <param name="items">The objects to include within the tree.</param> /// <param name="maxDivisions">The maximum number of cells into which each /// level in the tree should be divided</param> /// <param name="minCellSize">The minimum allowable size of a cell. Once a node /// reaches this size it will no longer subdivide regardless of how many items are /// contained within it.</param> /// <param name="maxLeafPopulation">The maximum population per leaf node. If the /// number of objects within a cell exceeds this number and the minimum cell size /// has not yet been reached, the node will subdivide</param> protected DDTree(IList <T> items, int maxDivisions = 10, double minCellSize = 1, int maxLeafPopulation = 4) { MaxDivisions = maxDivisions; MinCellSize = minCellSize; MaxLeafPopulation = maxLeafPopulation; _RootNode = new DDTreeNode <T>(this); foreach (T item in items) { _RootNode.Children.Add(item); } _RootNode.Subdivide(); }