23#ifndef VCL_SPACE_COMPLEX_KD_TREE_H
24#define VCL_SPACE_COMPLEX_KD_TREE_H
26#include <vclib/mesh.h>
27#include <vclib/space/core.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::PositionType,
124 mPoints(
m.vertexNumber()), mIndices(
m.vertexNumber()),
127 using VertexType = MeshType::VertexType;
130 for (
const VertexType& v :
m.vertices()) {
131 mPoints[
i] = v.position();
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;
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;
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]);
460 for (uint
i = start + 1;
i < end; ++
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)
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)
563 -> KDTree<typename MeshType::VertexType::PositionType>;
565template<MeshConcept MeshType>
566KDTree(
const MeshType& m, uint pointsPerCell)
567 -> KDTree<typename MeshType::VertexType::PositionType>;
569template<MeshConcept MeshType>
570KDTree(
const MeshType& m, uint pointsPerCell, uint maxDepth)
571 -> KDTree<typename MeshType::VertexType::PositionType>;
573template<MeshConcept MeshType>
574KDTree(
const MeshType& m, uint pointsPerCell, uint maxDepth,
bool balanced)
575 -> KDTree<typename MeshType::VertexType::PositionType>;
A class representing a box in N-dimensional space.
Definition box.h:46
PointT & max()
Returns a reference to the maximum point of the box.
Definition box.h:104
PointT & min()
Returns a reference to the minimum point of the box.
Definition box.h:90
void add(const PointT &p)
Adds the given point to the current box, expanding this box in order to contain also the values of th...
Definition box.h:385
auto dim(uint i) const
Get the length of the box along a given dimension.
Definition box.h:292
PointT size() const
Computes the size of the box.
Definition box.h:267
std::vector< uint > neighborsIndicesInDistance(const PointType &queryPoint, Scalar dist, std::vector< Scalar > &distances=dummyScalars) const
Performs the distance query.
Definition kd_tree.h:355
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
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
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
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:81