Exemplo n.º 1
0
        /// <summary>
        /// Returns the closest node between currentBest and CurrentNode to point
        /// </summary>
        private KDTreeNode <T> getClosestToPoint(IDistanceCalculator <T> distanceCalculator,
                                                 KDTreeNode <T> currentBest, KDTreeNode <T> currentNode, T[] point)
        {
            if (distanceCalculator.Compare(currentBest.Points,
                                           currentNode.Points, point) < 0)
            {
                return(currentBest);
            }

            return(currentNode);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Recursively find leaf node to insert
        /// at each level comparing against the next dimension.
        /// </summary>
        private KDTreeNode <T> findNearestNeighbour(KDTreeNode <T> currentNode,
                                                    T[] searchPoint, int depth,
                                                    IDistanceCalculator <T> distanceCalculator)
        {
            var            currentDimension = depth % dimensions;
            KDTreeNode <T> currentBest      = null;

            var compareResult = searchPoint[currentDimension]
                                .CompareTo(currentNode.Points[currentDimension]);

            //move toward search point until leaf is reached
            if (compareResult < 0)
            {
                if (currentNode.Left != null)
                {
                    currentBest = findNearestNeighbour(currentNode.Left,
                                                       searchPoint, depth + 1, distanceCalculator);
                }
                else
                {
                    currentBest = currentNode;
                }

                //currentBest is greater than point to current node distance
                //or if right node sits on split plane
                //then also move left
                if (currentNode.Right != null &&
                    (distanceCalculator.Compare(currentNode.Points[currentDimension], searchPoint[currentDimension], searchPoint, currentBest.Points) < 0 ||
                     currentNode.Right.Points[currentDimension]
                     .CompareTo(currentNode.Points[currentDimension]) == 0))
                {
                    var rightBest = findNearestNeighbour(currentNode.Right,
                                                         searchPoint, depth + 1,
                                                         distanceCalculator);

                    currentBest = getClosestToPoint(distanceCalculator, currentBest, rightBest, searchPoint);
                }
                //now recurse up from leaf updating current Best
                currentBest = getClosestToPoint(distanceCalculator, currentBest, currentNode, searchPoint);
            }
            else if (compareResult >= 0)
            {
                if (currentNode.Right != null)
                {
                    currentBest = findNearestNeighbour(currentNode.Right,
                                                       searchPoint, depth + 1, distanceCalculator);
                }
                else
                {
                    currentBest = currentNode;
                }

                //currentBest is greater than point to current node distance
                //or if search point lies on split plane
                //then also move left
                if (currentNode.Left != null &&
                    (distanceCalculator.Compare(currentNode.Points[currentDimension], searchPoint[currentDimension], searchPoint, currentBest.Points) < 0 || compareResult == 0))
                {
                    var leftBest = findNearestNeighbour(currentNode.Left,
                                                        searchPoint, depth + 1,
                                                        distanceCalculator);

                    currentBest = getClosestToPoint(distanceCalculator, currentBest, leftBest, searchPoint);
                }

                //now recurse up from leaf updating current Best
                currentBest = getClosestToPoint(distanceCalculator, currentBest, currentNode, searchPoint);
            }


            return(currentBest);
        }