-
Notifications
You must be signed in to change notification settings - Fork 0
/
kdtree.h
147 lines (131 loc) · 4.79 KB
/
kdtree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef KDTREE_H
#define KDTREE_H
#include <QVector3D>
#include <QVector>
#include "vertex.h"
/*!
* \brief utility function for point sorting
* \param p1
* \param p2
* \return returns true if p1.x < p2.x, false otherwise
*/
inline bool sortByX( const QVector3D& p1, const QVector3D& p2) { return p1.x() < p2.x(); }
/*!
* \brief utility function for point sorting
* \param p1
* \param p2
* \return returns true if p1.y < p2.y, false otherwise
*/
inline bool sortByY( const QVector3D& p1, const QVector3D& p2) { return p1.y() < p2.y(); }
/*!
* \brief utility function for point sorting
* \param p1
* \param p2
* \return returns true if p1.z < p2.z, false otherwise
*/
inline bool sortByZ( const QVector3D& p1, const QVector3D& p2) { return p1.z() < p2.z(); }
/*!
* \brief utility function for searching points in a cuboid area
* \param point
* \param min minimum xyz coordinates
* \param max maximum xyz coordinates
* \return true if point is inside or on the cuboid defined by min and max
*/
inline bool inRange(const QVector3D& point, const QVector3D& min, const QVector3D& max)
{
return point.x() >= min.x() && point.x() <= max.x() &&
point.y() >= min.y() && point.y() <= max.y() &&
point.z() >= min.z() && point.z() <= max.z();
}
/*!
* \brief The KdTree class
* \details This class is used for efficient filter and search operations on point clouds.
*/
class KdTree
{
public:
KdTree() {} //!< constructor - nothing actually happens here, the KdTree must be built with KdTree::build
/*!
* \brief build KdTree
* \details deletes current tree, assigns point data and calls KdTree::buildKdTree to build a new tree from given vertices
* \param vertices reference to a QVector holding colors and positions of all points
*/
void build(QVector<Vertex>& vertices);
~KdTree() { delete m_tree; } //!< destructor - deletes tree contents
/*!
* \brief find all points in a box
* \details finds all points within a cuboid defined by two points
* \param min minimum xyz boundaries for search box
* \param max maximum xyz boundaries for search box
* \param indices offsets of points from m_vertexArrayPointer that have been found inside the box
*/
void pointsInBox(const QVector3D& min, const QVector3D& max, QVector<int>& indices);
/*!
* \brief find all points in a sphere
* \details finds all points within a sphere defined by center point and radius
* \param center center of the sphere
* \param distance radius of the sphere
* \param indices offsets of points from m_vertexArrayPointer that have been found inside the box
*/
void pointsInSphere(const QVector3D& center, const float distance, QVector<int>& indices);
/*!
* \brief nearestPoint
* \details starts search for nearest neighbor to given point with depth 0
* \param point
* \return nearest neighbor of point
*/
Vertex* nearestPoint(QVector3D& point); //!<
private:
/*!
* \brief The KdTreeNode struct
* \details a single node of the KdTree
*/
struct KdTreeNode
{
~KdTreeNode() //!< destructor - calls child node destructors
{
delete leftChild;
delete rightChild;
}
float median = 0; //!< median value for the KdTree split
KdTreeNode* leftChild = 0; //!< pointer to left child node
KdTreeNode* rightChild = 0; //!< pointer to right child node
Vertex* begin = 0;
Vertex* end = 0;
};
/*!
* \brief build KdTree
* \details recursively builds KdTree from vertex data
* \param begin
* \param end
* \param depth
* \return root node
*/
KdTreeNode* buildKdTree(Vertex* begin, Vertex* end, unsigned int depth);
/*!
* \brief range query
* \details recursively find points within cuboid defined by min and max points
* \param min
* \param max
* \param indices
* \param node
* \param depth
*/
void rangeQuery(const QVector3D& min, const QVector3D& max, QVector<int>& indices, KdTreeNode* node, const uint depth);
// FIXME: finish implementation
Vertex* nearestPointApprox(const QVector3D& point, KdTreeNode* node, uint depth);
//Vertex* nearestPoint(const QVector3D& point, QVector3D& approx, KdTreeNode* node, uint depth);
/*!
* \brief nearest point
* \details recursively find nearest neighbor to given point
* \param point
* \param node
* \param dist distance to current neighbor
* \param np current nearest point
* \param depth current search depth
*/
void nearestPoint(const QVector3D& point, KdTreeNode* node, double& dist, Vertex *np, int depth);
KdTreeNode* m_tree = 0; //!< pointer to root node
Vertex* m_vertexArrayPointer = 0; //!< pointer to point data
};
#endif // KDTREE_H