예제 #1
0
        public void search(SearchRecord sr)
        {
            // the core search routine.
            // This uses true distance to bounding box as the
            // criterion to search the secondary node.
            //
            // This results in somewhat fewer searches of the secondary nodes
            // than 'search', which uses the vdiff vector,  but as this
            // takes more computational time, the overall performance may not
            // be improved in actual run time.
            //

            if ((ChildLeft == null) && (ChildRight == null))
            {
                // we are on a leaf node
                if (sr.NumberOfNeighbours == 0)
                {
                    process_leaf_node_fixedball(sr);
                }
                else
                {
                    process_leaf_node(sr);
                }
            }
            else
            {
                KDTreeNodeKennell ncloser;
                KDTreeNodeKennell nfarther;

                float extra;
                float qval = sr.VectorTarget[cutAxis];
                // value of the wall boundary on the cut dimension.
                if (qval < cut_val)
                {
                    ncloser  = ChildLeft;
                    nfarther = ChildRight;
                    extra    = cut_val_right - qval;
                }
                else
                {
                    ncloser  = ChildRight;
                    nfarther = ChildLeft;
                    extra    = qval - cut_val_left;
                };

                if (ncloser != null)
                {
                    ncloser.search(sr);
                }

                if ((nfarther != null) && (extra * extra < sr.Radius))
                {
                    // first cut
                    if (nfarther.box_in_search_range(sr))
                    {
                        nfarther.search(sr);
                    }
                }
            }
        }
예제 #2
0
        ///// <summary>
        ///// number of search result
        ///// </summary>
        ///// <param name="qv"></param>
        ///// <param name="r2"></param>
        ///// <returns></returns>
        //public int r_count(Vector3 qv, float r2)
        //{
        //    {
        //        // search for all within a ball of a certain radius
        //        ListKDTreeResultVectors result = new ListKDTreeResultVectors();
        //        SearchRecord sr = new SearchRecord(qv, this, result);

        //        sr.IndexCenter = -1;
        //        sr.correltime = 0;
        //        sr.IndexNeighbour = 0;
        //        sr.Ballsize = r2;

        //        root.search(sr);
        //        return (result.Count);
        //    }


        //}
        public ListKDTreeResultVectors r_nearest_around_point(int idxin, int correltime, float r2)
        {
            ListKDTreeResultVectors result = new ListKDTreeResultVectors();
            Vector3 qv = TreeVectors[idxin].Vector.Clone(); //  query vector


            // copy the query vector.


            SearchRecord sr = new SearchRecord(qv);

            // construct the search record.

            sr.Radius             = r2;
            sr.NumberOfNeighbours = 0;
            root.search(sr);


            //if (sort_results)
            //{
            //    result.So
            //    sort(result.begin(), result.end());
            //}

            return(sr.SearchResult);
        }
예제 #3
0
        public ListKDTreeResultVectors n_nearest_around_point(int idxin, int correltime, int numberOfNeighbours)
        {
            Vector3 qv = new Vector3();

            qv = TreeVectors[idxin].Vector.Clone();

            // copy the query vector.


            SearchRecord sr = new SearchRecord(qv);

            // construct the search record.
            //sr.IndexCenter = idxin;
            //sr.correltime = correltime;
            sr.NumberOfNeighbours = numberOfNeighbours;
            root.search(sr);


            //if (sort_results)
            //{
            //    sort(result.begin(), result.end());
            //}
            //            ListKDTreeResultVectors result = new ListKDTreeResultVectors();

            return(sr.SearchResult);
        }
예제 #4
0
        public ListKDTreeResultVectors Find_N_Nearest(Vector3 qv, int numberOfNeighbours)
        {
            SearchRecord sr = new SearchRecord(qv);

            sr.NumberOfNeighbours = numberOfNeighbours;

            root.search(sr);
            return(sr.SearchResult);
        }
예제 #5
0
        public void FindClosestPoints_Radius(VertexKDTree vertex, float radius, ref int neighboursCount)
        {
            // search for all within a ball of a certain radius
            //ListKDTreeResultVectors result = new ListKDTreeResultVectors();

            SearchRecord sr = new SearchRecord(vertex.Vector);

            // Vector3 vdiff = new Vector3();

            sr.Radius = radius;

            root.search(sr);

            ListKDTreeResultVectors listResult = sr.SearchResult;

            neighboursCount = listResult.Count;
        }
예제 #6
0
        public ListKDTreeResultVectors r_nearest(Vector3 qv, float r2)
        {
            // search for all within a ball of a certain radius
            //ListKDTreeResultVectors result = new ListKDTreeResultVectors();

            SearchRecord sr = new SearchRecord(qv);

            // Vector3 vdiff = new Vector3();



            sr.NumberOfNeighbours = 0;
            sr.Radius             = r2;

            root.search(sr);

            //if (sort_results)
            //{
            //    sort(result.begin(), result.end());
            //}
            return(sr.SearchResult);
        }
