예제 #1
0
        //DOKU
        private void TraverseSearch(Point query,
                                    OctreeBox node, NeigbourCollector neighbours)
        {
            if (node.IsLeaf)
            {
                foreach (Point p in node.Points)
                {
                    neighbours.AddNeighbour(p);
                }
                return;
            }

            // not leaf
            foreach (OctreeBox subNode in node.SubBoxes)
            {
                double curMinSDist = subNode.MinimumSquareDistanceTo(query);
                //TODO that shit about the Neighbourlist count
                // is really, really crappy!
                if (neighbours.BestNeighbours.Count > 0 &&
                    curMinSDist > neighbours.LargestSquareDistance)
                {
                    continue;
                }

                TraverseSearch(query, subNode, neighbours);
            }
            return;
        }
예제 #2
0
        //DOKU
        public List <Point> ClosestNeighbours(Point query, int amount)
        {
            NeigbourCollector neighbours = new NeigbourCollector(query, amount);

            TraverseSearch(query, RootNode, neighbours);
            return(neighbours.BestNeighbours);
        }
예제 #3
0
        /// <summary>
        /// Recursive search for neighbours.
        /// </summary>
        /// <param name="query">center of the search</param>
        /// <param name="node">current checked node</param>
        /// <param name="depth">current recursion depth</param>
        /// <param name="neighbours">KDTreeNeighbours-object, collecting results of nm-search</param>
        private void NMSearch(Point query,
                              KDTreeNode node, int depth, NeigbourCollector neighbours)
        {
            // The NM-search does only look for potential neighbours. The
            // final decision if this node is to be returned or not will
            // be done by the KDTreeNeighbours-object

            // If there is no node, return.
            if (node == null)
            {
                return;
            }

            // If the node is a leaf, it will always be added to the neighbours-list
            if (node.IsLeaf())
            {
                neighbours.AddNeighbour(node.Point);
                return;
            }

            // locked to 3 axis
            int axis = depth % 3;

            // One subtree usually lies closer to the query point along the currently
            // viewed axis. This one is the close-tree. The other one is the far-tree.
            KDTreeNode farSubTree, closeSubTree;

            if (query[axis] < node.Point[axis])
            {
                farSubTree   = node.Right;
                closeSubTree = node.Left;
            }
            else
            {
                farSubTree   = node.Left;
                closeSubTree = node.Right;
            }

            // Search the close-tree first
            NMSearch(query, closeSubTree, depth + 1, neighbours);

            // Since the current point was not sortet out by the
            // previous recursion level, it needs to be added to
            // the neighbour list.
            neighbours.AddNeighbour(node.Point);

            // If the current 'boundary' lies closer to the query
            // point than the farest approved neighbour so far,
            // the other side of the boundary also needs to be
            // searched.
            if (System.Math.Pow(node.Point[axis] -
                                query[axis], 2) < neighbours.LargestSquareDistance)
            {
                NMSearch(query, farSubTree, depth + 1, neighbours);
            }

            return;
        }
예제 #4
0
        /// <summary>
        /// Returns the n closest neighbours to a query point.
        /// </summary>
        /// <param name="query">query point</param>
        /// <param name="amount">n, the amount of desired neighbours</param>
        /// <returns>The n closest neighbours to query</returns>
        public List <Point> FindClosestNeighbours(Point query, int amount)
        {
            // This method is just a "wrapper". The real search will be
            // done by NMSearch().
            // This approach was necessary to define and return the
            // neighbours list.

            NeigbourCollector neighbours = new NeigbourCollector(query, amount);

            NMSearch(query, RootNode, 0, neighbours);
            return(neighbours.BestNeighbours);
        }