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); list.Add(current, d); if (++visited > maxLeaves) { return(true); } // 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]; double u = value - median; if (u <= 0) { if (current.Left != null) { if (approximate(current.Left, position, list, maxLeaves, ref visited)) { return(true); } } if (current.Right != null && Math.Abs(u) <= list.Maximum) { if (approximate(current.Right, position, list, maxLeaves, ref visited)) { return(true); } } } else { if (current.Right != null) { approximate(current.Right, position, list, maxLeaves, ref visited); } if (current.Left != null && Math.Abs(u) <= list.Maximum) { if (approximate(current.Left, position, list, maxLeaves, ref visited)) { return(true); } } } return(false); }
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]; double u = (value - median); if (u < 0) { if (current.Left != null) { nearest(current.Left, position, list); } list.Add(current, d); if (current.Right != null) { if ((u * u) < 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 ((u * u) < list.Distance.Max) { nearest(current.Left, position, list); } } } } }
/// <summary> /// Retrieves a fixed point of nearest points to a given point. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="neighbors">The number of neighbors to retrieve.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public KDTreeNodeCollection<T> Nearest(double[] position, int neighbors) { var list = new KDTreeNodeCollection<T>(size: neighbors); if (root != null) nearest(root, position, list); return list; }
/// <summary> /// Retrieves a fixed point of nearest points to a given point. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="neighbors">The number of neighbors to retrieve.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public KDTreeNodeCollection <T> Nearest(double[] position, int neighbors) { var list = new KDTreeNodeCollection <T>(size: neighbors); if (root != null) { find(root, position, neighbors, list); } return(list); }
/// <summary> /// Retrieves the nearest points to a given point within a given radius. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="radius">The search radius.</param> /// <param name="maximum">The maximum number of neighbors to retrieve.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public KDTreeNodeCollection <T> Nearest(double[] position, double radius, int maximum) { var list = new KDTreeNodeCollection <T>(maximum); if (root != null) { find(root, position, radius, list); } return(list); }
/// <summary> /// Retrieves a fixed point of nearest points to a given point. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="neighbors">The number of neighbors to retrieve.</param> /// <param name="maxLeaves">The maximum number of leaf nodes that can /// be visited before the search finishes with an approximate answer.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public KDTreeNodeCollection <T> ApproximateNearest(double[] position, int neighbors, int maxLeaves) { var list = new KDTreeNodeCollection <T>(size: neighbors); if (root != null) { int visited = 0; approximate(root, position, list, maxLeaves, ref visited); } return(list); }
/// <summary> /// Retrieves a fixed point of nearest points to a given point. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="neighbors">The number of neighbors to retrieve.</param> /// <param name="percentage">The maximum percentage of leaf nodes that /// can be visited before the search finishes with an approximate answer.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public KDTreeNodeCollection<T> ApproximateNearest(double[] position, int neighbors, double percentage) { int maxLeaves = (int)(leaves * percentage); var list = new KDTreeNodeCollection<T>(size: neighbors); if (root != null) { int visited = 0; approximate(root, position, list, maxLeaves, ref visited); } return list; }
/// <summary> /// Retrieves the nearest points to a given point within a given radius. /// </summary> /// /// <param name="position">The queried point.</param> /// <param name="radius">The search radius.</param> /// <param name="maximum">The maximum number of neighbors to retrieve.</param> /// /// <returns>A list of neighbor points, ordered by distance.</returns> /// public ICollection<KDTreeNodeDistance<T>> Nearest(double[] position, double radius, int maximum) { if (maximum == 0) { var list = new KDTreeNodeList<T>(); if (root != null) nearest(root, position, radius, list); return list; } else { var list = new KDTreeNodeCollection<T>(maximum); if (root != null) nearest(root, position, radius, list); return list; } }