Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }