23#ifndef VCL_SPACE_COMPLEX_KD_TREE_H
24#define VCL_SPACE_COMPLEX_KD_TREE_H
26#include <vclib/concepts/mesh.h>
27#include <vclib/space/core/box.h>
35template<Po
intConcept Po
intType>
38 using Scalar = PointType::ScalarType;
48 uint firstChildId : 24;
73 inline static Scalar dummyScalar;
74 inline static std::vector<Scalar> dummyScalars;
76 std::vector<PointType> mPoints;
77 std::vector<uint> mIndices;
78 std::vector<Node> mNodes;
80 uint mPointsPerCell = 16;
88 const std::vector<PointType>& points,
92 mPoints(points), mIndices(points.size()),
95 std::iota(std::begin(mIndices), std::end(mIndices), 0);
97 mNodes.back().leaf = 0;
114 template<MeshConcept MeshType>
120 requires (std::is_same_v<
121 typename MeshType::VertexType::CoordType,
124 mPoints(
m.vertexNumber()), mIndices(
m.vertexNumber()),
127 using VertexType = MeshType::VertexType;
130 for (
const VertexType& v :
m.vertices()) {
131 mPoints[
i] = v.coord();
132 mIndices[
i] =
m.index(v);
136 mNodes.back().leaf = 0;
149 Scalar& dist = dummyScalar)
const
151 std::vector<QueryNode>
mNodeStack(mDepth + 1);
154 unsigned int count = 1;
164 if (
qnode.sq < minDist) {
168 for (uint
i =
node.start;
i < end; ++
i) {
199 dist = std::sqrt(minDist);
203 PointType nearestNeighbor(
205 Scalar& dist = dummyScalar)
const
230 std::vector<Scalar>&
distances = dummyScalars)
const
234 P(
const PointType&
p,
int i) :
p(
p),
i(
i) {}
246 bool operator()(
const P& p1,
const P&
p2)
248 if (
qp.squaredDist(p1.p) >
qp.squaredDist(
p2.p))
258 std::vector<QueryNode>
mNodeStack(mDepth + 1);
261 unsigned int count = 1;
283 unsigned int end =
node.start +
node.size;
285 for (
unsigned int i =
node.start;
i < end; ++
i)
321 std::vector<uint>
res;
333 std::vector<PointType> kNearestNeighbors(
336 std::vector<Scalar>&
distances = dummyScalars)
const
338 std::vector<uint>
dists =
340 std::vector<PointType>
res;
343 res.push_back(mPoints[
k]);
358 std::vector<Scalar>&
distances = dummyScalars)
const
362 std::vector<QueryNode>
mNodeStack(mDepth + 1);
365 unsigned int count = 1;
375 unsigned int end =
node.start +
node.size;
376 for (
unsigned int i =
node.start;
i < end; ++
i) {
410 std::vector<PointType> neighborsInDistance(
413 std::vector<Scalar>&
distances = dummyScalars)
const
415 std::vector<uint>
dists =
417 std::vector<PointType>
res;
420 res.push_back(mPoints[
k]);
459 aabb.add(mPoints[start]);
460 for (uint
i = start + 1;
i < end; ++
i)
461 aabb.add(mPoints[
i]);
468 Scalar
max = std::numeric_limits<double>::lowest();
469 for (uint
i = 0;
i < PointType::DIM; ++
i) {
480 for (uint
i = start + 1;
i < end; ++
i)
490 node.splitValue = Scalar(0.5 * (
aabb.max()[dim] +
aabb.min()[dim]));
496 node.firstChildId = mNodes.size();
497 mNodes.resize(mNodes.size() + 2);
502 unsigned int childId = mNodes[nodeId].firstChildId;
504 if (
flag || (
midId - start) <= mPointsPerCell ||
level >= mMaxDepth) {
516 childId = mNodes[nodeId].firstChildId + 1;
518 if (
flag || (end -
midId) <= mPointsPerCell ||
level >= mMaxDepth) {
540 uint
split(uint start, uint end, uint dim, Scalar splitValue)
543 for (
l = start,
r = end - 1;
l <
r; ++
l, --
r) {
544 while (
l < end && mPoints[
l][dim] < splitValue)
546 while (
r >= start && mPoints[
r][dim] >= splitValue)
550 std::swap(mPoints[
l], mPoints[
r]);
551 std::swap(mIndices[
l], mIndices[
r]);
555 return (mPoints[
l][dim] < splitValue ?
l + 1 :
l);
561template<MeshConcept MeshType>
562KDTree(
const MeshType& m) -> KDTree<typename MeshType::VertexType::CoordType>;
564template<MeshConcept MeshType>
565KDTree(
const MeshType& m, uint pointsPerCell)
566 -> KDTree<typename MeshType::VertexType::CoordType>;
568template<MeshConcept MeshType>
569KDTree(
const MeshType& m, uint pointsPerCell, uint maxDepth)
570 -> KDTree<typename MeshType::VertexType::CoordType>;
572template<MeshConcept MeshType>
573KDTree(
const MeshType& m, uint pointsPerCell, uint maxDepth,
bool balanced)
574 -> KDTree<typename MeshType::VertexType::CoordType>;
std::vector< uint > neighborsIndicesInDistance(const PointType &queryPoint, Scalar dist, std::vector< Scalar > &distances=dummyScalars) const
Performs the distance query.
Definition kd_tree.h:355
uint nearestNeighborIndex(const PointType &queryPoint, Scalar &dist=dummyScalar) const
Searchs the closest point.
Definition kd_tree.h:147
uint createTree(uint nodeId, uint start, uint end, uint level, bool balanced)
Rrecursively builds the kdtree.
Definition kd_tree.h:447
uint split(uint start, uint end, uint dim, Scalar splitValue)
Split the subarray between start and end in two part, one with the elements less than splitValue,...
Definition kd_tree.h:540
KDTree(const MeshType &m, uint pointsPerCell=16, uint maxDepth=64, bool balanced=false)
Builds the KDTree starting from the given mesh.
Definition kd_tree.h:115
std::vector< uint > kNearestNeighborsIndices(const PointType &queryPoint, uint k, std::vector< Scalar > &distances=dummyScalars) const
Performs the k nearest neighbour query.
Definition kd_tree.h:227
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:83