9 #ifndef KDTreeCapable_H
10 #define KDTreeCapable_H
66 template <
class Derived,
typename num_t =
float,
typename metric_t = nanoflann::L2_Simple_Adaptor<num_t,Derived> >
81 inline const Derived&
derived()
const {
return *
static_cast<const Derived*
>(
this); }
83 inline Derived&
derived() {
return *
static_cast<Derived*
>(
this); }
129 const size_t knn = 1;
132 resultSet.
init(&ret_index, &out_dist_sqr );
139 out_x =
derived().kdtree_get_pt(ret_index,0);
140 out_y =
derived().kdtree_get_pt(ret_index,1);
150 float &out_dist_sqr )
const
156 const size_t knn = 1;
159 resultSet.
init(&ret_index, &out_dist_sqr );
184 float closerx,closery,closer_dist;
217 float &out_dist_sqr1,
218 float &out_dist_sqr2 )
const
224 const size_t knn = 2;
225 size_t ret_indexes[2];
228 resultSet.
init(&ret_indexes[0], &ret_sqdist[0] );
235 out_x1 =
derived().kdtree_get_pt(ret_indexes[0],0);
236 out_y1 =
derived().kdtree_get_pt(ret_indexes[0],1);
237 out_dist_sqr1 = ret_sqdist[0];
239 out_x2 =
derived().kdtree_get_pt(ret_indexes[1],0);
240 out_y2 =
derived().kdtree_get_pt(ret_indexes[1],1);
241 out_dist_sqr2 = ret_sqdist[0];
248 float dmy1,dmy2,dmy3,dmy4;
250 pOut1.
x=
static_cast<double>(dmy1);
251 pOut1.
y=
static_cast<double>(dmy2);
252 pOut2.
x=
static_cast<double>(dmy3);
253 pOut2.
y=
static_cast<double>(dmy4);
278 std::vector<float> &out_x,
279 std::vector<float> &out_y,
280 std::vector<float> &out_dist_sqr )
const
286 std::vector<size_t> ret_indexes(knn);
289 out_dist_sqr.resize(knn);
292 resultSet.
init(&ret_indexes[0], &out_dist_sqr[0] );
298 for (
size_t i=0;i<knn;i++)
300 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i],0);
301 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i],1);
308 std::vector<float> dmy1,dmy2;
309 std::vector<size_t> res=
kdTreeNClosestPoint2D(static_cast<float>(p0.
x),static_cast<float>(p0.
y),N,dmy1,dmy2,outDistSqr);
310 pOut.resize(dmy1.size());
311 for (
size_t i=0;i<dmy1.size();i++) {
312 pOut[i].x=
static_cast<double>(dmy1[i]);
313 pOut[i].y=
static_cast<double>(dmy2[i]);
336 std::vector<size_t> &out_idx,
337 std::vector<float> &out_dist_sqr )
const
344 out_dist_sqr.resize(knn);
346 resultSet.
init(&out_idx[0], &out_dist_sqr[0] );
389 const size_t knn = 1;
392 resultSet.
init(&ret_index, &out_dist_sqr );
400 out_x =
derived().kdtree_get_pt(ret_index,0);
401 out_y =
derived().kdtree_get_pt(ret_index,1);
402 out_z =
derived().kdtree_get_pt(ret_index,2);
420 const size_t knn = 1;
423 resultSet.
init(&ret_index, &out_dist_sqr );
436 float dmy1,dmy2,dmy3;
437 size_t res=
kdTreeClosestPoint3D(static_cast<float>(p0.
x),static_cast<float>(p0.
y),static_cast<float>(p0.
z),dmy1,dmy2,dmy3,outDistSqr);
438 pOut.
x=
static_cast<double>(dmy1);
439 pOut.
y=
static_cast<double>(dmy2);
440 pOut.
z=
static_cast<double>(dmy3);
466 std::vector<float> &out_x,
467 std::vector<float> &out_y,
468 std::vector<float> &out_z,
469 std::vector<float> &out_dist_sqr )
const
475 std::vector<size_t> ret_indexes(knn);
479 out_dist_sqr.resize(knn);
482 resultSet.
init(&ret_indexes[0], &out_dist_sqr[0] );
489 for (
size_t i=0;i<knn;i++)
491 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i],0);
492 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i],1);
493 out_z[i] =
derived().kdtree_get_pt(ret_indexes[i],2);
521 std::vector<float> &out_x,
522 std::vector<float> &out_y,
523 std::vector<float> &out_z,
524 std::vector<size_t> &out_idx,
525 std::vector<float> &out_dist_sqr )
const
535 out_dist_sqr.resize(knn);
538 resultSet.
init(&out_idx[0], &out_dist_sqr[0] );
545 for (
size_t i=0;i<knn;i++)
547 out_x[i] =
derived().kdtree_get_pt(out_idx[i],0);
548 out_y[i] =
derived().kdtree_get_pt(out_idx[i],1);
549 out_z[i] =
derived().kdtree_get_pt(out_idx[i],2);
555 std::vector<float> dmy1,dmy2,dmy3;
556 kdTreeNClosestPoint3D(static_cast<float>(p0.
x),static_cast<float>(p0.
y),static_cast<float>(p0.
z),N,dmy1,dmy2,dmy3,outDistSqr);
557 pOut.resize(dmy1.size());
558 for (
size_t i=0;i<dmy1.size();i++) {
559 pOut[i].x=
static_cast<double>(dmy1[i]);
560 pOut[i].y=
static_cast<double>(dmy2[i]);
561 pOut[i].z=
static_cast<double>(dmy3[i]);
581 const num_t x0,
const num_t y0,
const num_t z0,
582 const num_t maxRadius,
583 std::vector<std::pair<size_t,num_t> >& out_indices_dist )
const
587 out_indices_dist.clear();
590 const num_t xyz[3] = {x0,y0,z0};
593 return out_indices_dist.size();
612 const num_t x0,
const num_t y0,
613 const num_t maxRadius,
614 std::vector<std::pair<size_t,num_t> >& out_indices_dist )
const
618 out_indices_dist.clear();
621 const num_t xyz[2] = {x0,y0};
624 return out_indices_dist.size();
648 std::vector<size_t> &out_idx,
649 std::vector<float> &out_dist_sqr )
const
656 out_dist_sqr.resize(knn);
658 resultSet.
init(&out_idx[0], &out_dist_sqr[0] );
679 template <
int _DIM = -1>
690 if (&o!=
this)
clear();
719 if (!m_kdtree_is_uptodate) { m_kdtree2d_data.clear(); m_kdtree3d_data.clear(); m_kdtreeNd_data.clear(); }
721 if (!m_kdtree2d_data.index)
724 m_kdtree2d_data.clear();
726 const size_t N =
derived().kdtree_get_point_count();
727 m_kdtree2d_data.m_num_points = N;
728 m_kdtree2d_data.m_dim = 2;
729 m_kdtree2d_data.query_point.resize(2);
733 m_kdtree2d_data.index->buildIndex();
735 m_kdtree_is_uptodate =
true;
744 if (!m_kdtree_is_uptodate) { m_kdtree2d_data.clear(); m_kdtree3d_data.clear(); m_kdtreeNd_data.clear(); }
746 if (!m_kdtree3d_data.index)
749 m_kdtree3d_data.clear();
751 const size_t N =
derived().kdtree_get_point_count();
752 m_kdtree3d_data.m_num_points = N;
753 m_kdtree3d_data.m_dim = 3;
754 m_kdtree3d_data.query_point.resize(3);
758 m_kdtree3d_data.index->buildIndex();
760 m_kdtree_is_uptodate =
true;
~KDTreeCapable()
Destructor (nothing needed to do here)
KDTreeCapable()
Constructor.
float kdTreeClosestPoint2DsqrError(float x0, float y0) const
Like kdTreeClosestPoint2D, but just return the square error from some point to its closest neighbor...
size_t kdTreeClosestPoint2D(float x0, float y0, float &out_dist_sqr) const
#define THROW_EXCEPTION(msg)
const Derived & derived() const
CRTP helper method.
void init(IndexType *indices_, DistanceType *dists_)
TKDTreeDataHolder< 2 > m_kdtree2d_data
size_t m_dim
Dimensionality. typ: 2,3.
std::vector< size_t > kdTreeNClosestPoint2D(const TPoint2D &p0, size_t N, std::vector< TPoint2D > &pOut, std::vector< float > &outDistSqr) const
void kdTreeNClosestPoint2DIdx(const TPoint2D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
float kdTreeClosestPoint2DsqrError(const TPoint2D &p0) const
double z
X,Y,Z coordinates.
void kdTreeTwoClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut1, TPoint2D &pOut2, float &outDistSqr1, float &outDistSqr2) const
void rebuild_kdTree_3D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ... asking the child class for the dat...
Derived & derived()
CRTP helper method.
Internal structure with the KD-tree representation (mainly used to avoid copying pointers with the = ...
void kdTreeNClosestPoint3DWithIdx(float x0, float y0, float z0, size_t knn, std::vector< float > &out_x, std::vector< float > &out_y, std::vector< float > &out_z, std::vector< size_t > &out_idx, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest points to some given 3D coordinates.
void kdTreeNClosestPoint3D(const TPoint3D &p0, size_t N, std::vector< TPoint3D > &pOut, std::vector< float > &outDistSqr) const
A generic adaptor class for providing Approximate Nearest Neighbors (ANN) (via the nanoflann library)...
TKDTreeDataHolder< 3 > m_kdtree3d_data
TKDTreeDataHolder & operator=(const TKDTreeDataHolder &o)
Copy operator: It actually does NOT copy the kd-tree, a new object will be created if required! ...
size_t kdTreeClosestPoint3D(const TPoint3D &p0, TPoint3D &pOut, float &outDistSqr) const
void kdTreeNClosestPoint3DIdx(float x0, float y0, float z0, size_t knn, std::vector< size_t > &out_idx, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest point to some given 3D coordinates and returns their indexes...
TKDTreeDataHolder()
Init the pointer to NULL.
size_t kdTreeClosestPoint3D(float x0, float y0, float z0, float &out_x, float &out_y, float &out_z, float &out_dist_sqr) const
KD Tree-based search for the closest point (only ONE) to some given 3D coordinates.
~TKDTreeDataHolder()
Free memory (if allocated)
void kdtree_mark_as_outdated() const
To be called by child classes when KD tree data changes.
nanoflann::KDTreeSingleIndexAdaptor< metric_t, Derived, _DIM > kdtree_index_t
void kdTreeNClosestPoint3DIdx(const TPoint3D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void delete_safe(T *&ptr)
Calls "delete" to free an object only if the pointer is not NULL, then set the pointer to NULL...
size_t kdTreeRadiusSearch2D(const num_t x0, const num_t y0, const num_t maxRadius, std::vector< std::pair< size_t, num_t > > &out_indices_dist) const
KD Tree-based search for all the points within a given radius of some 2D point.
size_t kdTreeClosestPoint2D(float x0, float y0, float &out_x, float &out_y, float &out_dist_sqr) const
KD Tree-based search for the closest point (only ONE) to some given 2D coordinates.
bool m_kdtree_is_uptodate
whether the KD tree needs to be rebuilt or not.
size_t kdTreeClosestPoint3D(float x0, float y0, float z0, float &out_dist_sqr) const
void kdTreeNClosestPoint3D(float x0, float y0, float z0, size_t knn, std::vector< float > &out_x, std::vector< float > &out_y, std::vector< float > &out_z, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest points to some given 3D coordinates.
size_t leaf_max_size
Max points per leaf.
std::vector< size_t > kdTreeNClosestPoint2D(float x0, float y0, size_t knn, std::vector< float > &out_x, std::vector< float > &out_y, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest point to some given 2D coordinates.
Parameters (see http://code.google.com/p/nanoflann/ for help choosing the parameters) ...
void kdTreeTwoClosestPoint2D(float x0, float y0, float &out_x1, float &out_y1, float &out_x2, float &out_y2, float &out_dist_sqr1, float &out_dist_sqr2) const
KD Tree-based search for the TWO closest point to some given 2D coordinates.
void clear()
Free memory (if allocated)
kdtree_index_t * index
NULL or the up-to-date index.
Search options for KDTreeSingleIndexAdaptor::findNeighbors()
void rebuild_kdTree_2D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ... asking the child class for the dat...
std::vector< num_t > query_point
void kdTreeNClosestPoint2DIdx(float x0, float y0, size_t knn, std::vector< size_t > &out_idx, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest point to some given 2D coordinates and returns their indexes...
KDTreeCapable< Derived, num_t, metric_t > self_t
TKDTreeDataHolder(const TKDTreeDataHolder &)
Copy constructor: It actually does NOT copy the kd-tree, a new object will be created if required! ...
TKDTreeDataHolder m_kdtreeNd_data
void findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParams &searchParams) const
Find set of nearest neighbors to vec[0:dim-1].
TKDTreeSearchParams kdtree_search_params
Parameters to tune the ANN searches.
size_t kdTreeRadiusSearch3D(const num_t x0, const num_t y0, const num_t z0, const num_t maxRadius, std::vector< std::pair< size_t, num_t > > &out_indices_dist) const
KD Tree-based search for all the points within a given radius of some 3D point.
size_t radiusSearch(const ElementType *query_point, const DistanceType radius, std::vector< std::pair< IndexType, DistanceType > > &IndicesDists, const SearchParams &searchParams) const
Find all the neighbors to query_point[0:dim-1] within a maximum radius.
size_t kdTreeClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut, float &outDistSqr) const
int nChecks
The number of checks for ANN (default: 32) - corresponds to FLANN's SearchParams::check.