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(
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...
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 kdTreeNClosestPoint3DIdx(const TPoint3D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
KDTreeCapable()
Constructor.
void kdTreeNClosestPoint2DIdx(const TPoint2D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
TKDTreeDataHolder & operator=(const TKDTreeDataHolder &o) noexcept
Copy operator: It actually does NOT copy the kd-tree, a new object will be created if required! ...
void kdTreeTwoClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut1, TPoint2D &pOut2, float &outDistSqr1, float &outDistSqr2) const
#define THROW_EXCEPTION(msg)
size_t kdTreeClosestPoint3D(const TPoint3D &p0, TPoint3D &pOut, float &outDistSqr) const
TKDTreeDataHolder< 2 > m_kdtree2d_data
size_t m_dim
Dimensionality.
const Derived & derived() const
CRTP helper method.
KDTreeCapable< Derived, num_t, metric_t > self_t
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 rebuild_kdTree_2D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ...
Derived & derived()
CRTP helper method.
Internal structure with the KD-tree representation (mainly used to avoid copying pointers with the = ...
A generic adaptor class for providing Nearest Neighbor (NN) lookup via the nanoflann library...
TKDTreeDataHolder< 3 > m_kdtree3d_data
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.
void rebuild_kdTree_3D() const
Rebuild, if needed the KD-tree for 2D (nDims=2), 3D (nDims=3), ...
float kdTreeClosestPoint2DsqrError(const TPoint2D &p0) 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.
nanoflann::KDTreeSingleIndexAdaptor< metric_t, Derived, _DIM > kdtree_index_t
std::vector< size_t > kdTreeNClosestPoint2D(const TPoint2D &p0, size_t N, std::vector< TPoint2D > &pOut, std::vector< float > &outDistSqr) const
size_t kdTreeClosestPoint2D(float x0, float y0, float &out_dist_sqr) const
size_t kdTreeClosestPoint2D(const TPoint2D &p0, TPoint2D &pOut, float &outDistSqr) const
size_t kdTreeClosestPoint3D(float x0, float y0, float z0, float &out_dist_sqr) const
double x
X,Y,Z coordinates.
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.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool m_kdtree_is_uptodate
whether the KD tree needs to be rebuilt or not.
size_t leaf_max_size
Max points per leaf.
void kdTreeNClosestPoint3D(const TPoint3D &p0, size_t N, std::vector< TPoint3D > &pOut, std::vector< float > &outDistSqr) const
void kdtree_mark_as_outdated() const
To be called by child classes when KD tree data changes.
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.
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! ...
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.
TKDTreeDataHolder m_kdtreeNd_data
TKDTreeSearchParams kdtree_search_params
Parameters to tune the ANN searches.
void clear() noexcept
Free memory (if allocated)
float kdTreeClosestPoint2DsqrError(float x0, float y0) const
Like kdTreeClosestPoint2D, but just return the square error from some point to its closest neighbor...
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.
std::unique_ptr< kdtree_index_t > index
nullptr or the up-to-date index
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.