kd_tree.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------
00002 // File:                        kd_tree.h
00003 // Programmer:          Sunil Arya and David Mount
00004 // Description:         Declarations for standard kd-tree routines
00005 // Last modified:       05/03/05 (Version 1.1)
00006 //----------------------------------------------------------------------
00007 // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
00008 // David Mount.  All Rights Reserved.
00009 // 
00010 // This software and related documentation is part of the Approximate
00011 // Nearest Neighbor Library (ANN).  This software is provided under
00012 // the provisions of the Lesser GNU Public License (LGPL).  See the
00013 // file ../ReadMe.txt for further information.
00014 // 
00015 // The University of Maryland (U.M.) and the authors make no
00016 // representations about the suitability or fitness of this software for
00017 // any purpose.  It is provided "as is" without express or implied
00018 // warranty.
00019 //----------------------------------------------------------------------
00020 // History:
00021 //      Revision 0.1  03/04/98
00022 //              Initial release
00023 //      Revision 1.1  05/03/05
00024 //              Added fixed radius kNN search
00025 //----------------------------------------------------------------------
00026 
00027 #ifndef ANN_kd_tree_H
00028 #define ANN_kd_tree_H
00029 
00030 #include <ANN/ANNx.h>                                   // all ANN includes
00031 
00032 using namespace std;                                    // make std:: available
00033 
00034 //----------------------------------------------------------------------
00035 //      Generic kd-tree node
00036 //
00037 //              Nodes in kd-trees are of two types, splitting nodes which contain
00038 //              splitting information (a splitting hyperplane orthogonal to one
00039 //              of the coordinate axes) and leaf nodes which contain point
00040 //              information (an array of points stored in a bucket).  This is
00041 //              handled by making a generic class kd_node, which is essentially an
00042 //              empty shell, and then deriving the leaf and splitting nodes from
00043 //              this.
00044 //----------------------------------------------------------------------
00045 
00046 class ANNkd_node{                                               // generic kd-tree node (empty shell)
00047 public:
00048         virtual ~ANNkd_node() {}                                        // virtual distroyer
00049 
00050         virtual void ann_search(ANNdist) = 0;           // tree search
00051         virtual void ann_pri_search(ANNdist) = 0;       // priority search
00052         virtual void ann_FR_search(ANNdist) = 0;        // fixed-radius search
00053 
00054         virtual void getStats(                                          // get tree statistics
00055                                 int dim,                                                // dimension of space
00056                                 ANNkdStats &st,                                 // statistics
00057                                 ANNorthRect &bnd_box) = 0;              // bounding box
00058                                                                                                 // print node
00059         virtual void print(int level, ostream &out) = 0;
00060         virtual void dump(ostream &out) = 0;            // dump node
00061 
00062         friend class ANNkd_tree;                                        // allow kd-tree to access us
00063 };
00064 
00065 //----------------------------------------------------------------------
00066 //      kd-splitting function:
00067 //              kd_splitter is a pointer to a splitting routine for preprocessing.
00068 //              Different splitting procedures result in different strategies
00069 //              for building the tree.
00070 //----------------------------------------------------------------------
00071 
00072 typedef void (*ANNkd_splitter)(                 // splitting routine for kd-trees
00073         ANNpointArray           pa,                             // point array (unaltered)
00074         ANNidxArray                     pidx,                   // point indices (permuted on return)
00075         const ANNorthRect       &bnds,                  // bounding rectangle for cell
00076         int                                     n,                              // number of points
00077         int                                     dim,                    // dimension of space
00078         int                                     &cut_dim,               // cutting dimension (returned)
00079         ANNcoord                        &cut_val,               // cutting value (returned)
00080         int                                     &n_lo);                 // num of points on low side (returned)
00081 
00082 //----------------------------------------------------------------------
00083 //      Leaf kd-tree node
00084 //              Leaf nodes of the kd-tree store the set of points associated
00085 //              with this bucket, stored as an array of point indices.  These
00086 //              are indices in the array points, which resides with the
00087 //              root of the kd-tree.  We also store the number of points
00088 //              that reside in this bucket.
00089 //----------------------------------------------------------------------
00090 
00091 class ANNkd_leaf: public ANNkd_node             // leaf node for kd-tree
00092 {
00093         int                                     n_pts;                  // no. points in bucket
00094         ANNidxArray                     bkt;                    // bucket of points
00095 public:
00096         ANNkd_leaf(                                                     // constructor
00097                 int                             n,                              // number of points
00098                 ANNidxArray             b)                              // bucket
00099                 {
00100                         n_pts           = n;                    // number of points in bucket
00101                         bkt                     = b;                    // the bucket
00102                 }
00103 
00104         ~ANNkd_leaf() { }                                       // destructor (none)
00105 
00106         virtual void getStats(                                          // get tree statistics
00107                                 int dim,                                                // dimension of space
00108                                 ANNkdStats &st,                                 // statistics
00109                                 ANNorthRect &bnd_box);                  // bounding box
00110         virtual void print(int level, ostream &out);// print node
00111         virtual void dump(ostream &out);                        // dump node
00112 
00113         virtual void ann_search(ANNdist);                       // standard search
00114         virtual void ann_pri_search(ANNdist);           // priority search
00115         virtual void ann_FR_search(ANNdist);            // fixed-radius search
00116 };
00117 
00118 //----------------------------------------------------------------------
00119 //              KD_TRIVIAL is a special pointer to an empty leaf node. Since
00120 //              some splitting rules generate many (more than 50%) trivial
00121 //              leaves, we use this one shared node to save space.
00122 //
00123 //              The pointer is initialized to NULL, but whenever a kd-tree is
00124 //              created, we allocate this node, if it has not already been
00125 //              allocated. This node is *never* deallocated, so it produces
00126 //              a small memory leak.
00127 //----------------------------------------------------------------------
00128 
00129 extern ANNkd_leaf *KD_TRIVIAL;                                  // trivial (empty) leaf node
00130 
00131 //----------------------------------------------------------------------
00132 //      kd-tree splitting node.
00133 //              Splitting nodes contain a cutting dimension and a cutting value.
00134 //              These indicate the axis-parellel plane which subdivide the
00135 //              box for this node. The extent of the bounding box along the
00136 //              cutting dimension is maintained (this is used to speed up point
00137 //              to box distance calculations) [we do not store the entire bounding
00138 //              box since this may be wasteful of space in high dimensions].
00139 //              We also store pointers to the 2 children.
00140 //----------------------------------------------------------------------
00141 
00142 class ANNkd_split : public ANNkd_node   // splitting node of a kd-tree
00143 {
00144         int                                     cut_dim;                // dim orthogonal to cutting plane
00145         ANNcoord                        cut_val;                // location of cutting plane
00146         ANNcoord                        cd_bnds[2];             // lower and upper bounds of
00147                                                                                 // rectangle along cut_dim
00148         ANNkd_ptr                       child[2];               // left and right children
00149 public:
00150         ANNkd_split(                                            // constructor
00151                 int cd,                                                 // cutting dimension
00152                 ANNcoord cv,                                    // cutting value
00153                 ANNcoord lv, ANNcoord hv,                               // low and high values
00154                 ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL)   // children
00155                 {
00156                         cut_dim         = cd;                                   // cutting dimension
00157                         cut_val         = cv;                                   // cutting value
00158                         cd_bnds[ANN_LO] = lv;                           // lower bound for rectangle
00159                         cd_bnds[ANN_HI] = hv;                           // upper bound for rectangle
00160                         child[ANN_LO]   = lc;                           // left child
00161                         child[ANN_HI]   = hc;                           // right child
00162                 }
00163 
00164         ~ANNkd_split()                                          // destructor
00165                 {
00166                         if (child[ANN_LO]!= NULL && child[ANN_LO]!= KD_TRIVIAL)
00167                                 delete child[ANN_LO];
00168                         if (child[ANN_HI]!= NULL && child[ANN_HI]!= KD_TRIVIAL)
00169                                 delete child[ANN_HI];
00170                 }
00171 
00172         virtual void getStats(                                          // get tree statistics
00173                                 int dim,                                                // dimension of space
00174                                 ANNkdStats &st,                                 // statistics
00175                                 ANNorthRect &bnd_box);                  // bounding box
00176         virtual void print(int level, ostream &out);// print node
00177         virtual void dump(ostream &out);                        // dump node
00178 
00179         virtual void ann_search(ANNdist);                       // standard search
00180         virtual void ann_pri_search(ANNdist);           // priority search
00181         virtual void ann_FR_search(ANNdist);            // fixed-radius search
00182 };
00183 
00184 //----------------------------------------------------------------------
00185 //              External entry points
00186 //----------------------------------------------------------------------
00187 
00188 ANNkd_ptr rkd_tree(                             // recursive construction of kd-tree
00189         ANNpointArray           pa,                             // point array (unaltered)
00190         ANNidxArray                     pidx,                   // point indices to store in subtree
00191         int                                     n,                              // number of points
00192         int                                     dim,                    // dimension of space
00193         int                                     bsp,                    // bucket space
00194         ANNorthRect                     &bnd_box,               // bounding box for current node
00195         ANNkd_splitter          splitter);              // splitting routine
00196 
00197 #endif

Generated on Wed Nov 23 19:00:20 2011 for FreeCAD by  doxygen 1.6.1