Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef KNN_CLOUD_H
00017 #define KNN_CLOUD_H
00018
00019 #include <ANN/ANN.h>
00020
00024 class knn_cloud
00025 {
00026 public:
00032 knn_cloud (const double epsilon = 0.01)
00033 : pa (NULL),
00034 search_tree (NULL),
00035 eps (epsilon),
00036 num_points (0)
00037 {
00038 index = new ANNidx [1];
00039 dist = new ANNdist [1];
00040 query_point = annAllocPt (3);
00041 }
00042
00043 ~knn_cloud ()
00044 {
00045 if (pa != NULL) annDeallocPts (pa);
00046 if (search_tree != NULL) delete search_tree;
00047 if (index != NULL) delete [] index;
00048 if (dist != NULL) delete [] dist;
00049 if (query_point != NULL) annDeallocPt (query_point);
00050
00051 annClose ();
00052 }
00053
00060 void refresh (const std::vector<vector3> &points)
00061 {
00062
00063 if (pa != NULL)
00064 {
00065 annDeallocPts (pa);
00066 pa = NULL;
00067 }
00068 if (search_tree != NULL)
00069 {
00070 delete search_tree;
00071 search_tree = NULL;
00072 }
00073
00074
00075 num_points = points.size ();
00076 if (num_points > 0)
00077 {
00078 pa = annAllocPts (num_points, 3);
00079 for (size_t i = 0; i < num_points; i++)
00080 {
00081 const vector3 v = points [i];
00082 ANNpoint p = pa [i];
00083 for (size_t d = 0; d < 3; d++)
00084 p [d] = v [d];
00085 }
00086
00087 search_tree = new ANNkd_tree (pa, num_points, 3);
00088 }
00089 }
00090
00100 double nearest_distance (const vector3 &p) const
00101 {
00102 double retval;
00103
00104 #pragma omp critical
00105 {
00106 for (size_t d = 0; d < 3; d++)
00107 query_point [d] = p [d];
00108
00109 search_tree->annkSearch (query_point, 1, index, dist, eps);
00110 retval = dist [0];
00111 }
00112
00113 return retval;
00114 }
00115
00135 size_t knn_search (size_t k, const vector3 &p, std::vector<size_t> &indices, std::vector<double> &distances) const
00136 {
00137 if (is_valid ())
00138 {
00139 k = std::min (k, num_points);
00140
00141
00142 ANNidxArray l_index = new ANNidx [k];
00143 ANNdistArray l_dist = new ANNdist [k];
00144
00145
00146 #pragma omp critical
00147 {
00148 for (size_t d = 0; d < 3; d++)
00149 query_point [d] = p [d];
00150
00151 search_tree->annkSearch (query_point, k, l_index, l_dist, eps);
00152 }
00153
00154
00155 indices.resize (k);
00156 distances.resize (k);
00157 for (size_t j = 0; j < k; j++)
00158 {
00159 indices [j] = l_index [j];
00160 distances [j] = l_dist [j];
00161 }
00162
00163
00164 delete [] l_index;
00165 delete [] l_dist;
00166
00167 return k;
00168 }
00169 else
00170 return 0;
00171 }
00172
00177 bool is_valid () const
00178 {
00179 return search_tree != NULL;
00180 }
00181
00191 vector3 operator[] (const size_t idx) const
00192 {
00193 vector3 retval;
00194 for (size_t n = 0; n < 3; n++)
00195 retval [n] = pa [idx] [n];
00196 return retval;
00197 }
00198
00203 size_t size () const
00204 {
00205 return num_points;
00206 }
00207
00208 private:
00209 ANNpointArray pa;
00210 ANNkd_tree *search_tree;
00211 ANNidxArray index;
00212 ANNdistArray dist;
00213 ANNpoint query_point;
00214 const double eps;
00215 size_t num_points;
00216 };
00217
00218 #endif // KNN_CLOUD_H
00219