예제 #7
0
        public bool box_in_search_range(SearchRecord sr)
        {
            //
            // does the bounding box, represented by minbox[*],maxbox[*]
            // have any point which is within 'sr.ballsize' to 'sr.qv'??
            //


            float dis2     = 0.0F;
            float ballsize = sr.Radius;

            for (int i = 0; i < 3; i++)
            {
                float f = dis_from_bnd(sr.VectorTarget[i], box[i].lower, box[i].upper);

                dis2 += f * f;
                if (dis2 > ballsize)
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #8
0
        public void process_leaf_node_fixedball(SearchRecord sr)
        {
            float ballsize = sr.Radius;
            //
            bool rearrange = sr.rearrange;

            for (int i = IndexLeafVector; i <= endIndex; i++)
            {
                uint  indexofi = this.Parent.Indices[i];
                float distance;
                bool  early_exit;

                if (rearrange)
                {
                    early_exit = false;
                    distance   = 0.0F;
                    for (int k = 0; k < 3; k++)
                    {
                        float f = this.Parent.TreeVectors[i].Vector[k] - sr.VectorTarget[k];
                        distance += f * f;
                        if (distance > ballsize)
                        {
                            early_exit = true;
                            break;
                        }
                    }
                    if (early_exit)
                    {
                        continue; // next iteration of mainloop
                    }
                    // why do we do things like this?  because if we take an early
                    // exit (due to distance being too large) which is common, then
                    // we need not read in the actual point index, thus saving main
                    // memory bandwidth.  If the distance to point is less than the
                    // ballsize, though, then we need the index.
                    //
                    indexofi = this.Parent.Indices[i];
                }
                else
                {
                    //
                    // but if we are not using the rearranged data, then
                    // we must always
                    indexofi   = this.Parent.Indices[i];
                    early_exit = false;
                    distance   = 0.0F;
                    for (int k = 0; k < 3; k++)
                    {
                        float f = this.Parent.TreeVectors[Convert.ToInt32(indexofi)].Vector[k] - sr.VectorTarget[k];
                        distance += f * f;
                        if (distance > ballsize)
                        {
                            early_exit = true;
                            break;
                        }
                    }
                    if (early_exit)
                    {
                        continue; // next iteration of mainloop
                    }
                } // end if rearrange.


                KDTreeResult e = new KDTreeResult(indexofi, distance);

                //sr.result.push_back(e);

                sr.SearchResult.Add(e);
            }
        }
예제 #9
0
        public void process_leaf_node(SearchRecord sr)
        {
            float ballsize = sr.Radius;
            //
            bool rearrange = sr.rearrange;

            for (int i = IndexLeafVector; i <= endIndex; i++)
            {
                uint  indexofi; // sr.ind[i];
                float distance;

                if (rearrange)
                {
                    if (CheckDistance(this.Parent.TreeVectors[i].Vector, sr.VectorTarget, ballsize, out distance))
                    {
                        continue;// next iteration of mainloop
                    }
                    // why do we do things like this?  because if we take an early
                    // exit (due to distance being too large) which is common, then
                    // we need not read in the actual point index, thus saving main
                    // memory bandwidth.  If the distance to point is less than the
                    // ballsize, though, then we need the index.
                    //
                    indexofi = this.Parent.Indices[i];
                }
                else
                {
                    //
                    // but if we are not using the rearranged data, then
                    // we must always compare all
                    indexofi = this.Parent.Indices[i];

                    if (CheckDistance(this.Parent.TreeVectors[Convert.ToInt32(indexofi)].Vector, sr.VectorTarget, ballsize, out distance))
                    {
                        continue;// next iteration of mainloop
                    }
                } // end if rearrange.

                // here the point must be added to the list.
                //
                // two choices for any point.  The list so far is either
                // undersized, or it is not.
                //
                if (sr.SearchResult.Count < sr.NumberOfNeighbours)
                {
                    KDTreeResult e = new KDTreeResult(indexofi, distance);
                    if (!this.Parent.TakenAlgorithm)
                    {
                        sr.SearchResult.Add(e);
                        if (sr.SearchResult.Count == sr.NumberOfNeighbours)
                        {
                            ballsize = sr.SearchResult[0].Distance;
                        }
                    }
                    else
                    {
                        if (!this.Parent.TreeVectors[Convert.ToInt32(indexofi)].TakenInTree)
                        {
                            this.Parent.TreeVectors[Convert.ToInt32(indexofi)].TakenInTree = true;
                            sr.SearchResult.Add(e);
                            if (sr.SearchResult.Count == sr.NumberOfNeighbours)
                            {
                                ballsize = sr.SearchResult[0].Distance;
                            }
                        }
                        else
                        {
                        }
                    }
                    // Set the ball radius to the largest on the list (maximum priority).
                }
                else
                {
                    //
                    // if we get here then the current node, has a squared
                    // distance smaller
                    // than the last on the list, and belongs on the list.
                    //
                    KDTreeResult e = new KDTreeResult(indexofi, distance);

                    ballsize = sr.SearchResult.ReplaceLast_ReturnFirst(e);
                }
                if (distance == 0f)
                {
                    break;
                }
            } // main loop
            sr.Radius = ballsize;
        }