You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
7.1 KiB
C++

//----------------------------------------------------------------------
// File: kd_tree.h
// Programmer: Sunil Arya and David Mount
// Description: Declarations for standard kd-tree routines
// Last modified: 05/03/05 (Version 1.1)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
// Revision 1.1 05/03/05
// Added fixed radius kNN search
//----------------------------------------------------------------------
#ifndef ANN_kd_tree_H
#define ANN_kd_tree_H
#include <ANN/ANNx.h> // all ANN includes
using namespace std; // make std:: available
//----------------------------------------------------------------------
// kd-splitting function:
// kd_splitter is a pointer to a splitting routine for preprocessing.
// Different splitting procedures result in different strategies
// for building the tree.
//----------------------------------------------------------------------
typedef void (*ANNkd_splitter)( // splitting routine for kd-trees
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices (permuted on return)
const ANNorthRect &bnds, // bounding rectangle for cell
int n, // number of points
int dim, // dimension of space
int &cut_dim, // cutting dimension (returned)
ANNcoord &cut_val, // cutting value (returned)
int &n_lo); // num of points on low side (returned)
//----------------------------------------------------------------------
// Leaf kd-tree node
// Leaf nodes of the kd-tree store the set of points associated
// with this bucket, stored as an array of point indices. These
// are indices in the array points, which resides with the
// root of the kd-tree. We also store the number of points
// that reside in this bucket.
//----------------------------------------------------------------------
class ANNkd_leaf: public ANNkd_node // leaf node for kd-tree
{
int n_pts; // no. points in bucket
ANNidxArray bkt; // bucket of points
public:
ANNkd_leaf( // constructor
int n, // number of points
ANNidxArray b) // bucket
{
n_pts = n; // number of points in bucket
bkt = b; // the bucket
}
~ANNkd_leaf() { } // destructor (none)
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box); // bounding box
virtual void print(int level, ostream &out);// print node
virtual void dump(ostream &out); // dump node
virtual void ann_search(ANNdist); // standard search
virtual void ann_pri_search(ANNdist); // priority search
virtual void ann_FR_search(ANNdist); // fixed-radius search
ANNidxArray getIdxArray() // Deyuan Qiu
{ return bkt; }
bool isLeaf() // Deyuan Qiu
{ return true; }
};
//----------------------------------------------------------------------
// KD_TRIVIAL is a special pointer to an empty leaf node. Since
// some splitting rules generate many (more than 50%) trivial
// leaves, we use this one shared node to save space.
//
// The pointer is initialized to NULL, but whenever a kd-tree is
// created, we allocate this node, if it has not already been
// allocated. This node is *never* deallocated, so it produces
// a small memory leak.
//----------------------------------------------------------------------
extern ANNkd_leaf *KD_TRIVIAL; // trivial (empty) leaf node
//----------------------------------------------------------------------
// kd-tree splitting node.
// Splitting nodes contain a cutting dimension and a cutting value.
// These indicate the axis-parellel plane which subdivide the
// box for this node. The extent of the bounding box along the
// cutting dimension is maintained (this is used to speed up point
// to box distance calculations) [we do not store the entire bounding
// box since this may be wasteful of space in high dimensions].
// We also store pointers to the 2 children.
//----------------------------------------------------------------------
class ANNkd_split : public ANNkd_node // splitting node of a kd-tree
{
int cut_dim; // dim orthogonal to cutting plane
ANNcoord cut_val; // location of cutting plane
ANNcoord cd_bnds[2]; // lower and upper bounds of
// rectangle along cut_dim
ANNkd_ptr child[2]; // left and right children
public:
ANNkd_split( // constructor
int cd, // cutting dimension
ANNcoord cv, // cutting value
ANNcoord lv, ANNcoord hv, // low and high values
ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL) // children
{
cut_dim = cd; // cutting dimension
cut_val = cv; // cutting value
cd_bnds[ANN_LO] = lv; // lower bound for rectangle
cd_bnds[ANN_HI] = hv; // upper bound for rectangle
child[ANN_LO] = lc; // left child
child[ANN_HI] = hc; // right child
}
~ANNkd_split() // destructor
{
if (child[ANN_LO]!= NULL && child[ANN_LO]!= KD_TRIVIAL)
delete child[ANN_LO];
if (child[ANN_HI]!= NULL && child[ANN_HI]!= KD_TRIVIAL)
delete child[ANN_HI];
}
virtual void getStats( // get tree statistics
int dim, // dimension of space
ANNkdStats &st, // statistics
ANNorthRect &bnd_box); // bounding box
virtual void print(int level, ostream &out);// print node
virtual void dump(ostream &out); // dump node
virtual void ann_search(ANNdist); // standard search
virtual void ann_pri_search(ANNdist); // priority search
virtual void ann_FR_search(ANNdist); // fixed-radius search
ANNkd_ptr getLeftChild() // Deyuan Qiu
{ return child[0]; }
ANNkd_ptr getRightChild() // Deyuan Qiu
{ return child[1]; }
ANNcoord getCutVal() // Deyuan Qiu
{ return cut_val; }
int getCutDim() // Deyuan Qiu
{ return cut_dim; }
bool isLeaf() // Deyuan Qiu
{ return false; }
float getLoBound() // Deyuan Qiu
{ return (float)cd_bnds[0]; }
float getHiBound() // Deyuan Qiu
{ return (float)cd_bnds[1]; }
};
//----------------------------------------------------------------------
// External entry points
//----------------------------------------------------------------------
ANNkd_ptr rkd_tree( // recursive construction of kd-tree
ANNpointArray pa, // point array (unaltered)
ANNidxArray pidx, // point indices to store in subtree
int n, // number of points
int dim, // dimension of space
int bsp, // bucket space
ANNorthRect &bnd_box, // bounding box for current node
ANNkd_splitter splitter); // splitting routine
#endif