source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/ann_1.1.1/src/kd_fix_rad_search.cpp @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 7.2 KB
Line 
1//----------------------------------------------------------------------
2// File:                        kd_fix_rad_search.cpp
3// Programmer:          Sunil Arya and David Mount
4// Description:         Standard kd-tree fixed-radius kNN search
5// Last modified:       05/03/05 (Version 1.1)
6//----------------------------------------------------------------------
7// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
8// David Mount.  All Rights Reserved.
9//
10// This software and related documentation is part of the Approximate
11// Nearest Neighbor Library (ANN).  This software is provided under
12// the provisions of the Lesser GNU Public License (LGPL).  See the
13// file ../ReadMe.txt for further information.
14//
15// The University of Maryland (U.M.) and the authors make no
16// representations about the suitability or fitness of this software for
17// any purpose.  It is provided "as is" without express or implied
18// warranty.
19//----------------------------------------------------------------------
20// History:
21//      Revision 1.1  05/03/05
22//              Initial release
23//----------------------------------------------------------------------
24
25#include "kd_fix_rad_search.h"                  // kd fixed-radius search decls
26
27//----------------------------------------------------------------------
28//      Approximate fixed-radius k nearest neighbor search
29//              The squared radius is provided, and this procedure finds the
30//              k nearest neighbors within the radius, and returns the total
31//              number of points lying within the radius.
32//
33//              The method used for searching the kd-tree is a variation of the
34//              nearest neighbor search used in kd_search.cpp, except that the
35//              radius of the search ball is known.  We refer the reader to that
36//              file for the explanation of the recursive search procedure.
37//----------------------------------------------------------------------
38
39//----------------------------------------------------------------------
40//              To keep argument lists short, a number of global variables
41//              are maintained which are common to all the recursive calls.
42//              These are given below.
43//----------------------------------------------------------------------
44
45int                             ANNkdFRDim;                             // dimension of space
46ANNpoint                ANNkdFRQ;                               // query point
47ANNdist                 ANNkdFRSqRad;                   // squared radius search bound
48double                  ANNkdFRMaxErr;                  // max tolerable squared error
49ANNpointArray   ANNkdFRPts;                             // the points
50ANNmin_k*               ANNkdFRPointMK;                 // set of k closest points
51int                             ANNkdFRPtsVisited;              // total points visited
52int                             ANNkdFRPtsInRange;              // number of points in the range
53
54//----------------------------------------------------------------------
55//      annkFRSearch - fixed radius search for k nearest neighbors
56//----------------------------------------------------------------------
57
58int ANNkd_tree::annkFRSearch(
59        ANNpoint                        q,                              // the query point
60        ANNdist                         sqRad,                  // squared radius search bound
61        int                                     k,                              // number of near neighbors to return
62        ANNidxArray                     nn_idx,                 // nearest neighbor indices (returned)
63        ANNdistArray            dd,                             // the approximate nearest neighbor
64        double                          eps)                    // the error bound
65{
66        ANNkdFRDim = dim;                                       // copy arguments to static equivs
67        ANNkdFRQ = q;
68        ANNkdFRSqRad = sqRad;
69        ANNkdFRPts = pts;
70        ANNkdFRPtsVisited = 0;                          // initialize count of points visited
71        ANNkdFRPtsInRange = 0;                          // ...and points in the range
72
73        ANNkdFRMaxErr = ANN_POW(1.0 + eps);
74        ANN_FLOP(2)                                                     // increment floating op count
75
76        ANNkdFRPointMK = new ANNmin_k(k);       // create set for closest k points
77                                                                                // search starting at the root
78        root->ann_FR_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim));
79
80        for (int i = 0; i < k; i++) {           // extract the k-th closest points
81                if (dd != NULL)
82                        dd[i] = ANNkdFRPointMK->ith_smallest_key(i);
83                if (nn_idx != NULL)
84                        nn_idx[i] = ANNkdFRPointMK->ith_smallest_info(i);
85        }
86
87        delete ANNkdFRPointMK;                          // deallocate closest point set
88        return ANNkdFRPtsInRange;                       // return final point count
89}
90
91//----------------------------------------------------------------------
92//      kd_split::ann_FR_search - search a splitting node
93//              Note: This routine is similar in structure to the standard kNN
94//              search.  It visits the subtree that is closer to the query point
95//              first.  For fixed-radius search, there is no benefit in visiting
96//              one subtree before the other, but we maintain the same basic
97//              code structure for the sake of uniformity.
98//----------------------------------------------------------------------
99
100void ANNkd_split::ann_FR_search(ANNdist box_dist)
101{
102                                                                                // check dist calc term condition
103        if (ANNmaxPtsVisited != 0 && ANNkdFRPtsVisited > ANNmaxPtsVisited) return;
104
105                                                                                // distance to cutting plane
106        ANNcoord cut_diff = ANNkdFRQ[cut_dim] - cut_val;
107
108        if (cut_diff < 0) {                                     // left of cutting plane
109                child[ANN_LO]->ann_FR_search(box_dist);// visit closer child first
110
111                ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdFRQ[cut_dim];
112                if (box_diff < 0)                               // within bounds - ignore
113                        box_diff = 0;
114                                                                                // distance to further box
115                box_dist = (ANNdist) ANN_SUM(box_dist,
116                                ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
117
118                                                                                // visit further child if in range
119                if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
120                        child[ANN_HI]->ann_FR_search(box_dist);
121
122        }
123        else {                                                          // right of cutting plane
124                child[ANN_HI]->ann_FR_search(box_dist);// visit closer child first
125
126                ANNcoord box_diff = ANNkdFRQ[cut_dim] - cd_bnds[ANN_HI];
127                if (box_diff < 0)                               // within bounds - ignore
128                        box_diff = 0;
129                                                                                // distance to further box
130                box_dist = (ANNdist) ANN_SUM(box_dist,
131                                ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
132
133                                                                                // visit further child if close enough
134                if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
135                        child[ANN_LO]->ann_FR_search(box_dist);
136
137        }
138        ANN_FLOP(13)                                            // increment floating ops
139        ANN_SPL(1)                                                      // one more splitting node visited
140}
141
142//----------------------------------------------------------------------
143//      kd_leaf::ann_FR_search - search points in a leaf node
144//              Note: The unreadability of this code is the result of
145//              some fine tuning to replace indexing by pointer operations.
146//----------------------------------------------------------------------
147
148void ANNkd_leaf::ann_FR_search(ANNdist box_dist)
149{
150        register ANNdist dist;                          // distance to data point
151        register ANNcoord* pp;                          // data coordinate pointer
152        register ANNcoord* qq;                          // query coordinate pointer
153        register ANNcoord t;
154        register int d;
155
156        for (int i = 0; i < n_pts; i++) {       // check points in bucket
157
158                pp = ANNkdFRPts[bkt[i]];                // first coord of next data point
159                qq = ANNkdFRQ;                                  // first coord of query point
160                dist = 0;
161
162                for(d = 0; d < ANNkdFRDim; d++) {
163                        ANN_COORD(1)                            // one more coordinate hit
164                        ANN_FLOP(5)                                     // increment floating ops
165
166                        t = *(qq++) - *(pp++);          // compute length and adv coordinate
167                                                                                // exceeds dist to k-th smallest?
168                        if( (dist = ANN_SUM(dist, ANN_POW(t))) > ANNkdFRSqRad) {
169                                break;
170                        }
171                }
172
173                if (d >= ANNkdFRDim &&                                  // among the k best?
174                   (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem
175                                                                                                // add it to the list
176                        ANNkdFRPointMK->insert(dist, bkt[i]);
177                        ANNkdFRPtsInRange++;                            // increment point count
178                }
179        }
180        ANN_LEAF(1)                                                     // one more leaf node visited
181        ANN_PTS(n_pts)                                          // increment points visited
182        ANNkdFRPtsVisited += n_pts;                     // increment number of points visited
183}
Note: See TracBrowser for help on using the repository browser.