private void nearest(KDTreeNode <T> current, double[] position, KdTreeNodeCollection <T> list) { // Compute distance from this node to the point double d = _distance(position, current.Position); if (current.IsLeaf) { // Base: node is leaf list.Add(current, d); } else { // Check for leafs on the opposite sides of // the subtrees to nearest possible neighbors. // Prepare for recursion. The following null checks // will be used to avoid function calls if possible double value = position[current.Axis]; double median = current.Position[current.Axis]; if (value < median) { if (current.Left != null) { nearest(current.Left, position, list); } list.Add(current, d); if (current.Right != null) { if (Math.Abs(value - median) <= list.Distance.Max) { nearest(current.Right, position, list); } } } else { if (current.Right != null) { nearest(current.Right, position, list); } list.Add(current, d); if (current.Left != null) { if (Math.Abs(value - median) <= list.Distance.Max) { nearest(current.Left, position, list); } } } } }
private bool approximate(KDTreeNode <T> current, double[] position, KdTreeNodeCollection <T> list, int maxLeaves, ref int visited) { // Compute distance from this node to the point double d = _distance(position, current.Position); if (current.IsLeaf) { // Base: node is leaf list.Add(current, d); visited++; if (visited > maxLeaves) { return(true); } } else { // Check for leafs on the opposite sides of // the subtrees to nearest possible neighbors. // Prepare for recursion. The following null checks // will be used to avoid function calls if possible double value = position[current.Axis]; double median = current.Position[current.Axis]; if (value < median) { if (current.Left != null) { if (approximate(current.Left, position, list, maxLeaves, ref visited)) { return(true); } } list.Add(current, d); if (current.Right != null) { if (Math.Abs(value - median) <= list.Distance.Max) { if (approximate(current.Right, position, list, maxLeaves, ref visited)) { return(true); } } } } else { if (current.Right != null) { approximate(current.Right, position, list, maxLeaves, ref visited); } list.Add(current, d); if (current.Left != null) { if (Math.Abs(value - median) <= list.Distance.Max) { if (approximate(current.Left, position, list, maxLeaves, ref visited)) { return(true); } } } } } return(false); }