9 #ifndef KDTreeCapable_H
10 #define KDTreeCapable_H
15 #include <mrpt/otherlibs/nanoflann/nanoflann.hpp>
79 template <
class Derived,
typename num_t = float,
80 typename metric_t = nanoflann::L2_Simple_Adaptor<num_t, Derived>>
93 return *
static_cast<const Derived*
>(
this);
96 inline Derived&
derived() {
return *
static_cast<Derived*
>(
this); }
128 float x0,
float y0,
float& out_x,
float& out_y,
129 float& out_dist_sqr)
const
136 const size_t knn = 1;
138 nanoflann::KNNResultSet<num_t> resultSet(knn);
139 resultSet.init(&ret_index, &out_dist_sqr);
145 nanoflann::SearchParams());
148 out_x =
derived().kdtree_get_pt(ret_index, 0);
149 out_y =
derived().kdtree_get_pt(ret_index, 1);
157 float x0,
float y0,
float& out_dist_sqr)
const
164 const size_t knn = 1;
166 nanoflann::KNNResultSet<num_t> resultSet(knn);
167 resultSet.init(&ret_index, &out_dist_sqr);
173 nanoflann::SearchParams());
185 static_cast<float>(p0.
x),
static_cast<float>(p0.
y), dmy1, dmy2,
197 float closerx, closery, closer_dist;
205 static_cast<float>(p0.
x),
static_cast<float>(p0.
y));
229 float x0,
float y0,
float& out_x1,
float& out_y1,
float& out_x2,
230 float& out_y2,
float& out_dist_sqr1,
float& out_dist_sqr2)
const
237 const size_t knn = 2;
238 size_t ret_indexes[2];
240 nanoflann::KNNResultSet<num_t> resultSet(knn);
241 resultSet.init(&ret_indexes[0], &ret_sqdist[0]);
247 nanoflann::SearchParams());
250 out_x1 =
derived().kdtree_get_pt(ret_indexes[0], 0);
251 out_y1 =
derived().kdtree_get_pt(ret_indexes[0], 1);
252 out_dist_sqr1 = ret_sqdist[0];
254 out_x2 =
derived().kdtree_get_pt(ret_indexes[1], 0);
255 out_y2 =
derived().kdtree_get_pt(ret_indexes[1], 1);
256 out_dist_sqr2 = ret_sqdist[0];
263 float& outDistSqr1,
float& outDistSqr2)
const
265 float dmy1, dmy2, dmy3, dmy4;
267 p0.
x, p0.
y, dmy1, dmy2, dmy3, dmy4, outDistSqr1, outDistSqr2);
268 pOut1.
x =
static_cast<double>(dmy1);
269 pOut1.
y =
static_cast<double>(dmy2);
270 pOut2.
x =
static_cast<double>(dmy3);
271 pOut2.
y =
static_cast<double>(dmy4);
296 float x0,
float y0,
size_t knn, std::vector<float>& out_x,
297 std::vector<float>& out_y, std::vector<float>& out_dist_sqr)
const
304 std::vector<size_t> ret_indexes(knn);
307 out_dist_sqr.resize(knn);
309 nanoflann::KNNResultSet<num_t> resultSet(knn);
310 resultSet.init(&ret_indexes[0], &out_dist_sqr[0]);
316 nanoflann::SearchParams());
318 for (
size_t i = 0; i < knn; i++)
320 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i], 0);
321 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i], 1);
328 const TPoint2D& p0,
size_t N, std::vector<TPoint2D>& pOut,
329 std::vector<float>& outDistSqr)
const
331 std::vector<float> dmy1, dmy2;
333 static_cast<float>(p0.
x),
static_cast<float>(p0.
y), N, dmy1, dmy2,
335 pOut.resize(dmy1.size());
336 for (
size_t i = 0; i < dmy1.size(); i++)
338 pOut[i].x =
static_cast<double>(dmy1[i]);
339 pOut[i].y =
static_cast<double>(dmy2[i]);
361 float x0,
float y0,
size_t knn, std::vector<size_t>& out_idx,
362 std::vector<float>& out_dist_sqr)
const
370 out_dist_sqr.resize(knn);
371 nanoflann::KNNResultSet<num_t> resultSet(knn);
372 resultSet.init(&out_idx[0], &out_dist_sqr[0]);
378 nanoflann::SearchParams());
383 const TPoint2D& p0,
size_t N, std::vector<size_t>& outIdx,
384 std::vector<float>& outDistSqr)
const
387 static_cast<float>(p0.
x),
static_cast<float>(p0.
y), N, outIdx,
411 float x0,
float y0,
float z0,
float& out_x,
float& out_y,
float& out_z,
412 float& out_dist_sqr)
const
419 const size_t knn = 1;
421 nanoflann::KNNResultSet<num_t> resultSet(knn);
422 resultSet.init(&ret_index, &out_dist_sqr);
429 nanoflann::SearchParams());
432 out_x =
derived().kdtree_get_pt(ret_index, 0);
433 out_y =
derived().kdtree_get_pt(ret_index, 1);
434 out_z =
derived().kdtree_get_pt(ret_index, 2);
442 float x0,
float y0,
float z0,
float& out_dist_sqr)
const
449 const size_t knn = 1;
451 nanoflann::KNNResultSet<num_t> resultSet(knn);
452 resultSet.init(&ret_index, &out_dist_sqr);
459 nanoflann::SearchParams());
469 float dmy1, dmy2, dmy3;
471 static_cast<float>(p0.
x),
static_cast<float>(p0.
y),
472 static_cast<float>(p0.
z), dmy1, dmy2, dmy3, outDistSqr);
473 pOut.
x =
static_cast<double>(dmy1);
474 pOut.
y =
static_cast<double>(dmy2);
475 pOut.
z =
static_cast<double>(dmy3);
502 float x0,
float y0,
float z0,
size_t knn, std::vector<float>& out_x,
503 std::vector<float>& out_y, std::vector<float>& out_z,
504 std::vector<float>& out_dist_sqr)
const
511 std::vector<size_t> ret_indexes(knn);
515 out_dist_sqr.resize(knn);
517 nanoflann::KNNResultSet<num_t> resultSet(knn);
518 resultSet.init(&ret_indexes[0], &out_dist_sqr[0]);
525 nanoflann::SearchParams());
527 for (
size_t i = 0; i < knn; i++)
529 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i], 0);
530 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i], 1);
531 out_z[i] =
derived().kdtree_get_pt(ret_indexes[i], 2);
560 float x0,
float y0,
float z0,
size_t knn, std::vector<float>& out_x,
561 std::vector<float>& out_y, std::vector<float>& out_z,
562 std::vector<size_t>& out_idx, std::vector<float>& out_dist_sqr)
const
573 out_dist_sqr.resize(knn);
575 nanoflann::KNNResultSet<num_t> resultSet(knn);
576 resultSet.init(&out_idx[0], &out_dist_sqr[0]);
583 nanoflann::SearchParams());
585 for (
size_t i = 0; i < knn; i++)
587 out_x[i] =
derived().kdtree_get_pt(out_idx[i], 0);
588 out_y[i] =
derived().kdtree_get_pt(out_idx[i], 1);
589 out_z[i] =
derived().kdtree_get_pt(out_idx[i], 2);
595 const TPoint3D& p0,
size_t N, std::vector<TPoint3D>& pOut,
596 std::vector<float>& outDistSqr)
const
598 std::vector<float> dmy1, dmy2, dmy3;
600 static_cast<float>(p0.
x),
static_cast<float>(p0.
y),
601 static_cast<float>(p0.
z), N, dmy1, dmy2, dmy3, outDistSqr);
602 pOut.resize(dmy1.size());
603 for (
size_t i = 0; i < dmy1.size(); i++)
605 pOut[i].x =
static_cast<double>(dmy1[i]);
606 pOut[i].y =
static_cast<double>(dmy2[i]);
607 pOut[i].z =
static_cast<double>(dmy3[i]);
629 const num_t x0,
const num_t y0,
const num_t z0,
630 const num_t maxRadiusSqr,
631 std::vector<std::pair<size_t, num_t>>& out_indices_dist)
const
635 out_indices_dist.clear();
638 const num_t xyz[3] = {x0, y0, z0};
640 &xyz[0], maxRadiusSqr, out_indices_dist,
641 nanoflann::SearchParams());
643 return out_indices_dist.size();
664 const num_t x0,
const num_t y0,
const num_t maxRadiusSqr,
665 std::vector<std::pair<size_t, num_t>>& out_indices_dist)
const
669 out_indices_dist.clear();
672 const num_t xyz[2] = {x0, y0};
674 &xyz[0], maxRadiusSqr, out_indices_dist,
675 nanoflann::SearchParams());
677 return out_indices_dist.size();
699 float x0,
float y0,
float z0,
size_t knn, std::vector<size_t>& out_idx,
700 std::vector<float>& out_dist_sqr)
const
708 out_dist_sqr.resize(knn);
709 nanoflann::KNNResultSet<num_t> resultSet(knn);
710 resultSet.init(&out_idx[0], &out_dist_sqr[0]);
717 nanoflann::SearchParams());
722 const TPoint3D& p0,
size_t N, std::vector<size_t>& outIdx,
723 std::vector<float>& outDistSqr)
const
726 static_cast<float>(p0.
x),
static_cast<float>(p0.
y),
727 static_cast<float>(p0.
z), N, outIdx, outDistSqr);
742 template <
int _DIM = -1>
755 if (&o !=
this)
clear();
761 typedef nanoflann::KDTreeSingleIndexAdaptor<metric_t, Derived, _DIM>
765 std::unique_ptr<kdtree_index_t>
index;
797 const size_t N =
derived().kdtree_get_point_count();
805 2,
derived(), nanoflann::KDTreeSingleIndexAdaptorParams(
831 const size_t N =
derived().kdtree_get_point_count();
839 3,
derived(), nanoflann::KDTreeSingleIndexAdaptorParams(
A generic adaptor class for providing Nearest Neighbor (NN) lookup via the nanoflann library.
void kdTreeNClosestPoint3DIdx(const TPoint3D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
size_t kdTreeClosestPoint3D(float x0, float y0, float z0, float &out_dist_sqr) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
TKDTreeSearchParams kdtree_search_params
Parameters to tune the ANN searches.
float kdTreeClosestPoint2DsqrError(const TPoint2D &p0) 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< 3 > m_kdtree3d_data
TKDTreeDataHolder m_kdtreeNd_data
size_t kdTreeClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut, float &outDistSqr) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
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
Derived & derived()
CRTP helper method.
size_t kdTreeRadiusSearch3D(const num_t x0, const num_t y0, const num_t z0, const num_t maxRadiusSqr, 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.
void kdtree_mark_as_outdated() const
To be called by child classes when KD tree data changes.
const Derived & derived() const
CRTP helper method.
TKDTreeDataHolder< 2 > m_kdtree2d_data
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.
float kdTreeClosestPoint2DsqrError(float x0, float y0) const
Like kdTreeClosestPoint2D, but just return the square error from some point to its closest neighbor.
void rebuild_kdTree_3D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ...
void rebuild_kdTree_2D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ...
bool m_kdtree_is_uptodate
whether the KD tree needs to be rebuilt or not.
void kdTreeNClosestPoint2DIdx(const TPoint2D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
KDTreeCapable< Derived, num_t, metric_t > self_t
size_t kdTreeClosestPoint2D(float x0, float y0, float &out_dist_sqr) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
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.
void kdTreeTwoClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut1, TPoint2D &pOut2, float &outDistSqr1, float &outDistSqr2) const
size_t kdTreeClosestPoint3D(const TPoint3D &p0, TPoint3D &pOut, float &outDistSqr) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
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.
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.
size_t kdTreeRadiusSearch2D(const num_t x0, const num_t y0, const num_t maxRadiusSqr, 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.
std::vector< size_t > kdTreeNClosestPoint2D(const TPoint2D &p0, size_t N, std::vector< TPoint2D > &pOut, std::vector< float > &outDistSqr) const
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.
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.
KDTreeCapable()
Constructor.
#define THROW_EXCEPTION(msg)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Internal structure with the KD-tree representation (mainly used to avoid copying pointers with the = ...
TKDTreeDataHolder & operator=(const TKDTreeDataHolder &o) noexcept
Copy operator: It actually does NOT copy the kd-tree, a new object will be created if required!
nanoflann::KDTreeSingleIndexAdaptor< metric_t, Derived, _DIM > kdtree_index_t
std::unique_ptr< kdtree_index_t > index
nullptr or the up-to-date index
size_t m_dim
Dimensionality.
std::vector< num_t > query_point
TKDTreeDataHolder(const TKDTreeDataHolder &)
Copy constructor: It actually does NOT copy the kd-tree, a new object will be created if required!
void clear() noexcept
Free memory (if allocated)
size_t leaf_max_size
Max points per leaf.
double x
X,Y,Z coordinates.