Example #1
0
        /// <summary>
        /// Find the nearest N elements in the KD Tree to the specified element.
        /// </summary>
        /// <param name="_item">The item to search for</param>
        /// <param name="_count">The number of closest elements to return</param>
        /// <returns>
        /// An enumeration of the closest N elements to the item specified
        /// </returns>
        public IEnumerable <T> FindNearest(T _item, int _count)
        {
            if (ExploredNodes != null)
            {
                ExploredNodes.Clear();
            }

            var closest = new ClosestObjects <T>(_count);

            FindNearest(_item, 0, 0, closest);
            return(closest.GetClosestObjects());
        }
Example #2
0
        /// <summary>
        /// Find all items that are within a certain distance of an item
        /// </summary>
        /// <param name="_item">The item to find close other items for</param>
        /// <param name="_maxDistance">The maximum distance from _item to include</param>
        /// <returns>
        /// An enumeration of objects that are closer than _distance to _item
        /// </returns>
        public IEnumerable <T> FindClose(T _item, double _maxDistance)
        {
            if (ExploredNodes != null)
            {
                ExploredNodes.Clear();
            }

            var closest = new ClosestObjects <T>(_maxDistance);

            FindNearest(_item, 0, 0, closest);
            return(closest.GetClosestObjects());
        }
Example #3
0
        /// <summary>
        /// Find the nearest element in the KD Tree to the specified element.
        /// </summary>
        /// <param name="_item">The item to search for</param>
        /// <returns>The closest node in the KD tree to the node specified</returns>
        public T FindNearest(T _item)
        {
            if (ExploredNodes != null)
            {
                ExploredNodes.Clear();
            }

            var closest = new ClosestObjects <T>();

            FindNearest(_item, 0, 0, closest);
            return(closest.GetClosestSingle());
        }
Example #4
0
        /// <summary>
        /// Internal method for finding the closest N items to some item
        /// </summary>
        /// <param name="_item">The item to search for</param>
        /// <param name="_nodeIdx">The index of the node to start searching</param>
        /// <param name="_axis">The axis of the node at the index specified</param>
        /// <param name="_closest">A collection of close and valid nodes</param>
        private void FindNearest(T _item, int _nodeIdx, int _axis, ClosestObjects <T> _closest)
        {
            var currentItem = m_tree[_nodeIdx];

            // we are below a leaf node, so the parent IS the leaf node to kick off the
            // unwinding of the recursion
            if (currentItem == null)
            {
                return;
            }

            var nextAxis         = (_axis + 1) % m_axisCount;
            var itemCoord        = m_selector(_item, _axis);
            var currentNodeCoord = m_selector(currentItem, _axis);

            var nextIdx = m_tree.GetLeftIndex(_nodeIdx);

            if (itemCoord > currentNodeCoord) // actually need the...
            {
                nextIdx++;                    // ... right child
            }
            FindNearest(_item, nextIdx, nextAxis, _closest);

            var thisDist             = m_distanceFunction(currentItem, _item);
            var worstClosestDistance = _closest.Add(currentItem, thisDist);

            if (ExploredNodes != null) // for debugging
            {
                ExploredNodes.Add(currentItem);
            }

            var distFromAxis = itemCoord - currentNodeCoord;

            // This deals with the SQUARE of the distances- Could be more flexible
            distFromAxis *= distFromAxis;

            // The item is closer to the axis than the worst closest node in _closest
            if (distFromAxis < worstClosestDistance)
            {
                // so now we need to check the opposite side of the tree at the current node

                // The sibling is either one element after, or one element before, depending
                // on the coordinate relative to "_item"'s coordinate
                var siblingIndex = (itemCoord > currentNodeCoord) ? nextIdx - 1 : nextIdx + 1;

                // ... and go down that side of the tree
                FindNearest(_item, siblingIndex, nextAxis, _closest);
            }
        }