81 class Derived,
typename num_t = float,
102 return *
static_cast<const Derived*
>(
this);
105 inline Derived&
derived() {
return *
static_cast<Derived*
>(
this); }
137 float x0,
float y0,
float& out_x,
float& out_y,
138 float& out_dist_sqr)
const 145 const size_t knn = 1;
148 resultSet.
init(&ret_index, &out_dist_sqr);
150 const std::array<num_t, 2> query_point{{x0, y0}};
155 out_x =
derived().kdtree_get_pt(ret_index, 0);
156 out_y =
derived().kdtree_get_pt(ret_index, 1);
164 float x0,
float y0,
float& out_dist_sqr)
const 171 const size_t knn = 1;
174 resultSet.
init(&ret_index, &out_dist_sqr);
176 const std::array<num_t, 2> query_point{{x0, y0}};
201 float closerx, closery, closer_dist;
232 float x0,
float y0,
float& out_x1,
float& out_y1,
float& out_x2,
233 float& out_y2,
float& out_dist_sqr1,
float& out_dist_sqr2)
const 240 const size_t knn = 2;
241 size_t ret_indexes[2];
244 resultSet.
init(&ret_indexes[0], &ret_sqdist[0]);
246 const std::array<num_t, 2> query_point{{x0, y0}};
251 out_x1 =
derived().kdtree_get_pt(ret_indexes[0], 0);
252 out_y1 =
derived().kdtree_get_pt(ret_indexes[0], 1);
253 out_dist_sqr1 = ret_sqdist[0];
255 out_x2 =
derived().kdtree_get_pt(ret_indexes[1], 0);
256 out_y2 =
derived().kdtree_get_pt(ret_indexes[1], 1);
257 out_dist_sqr2 = ret_sqdist[0];
264 float& outDistSqr1,
float& outDistSqr2)
const 266 float dmy1, dmy2, dmy3, dmy4;
268 p0.
x, p0.
y, dmy1, dmy2, dmy3, dmy4, outDistSqr1, outDistSqr2);
269 pOut1.
x =
static_cast<double>(dmy1);
270 pOut1.
y =
static_cast<double>(dmy2);
271 pOut2.
x =
static_cast<double>(dmy3);
272 pOut2.
y =
static_cast<double>(dmy4);
297 float x0,
float y0,
size_t knn, std::vector<float>& out_x,
298 std::vector<float>& out_y, std::vector<float>& out_dist_sqr)
const 305 std::vector<size_t> ret_indexes(knn);
308 out_dist_sqr.resize(knn);
311 resultSet.
init(&ret_indexes[0], &out_dist_sqr[0]);
313 const std::array<num_t, 2> query_point{{x0, y0}};
317 for (
size_t i = 0; i < knn; i++)
319 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i], 0);
320 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i], 1);
327 const TPoint2D& p0,
size_t N, std::vector<TPoint2D>& pOut,
328 std::vector<float>& outDistSqr)
const 330 std::vector<float> dmy1, dmy2;
332 d2f(p0.
x),
d2f(p0.
y), N, dmy1, dmy2, outDistSqr);
333 pOut.resize(dmy1.size());
334 for (
size_t i = 0; i < dmy1.size(); i++)
336 pOut[i].x =
static_cast<double>(dmy1[i]);
337 pOut[i].y =
static_cast<double>(dmy2[i]);
359 float x0,
float y0,
size_t knn, std::vector<size_t>& out_idx,
360 std::vector<float>& out_dist_sqr)
const 368 out_dist_sqr.resize(knn);
370 resultSet.
init(&out_idx[0], &out_dist_sqr[0]);
372 const std::array<num_t, 2> query_point{{x0, y0}};
379 const TPoint2D& p0,
size_t N, std::vector<size_t>& outIdx,
380 std::vector<float>& outDistSqr)
const 383 d2f(p0.
x),
d2f(p0.
y), N, outIdx, outDistSqr);
406 float x0,
float y0,
float z0,
float& out_x,
float& out_y,
float& out_z,
407 float& out_dist_sqr)
const 414 const size_t knn = 1;
417 resultSet.
init(&ret_index, &out_dist_sqr);
419 const std::array<num_t, 3> query_point{{x0, y0, z0}};
424 out_x =
derived().kdtree_get_pt(ret_index, 0);
425 out_y =
derived().kdtree_get_pt(ret_index, 1);
426 out_z =
derived().kdtree_get_pt(ret_index, 2);
434 float x0,
float y0,
float z0,
float& out_dist_sqr)
const 441 const size_t knn = 1;
444 resultSet.
init(&ret_index, &out_dist_sqr);
446 const std::array<num_t, 3> query_point{{x0, y0, z0}};
458 float dmy1, dmy2, dmy3;
460 d2f(p0.
x),
d2f(p0.
y),
d2f(p0.
z), dmy1, dmy2, dmy3, outDistSqr);
461 pOut.
x =
static_cast<double>(dmy1);
462 pOut.
y =
static_cast<double>(dmy2);
463 pOut.
z =
static_cast<double>(dmy3);
490 float x0,
float y0,
float z0,
size_t knn, std::vector<float>& out_x,
491 std::vector<float>& out_y, std::vector<float>& out_z,
492 std::vector<float>& out_dist_sqr)
const 499 std::vector<size_t> ret_indexes(knn);
503 out_dist_sqr.resize(knn);
506 resultSet.
init(&ret_indexes[0], &out_dist_sqr[0]);
508 const std::array<num_t, 3> query_point{{x0, y0, z0}};
512 for (
size_t i = 0; i < knn; i++)
514 out_x[i] =
derived().kdtree_get_pt(ret_indexes[i], 0);
515 out_y[i] =
derived().kdtree_get_pt(ret_indexes[i], 1);
516 out_z[i] =
derived().kdtree_get_pt(ret_indexes[i], 2);
545 float x0,
float y0,
float z0,
size_t knn, std::vector<float>& out_x,
546 std::vector<float>& out_y, std::vector<float>& out_z,
547 std::vector<size_t>& out_idx, std::vector<float>& out_dist_sqr)
const 558 out_dist_sqr.resize(knn);
561 resultSet.
init(&out_idx[0], &out_dist_sqr[0]);
563 const std::array<num_t, 3> query_point{{x0, y0, z0}};
567 for (
size_t i = 0; i < knn; i++)
569 out_x[i] =
derived().kdtree_get_pt(out_idx[i], 0);
570 out_y[i] =
derived().kdtree_get_pt(out_idx[i], 1);
571 out_z[i] =
derived().kdtree_get_pt(out_idx[i], 2);
577 const TPoint3D& p0,
size_t N, std::vector<TPoint3D>& pOut,
578 std::vector<float>& outDistSqr)
const 580 std::vector<float> dmy1, dmy2, dmy3;
582 d2f(p0.
x),
d2f(p0.
y),
d2f(p0.
z), N, dmy1, dmy2, dmy3, outDistSqr);
583 pOut.resize(dmy1.size());
584 for (
size_t i = 0; i < dmy1.size(); i++)
586 pOut[i].x =
static_cast<double>(dmy1[i]);
587 pOut[i].y =
static_cast<double>(dmy2[i]);
588 pOut[i].z =
static_cast<double>(dmy3[i]);
610 const num_t x0,
const num_t y0,
const num_t z0,
611 const num_t maxRadiusSqr,
612 std::vector<std::pair<size_t, num_t>>& out_indices_dist)
const 616 out_indices_dist.clear();
619 const num_t xyz[3] = {x0, y0, z0};
621 &xyz[0], maxRadiusSqr, out_indices_dist,
624 return out_indices_dist.size();
645 const num_t x0,
const num_t y0,
const num_t maxRadiusSqr,
646 std::vector<std::pair<size_t, num_t>>& out_indices_dist)
const 650 out_indices_dist.clear();
653 const num_t xyz[2] = {x0, y0};
655 &xyz[0], maxRadiusSqr, out_indices_dist,
658 return out_indices_dist.size();
680 float x0,
float y0,
float z0,
size_t knn, std::vector<size_t>& out_idx,
681 std::vector<float>& out_dist_sqr)
const 689 out_dist_sqr.resize(knn);
691 resultSet.
init(&out_idx[0], &out_dist_sqr[0]);
693 const std::array<num_t, 3> query_point{{x0, y0, z0}};
700 const TPoint3D& p0,
size_t N, std::vector<size_t>& outIdx,
701 std::vector<float>& outDistSqr)
const 704 d2f(p0.
x),
d2f(p0.
y),
d2f(p0.
z), N, outIdx, outDistSqr);
723 template <
int _DIM = -1>
736 if (&o !=
this)
clear();
746 std::unique_ptr<kdtree_index_t>
index;
779 const size_t N =
derived().kdtree_get_point_count();
813 const size_t N =
derived().kdtree_get_point_count();
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.
TKDTreeDataHolder()=default
void kdTreeNClosestPoint3DIdx(const TPoint3D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
KDTreeCapable & operator=(const KDTreeCapable &)
#define THROW_EXCEPTION(msg)
Squared Euclidean (L2) distance functor (suitable for low-dimensionality datasets, like 2D or 3D point clouds) Corresponding distance traits: nanoflann::metric_L2_Simple.
void kdTreeNClosestPoint2DIdx(const TPoint2D &p0, size_t N, std::vector< size_t > &outIdx, std::vector< float > &outDistSqr) const
nanoflann::KDTreeSingleIndexAdaptor< metric_t, Derived, _DIM > kdtree_index_t
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
size_t kdTreeClosestPoint3D(const TPoint3D &p0, TPoint3D &pOut, float &outDistSqr) const
void init(IndexType *indices_, DistanceType *dists_)
TKDTreeDataHolder< 2 > m_kdtree2d_data
size_t m_dim
Dimensionality.
const Derived & derived() const
CRTP helper method.
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 kdTreeEnsureIndexBuilt3D()
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 = ...
TKDTreeSearchParams()=default
A generic adaptor class for providing Nearest Neighbor (NN) lookup via the nanoflann library...
TKDTreeDataHolder< 3 > m_kdtree3d_data
float d2f(const double d)
shortcut for static_cast<float>(double)
This base provides a set of functions for maths stuff.
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.
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
KDTreeCapable(const KDTreeCapable &)
KDTreeCapable()=default
Constructor.
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.
size_t leaf_max_size
Max points per leaf.
Parameters (see README.md)
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.
Search options for KDTreeSingleIndexAdaptor::findNeighbors()
std::atomic_bool m_kdtree_is_uptodate
whether the KD tree needs to be rebuilt or not.
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.
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 kdTreeEnsureIndexBuilt2D()
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.