private IKDTreeDomain NearestNeighbourListBBFI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, int maxDistSq, out int resDistSq, SortedLimitedList searchHr, ref int searchSteps) { resDistSq = Int32.MaxValue; IKDTreeDomain pivot = dr; best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr), true)); HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } IKDTreeDomain nearest = null; int distSq; searchHr.Add(new HREntry(furtherHr, furtherKd, pivot, furtherHr.Distance(target))); if (nearerKd == null) { distSq = Int32.MaxValue; } else { nearest = nearerKd.NearestNeighbourListBBFI(best, q, target, nearerHr, maxDistSq, out distSq, searchHr, ref searchSteps); } if (best.Count >= q) { maxDistSq = ((BestEntry)best[q - 1]).DistanceSq; } else { maxDistSq = Int32.MaxValue; } if (searchHr.Count > 0) { HREntry hre = (HREntry)searchHr[0]; searchHr.RemoveAt(0); furtherHr = hre.HR; furtherKd = hre.Tree; pivot = hre.Pivot; } searchSteps -= 1; if (searchSteps > 0 && furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { int ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { nearest = pivot; distSq = ptDistSq; maxDistSq = distSq; } int tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Int32.MaxValue; } else { tempNearest = furtherKd.NearestNeighbourListBBFI(best, q, target, furtherHr, maxDistSq, out tempDistSq, searchHr, ref searchSteps); } if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }