40#include <pcl/search/brute_force.h>
45template <
typename Po
intT>
float
49 if constexpr (pcl::traits::has_xyz_v<PointT>)
51 if (point_representation_->isTrivial () &&
52 point_representation_->getNumberOfDimensions () == 3)
53 return (point1.getVector3fMap () - point2.getVector3fMap ()).squaredNorm ();
56 const int nr_dimensions = point_representation_->getNumberOfDimensions ();
57 std::vector<float> point1_representation (nr_dimensions);
58 std::vector<float> point2_representation (nr_dimensions);
59 point_representation_->vectorize (point1, point1_representation);
60 point_representation_->vectorize (point2, point2_representation);
63 for (
int i = 0; i < nr_dimensions; ++i)
65 const float diff = point1_representation[i] - point2_representation[i];
72template <
typename Po
intT>
int
74 const PointT& point,
int k,
Indices& k_indices, std::vector<float>& k_distances)
const
76 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point given to nearestKSearch!");
84 return denseKSearch (point, k, k_indices, k_distances);
85 return sparseKSearch (point, k, k_indices, k_distances);
89template <
typename Po
intT>
int
91 const PointT &point,
int k,
Indices &k_indices, std::vector<float> &k_distances)
const
94 std::vector<Entry> result;
96 std::priority_queue<Entry> queue;
99 auto iIt = indices_->cbegin ();
100 auto iEnd = indices_->cbegin () + std::min (
static_cast<unsigned> (k),
static_cast<unsigned> (indices_->size ()));
101 for (; iIt != iEnd; ++iIt)
102 result.push_back (Entry (*iIt, getDistSqr ((*input_)[*iIt], point)));
104 queue = std::priority_queue<Entry> (result.begin (), result.end ());
108 for (; iIt != indices_->cend (); ++iIt)
110 entry.distance = getDistSqr ((*input_)[*iIt], point);
111 if (queue.top ().distance > entry.distance)
122 for (entry.index = 0; entry.index < std::min<pcl::index_t> (k, input_->size ()); ++entry.index)
124 entry.distance = getDistSqr ((*input_)[entry.index], point);
125 result.push_back (entry);
128 queue = std::priority_queue<Entry> (result.begin (), result.end ());
131 for (; entry.index <
static_cast<pcl::index_t>(input_->size ()); ++entry.index)
133 entry.distance = getDistSqr ((*input_)[entry.index], point);
134 if (queue.top ().distance > entry.distance)
142 k_indices.resize (queue.size ());
143 k_distances.resize (queue.size ());
144 std::size_t idx = queue.size () - 1;
145 while (!queue.empty ())
147 k_indices [idx] = queue.top ().index;
148 k_distances [idx] = queue.top ().distance;
153 return (
static_cast<int> (k_indices.size ()));
157template <
typename Po
intT>
int
159 const PointT &point,
int k, Indices &k_indices, std::vector<float> &k_distances)
const
162 std::vector<Entry> result;
165 std::priority_queue<Entry> queue;
168 auto iIt =indices_->cbegin ();
169 for (; iIt != indices_->cend () && result.size () <
static_cast<unsigned> (k); ++iIt)
171 if (point_representation_->isValid ((*input_)[*iIt]))
172 result.push_back (Entry (*iIt, getDistSqr ((*input_)[*iIt], point)));
175 queue = std::priority_queue<Entry> (result.begin (), result.end ());
182 for (; iIt != indices_->cend (); ++iIt)
184 if (!point_representation_->isValid ((*input_)[*iIt]))
187 entry.distance = getDistSqr ((*input_)[*iIt], point);
188 if (queue.top ().distance > entry.distance)
199 for (entry.index = 0; (entry.index <
static_cast<pcl::index_t>(input_->size ())) && (result.size () <
static_cast<std::size_t
> (k)); ++entry.index)
201 if (point_representation_->isValid ((*input_)[entry.index]))
203 entry.distance = getDistSqr ((*input_)[entry.index], point);
204 result.push_back (entry);
207 queue = std::priority_queue<Entry> (result.begin (), result.end ());
212 for (; entry.index <
static_cast<pcl::index_t>(input_->size ()); ++entry.index)
214 if (!point_representation_->isValid ((*input_)[entry.index]))
217 entry.distance = getDistSqr ((*input_)[entry.index], point);
218 if (queue.top ().distance > entry.distance)
226 k_indices.resize (queue.size ());
227 k_distances.resize (queue.size ());
228 std::size_t idx = queue.size () - 1;
229 while (!queue.empty ())
231 k_indices [idx] = queue.top ().index;
232 k_distances [idx] = queue.top ().distance;
236 return (
static_cast<int> (k_indices.size ()));
240template <
typename Po
intT>
int
242 const PointT& point,
double radius,
243 Indices &k_indices, std::vector<float> &k_sqr_distances,
244 unsigned int max_nn)
const
248 std::size_t reserve = max_nn;
252 reserve = std::min (indices_->size (), input_->size ());
254 reserve = input_->size ();
256 k_indices.reserve (reserve);
257 k_sqr_distances.reserve (reserve);
261 for (
const auto& idx : *indices_)
263 distance = getDistSqr ((*input_)[idx], point);
264 if (distance <= radius)
266 k_indices.push_back (idx);
267 k_sqr_distances.push_back (distance);
268 if (k_indices.size () == max_nn)
275 for (std::size_t index = 0; index < input_->size (); ++index)
277 distance = getDistSqr ((*input_)[index], point);
278 if (distance <= radius)
280 k_indices.push_back (index);
281 k_sqr_distances.push_back (distance);
282 if (k_indices.size () == max_nn)
289 this->sortResults (k_indices, k_sqr_distances);
291 return (
static_cast<int> (k_indices.size ()));
295template <
typename Po
intT>
int
297 const PointT& point,
double radius,
298 Indices &k_indices, std::vector<float> &k_sqr_distances,
299 unsigned int max_nn)
const
303 std::size_t reserve = max_nn;
307 reserve = std::min (indices_->size (), input_->size ());
309 reserve = input_->size ();
311 k_indices.reserve (reserve);
312 k_sqr_distances.reserve (reserve);
317 for (
const auto& idx : *indices_)
319 if (!point_representation_->isValid ((*input_)[idx]))
322 distance = getDistSqr ((*input_)[idx], point);
323 if (distance <= radius)
325 k_indices.push_back (idx);
326 k_sqr_distances.push_back (distance);
327 if (k_indices.size () == max_nn)
334 for (std::size_t index = 0; index < input_->size (); ++index)
336 if (!point_representation_->isValid ((*input_)[index]))
338 distance = getDistSqr ((*input_)[index], point);
339 if (distance <= radius)
341 k_indices.push_back (index);
342 k_sqr_distances.push_back (distance);
343 if (k_indices.size () == max_nn)
350 this->sortResults (k_indices, k_sqr_distances);
352 return (
static_cast<int> (k_indices.size ()));
356template <
typename Po
intT>
int
359 std::vector<float> &k_sqr_distances,
unsigned int max_nn)
const
361 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point given to radiusSearch!");
364 k_sqr_distances.clear ();
368 if (input_->is_dense)
369 return denseRadiusSearch (point, radius, k_indices, k_sqr_distances, max_nn);
370 return sparseRadiusSearch (point, radius, k_indices, k_sqr_distances, max_nn);
373#define PCL_INSTANTIATE_BruteForce(T) template class PCL_EXPORTS pcl::search::BruteForce<T>;
Implementation of a simple brute force search algorithm.
int nearestKSearch(const PointT &point, int k, Indices &k_indices, std::vector< float > &k_distances) const override
Search for the k-nearest neighbors for the given query point.
int radiusSearch(const PointT &point, double radius, Indices &k_indices, std::vector< float > &k_sqr_distances, unsigned int max_nn=0) const override
Search for all the nearest neighbors of the query point in a given radius.
float distance(const PointT &p1, const PointT &p2)
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
IndicesAllocator<> Indices
Type used for indices in PCL.
A point structure representing Euclidean xyz coordinates, and the RGB color.