private IKDTreeDomain NearestNeighbourListBBFI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, float maxDistSq, out float resDistSq, SortedLimitedList searchHr, ref int searchSteps) { //Console.WriteLine ("C NearestNeighbourI called"); 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; // step 5-7 if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } // step 8 IKDTreeDomain nearest = null; float distSq; searchHr.Add(new HREntry(furtherHr, furtherKd, pivot, furtherHr.Distance(target))); // No child, bottom reached! if (nearerKd == null) { distSq = Int32.MaxValue; } else { nearest = nearerKd.NearestNeighbourListBBFI(best, q, target, nearerHr, maxDistSq, out distSq, searchHr, ref searchSteps); } // step 9 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; } // step 10 searchSteps -= 1; if (searchSteps > 0 && furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { float ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { // steps 10.1.1 to 10.1.3 nearest = pivot; distSq = ptDistSq; maxDistSq = distSq; } // step 10.2 float tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Int32.MaxValue; } else { tempNearest = furtherKd.NearestNeighbourListBBFI(best, q, target, furtherHr, maxDistSq, out tempDistSq, searchHr, ref searchSteps); } // step 10.3 if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }
private IKDTreeDomain NearestNeighbourListI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, double maxDistSq, out double resDistSq) { //Console.WriteLine ("C NearestNeighbourI called"); resDistSq = Double.PositiveInfinity; IKDTreeDomain pivot = dr; best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr))); HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; // step 5-7 if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } // step 8 IKDTreeDomain nearest = null; double distSq; // No child, bottom reached! if (nearerKd == null) { distSq = Double.PositiveInfinity; } else { nearest = nearerKd.NearestNeighbourListI(best, q, target, nearerHr, maxDistSq, out distSq); } // step 9 //maxDistSq = Math.Min (maxDistSq, distSq); if (best.Count >= q) { maxDistSq = ((BestEntry)best[q - 1]).Distance; } else { maxDistSq = Double.PositiveInfinity; } // step 10 if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { double ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { // steps 10.1.1 to 10.1.3 nearest = pivot; distSq = ptDistSq; // TODO: use k-element list /* * best.Add (new BestEntry (pivot, ptDistSq)); * best.Sort (); */ maxDistSq = distSq; } // step 10.2 double tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Double.PositiveInfinity; } else { tempNearest = furtherKd.NearestNeighbourListI(best, q, target, furtherHr, maxDistSq, out tempDistSq); } // step 10.3 if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }