1
+ /* *
2
+ * @file KdTree.h
3
+ * @author Quoc-Minh Ton-That ([email protected] )
4
+ * @brief This file contains the KdTree class.
5
+ * @date 2025-02-12
6
+ *
7
+ * @copyright Copyright (c) 2025
8
+ *
9
+ */
10
+
1
11
#ifndef PBAT_GEOMETRY_KD_TREE_H
2
12
#define PBAT_GEOMETRY_KD_TREE_H
3
13
14
24
namespace pbat {
15
25
namespace geometry {
16
26
27
+ /* *
28
+ * @brief Node of a KDTree
29
+ */
17
30
struct KdTreeNode
18
31
{
19
32
Index lc{-1 }; // /< Index of left child of this node in the KDTree. -1 if no left child.
@@ -24,23 +37,48 @@ struct KdTreeNode
24
37
std::size_t n{0 }; // /< Number of points encapsulated in this node's AABB starting from begin and
25
38
// /< continuing in contiguous memory in the permutation list until begin + n.
26
39
27
- Index depth{0 };
28
-
40
+ Index depth{0 }; // /< Depth of this node in the KDTree.
41
+ /* *
42
+ * @brief Returns true if this node has a left child, false otherwise
43
+ * @return true if this node has a left child, false otherwise
44
+ */
29
45
bool HasLeftChild () const { return lc > -1 ; }
46
+ /* *
47
+ * @brief Returns true if this node has a right child, false otherwise
48
+ * @return true if this node has a right child, false otherwise
49
+ */
30
50
bool HasRightChild () const { return rc > -1 ; }
51
+ /* *
52
+ * @brief Returns true if this node is a leaf node, false otherwise
53
+ * @return true if this node is a leaf node, false otherwise
54
+ */
31
55
[[maybe_unused]] bool IsLeafNode () const
32
56
{
33
57
return (not HasLeftChild ()) and (not HasRightChild ());
34
58
}
59
+ /* *
60
+ * @brief Returns true if this node is an internal node, false otherwise
61
+ * @return true if this node is an internal node, false otherwise
62
+ */
35
63
[[maybe_unused]] bool IsInternalNode () const { return HasLeftChild () or HasRightChild (); }
36
64
};
37
65
66
+ /* *
67
+ * @brief KDTree class
68
+ * @tparam Dims Number of dimensions of the points' coordinate system in the k-D tree
69
+ */
38
70
template <int Dims>
39
71
class KdTree
40
72
{
41
73
public:
42
74
KdTree () = default ;
43
75
76
+ /* *
77
+ * @brief Construct a k-D tree from a set of points
78
+ * @tparam TDerivedP Eigen dense expression type
79
+ * @param P Points to construct the k-D tree from
80
+ * @param maxPointsInLeaf Maximum number of points in a leaf node
81
+ */
44
82
template <class TDerivedP >
45
83
KdTree (Eigen::DenseBase<TDerivedP> const & P, std::size_t maxPointsInLeaf = 10 );
46
84
@@ -51,35 +89,77 @@ class KdTree
51
89
52
90
public:
53
91
/* *
54
- * @brief
55
- * @param visit Returns true if the node's children should be visited, false otherwise
56
- * @param stop Returns true if the search should stop
57
- * @param root
92
+ * @brief Breadth-first search over the k-D tree
93
+ * @tparam FVisit Callable with signature `bool(Index, KdTreeNode const&)`
94
+ * @tparam FStop Callable with signature `bool(Index, KdTreeNode const&)`
95
+ * @param visit Callback invoked when visiting a node. Returns true if the node's children
96
+ * should be visited, false otherwise
97
+ * @param stop Callback invoked when visiting a node. Returns true if the search should stop,
98
+ * false otherwise
99
+ * @param root Index of the root node to start the search from
58
100
*/
59
101
template <class FVisit , class FStop = decltype (fStopDefault )>
60
102
void BreadthFirstSearch (FVisit visit, FStop stop = fStopDefault , Index root = 0 ) const ;
61
103
62
104
/* *
63
- * @brief
64
- * @param visit Returns true if the node's children should be visited, false otherwise
65
- * @param stop Returns true if the search should stop
66
- * @param root
105
+ * @brief Depth-first search over the k-D tree
106
+ * @tparam FVisit Callable with signature `bool(Index, KdTreeNode const&)`
107
+ * @tparam FStop Callable with signature `bool(Index, KdTreeNode const&)`
108
+ * @param visit Callback invoked when visiting a node. Returns true if the node's children
109
+ * @param stop Callback invoked when visiting a node. Returns true if the search should stop,
110
+ * @param root Index of the root node to start the search from
67
111
*/
68
112
template <class FVisit , class FStop = decltype (fStopDefault )>
69
113
void DepthFirstSearch (FVisit visit, FStop stop = fStopDefault , Index root = 0 ) const ;
70
114
115
+ /* *
116
+ * @brief Construct a k-D tree from a set of points
117
+ * @tparam TDerivedP Eigen dense expression type
118
+ * @param P Points to construct the k-D tree from
119
+ * @param maxPointsInLeaf Maximum number of points in a leaf node
120
+ */
71
121
template <class TDerivedP >
72
122
void Construct (Eigen::DenseBase<TDerivedP> const & P, std::size_t maxPointsInLeaf);
73
123
124
+ /* *
125
+ * @brief Returns the nodes of the k-D tree
126
+ * @return Nodes of the k-D tree
127
+ */
74
128
std::vector<KdTreeNode> const & Nodes () const { return mNodes ; }
75
-
129
+ /* *
130
+ * @brief Returns the permutation of the points in the k-D tree
131
+ *
132
+ * The permutation is such that mPermutation[i] gives the index of point i in the original point
133
+ * set given to Construct().
134
+ *
135
+ * @return Permutation of the points in the k-D tree
136
+ */
76
137
std::vector<Index> const & Permutation () const { return mPermutation ; }
77
-
138
+ /* *
139
+ * @brief Returns the points in a node
140
+ * @param nodeIdx Index of the node
141
+ * @return Range of points in the node
142
+ */
78
143
auto PointsInNode (Index const nodeIdx) const ;
79
-
144
+ /* *
145
+ * @brief Returns the points in a node
146
+ * @param node Reference to k-D tree node
147
+ * @return Range of points in the node
148
+ */
80
149
auto PointsInNode (KdTreeNode const & node) const ;
81
150
82
151
protected:
152
+ /* *
153
+ * @brief Recursive construct call that constructs a sub-tree of the full k-D tree
154
+ * @tparam TDerivedP Eigen dense expression type
155
+ * @param nodeIdx Index of the sub-tree root node
156
+ * @param P Points to construct the k-D tree from
157
+ * @param aabb Axis-aligned bounding box of the points contained in the sub-tree
158
+ * @param begin Index of the first point in the permutation list contained in the sub-tree
159
+ * @param n Number of points in the permutation list starting from begin contained in the
160
+ * sub-tree
161
+ * @param maxPointsInLeaf Maximum number of points in a leaf node
162
+ */
83
163
template <class TDerivedP >
84
164
void DoConstruct (
85
165
Index const nodeIdx,
@@ -88,11 +168,20 @@ class KdTree
88
168
Index const begin,
89
169
std::size_t const n,
90
170
std::size_t maxPointsInLeaf);
91
-
171
+ /* *
172
+ * @brief Adds a node to the k-D tree's node list
173
+ *
174
+ * @param begin Index of the first point in the permutation list contained in the sub-tree
175
+ * rooted in the added node
176
+ * @param n Number of points in the permutation list starting from begin contained in the
177
+ * sub-tree rooted in the added node
178
+ * @param depth Depth of the added node in the k-D tree
179
+ * @return Index of the added node in the k-D tree's node list
180
+ */
92
181
Index AddNode (Index begin, std::size_t n, Index depth);
93
182
94
183
private:
95
- std::vector<Index> mPermutation ; // /< permutation_ [i] gives the index of point i in
184
+ std::vector<Index> mPermutation ; // /< mPermutation [i] gives the index of point i in
96
185
// /< the original points list given to
97
186
// /< construct(std::vector<Vector3> const& points).
98
187
std::vector<KdTreeNode> mNodes ; // /< KDTree nodes.
0 commit comments