forked from cdalitz/kdtree-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkdtree.hpp
More file actions
108 lines (97 loc) · 3.27 KB
/
kdtree.hpp
File metadata and controls
108 lines (97 loc) · 3.27 KB
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
#ifndef __kdtree_HPP
#define __kdtree_HPP
//
// Kd-Tree implementation.
//
// Copyright: Christoph Dalitz, 2018-2020
// Jens Wilberg, 2018
// License: BSD style license
// (see the file LICENSE for details)
//
#include <cstdlib>
#include <queue>
#include <vector>
namespace Kdtree {
typedef std::vector<double> CoordPoint;
typedef std::vector<double> DoubleVector;
// for passing points to the constructor of kdtree
struct KdNode {
CoordPoint point;
void* data;
KdNode(const CoordPoint& p, void* d = NULL) {
point = p;
data = d;
}
KdNode() { data = NULL; }
};
typedef std::vector<KdNode> KdNodeVector;
// base function object for search predicate in knn search
// returns true when the given KdNode is an admissible neighbor
// To define an own search predicate, derive from this class
// and overwrite the call operator operator()
struct KdNodePredicate {
virtual ~KdNodePredicate() {}
virtual bool operator()(const KdNode&) const { return true; }
};
//--------------------------------------------------------
// private helper classes used internally by KdTree
//
// the internal node structure used by kdtree
class kdtree_node;
// base class for different distance computations
class DistanceMeasure;
// helper class for priority queue in k nearest neighbor search
class nn4heap {
public:
size_t dataindex; // index of actual kdnode in *allnodes*
double distance; // distance of this neighbor from *point*
nn4heap(size_t i, double d) {
dataindex = i;
distance = d;
}
};
class compare_nn4heap {
public:
bool operator()(const nn4heap& n, const nn4heap& m) {
return (n.distance < m.distance);
}
};
//--------------------------------------------------------
// kdtree class
class KdTree {
private:
// recursive build of tree
kdtree_node* build_tree(size_t depth, size_t a, size_t b);
// helper variable for keeping track of subtree bounding box
CoordPoint lobound, upbound;
// helper variables and functions for k nearest neighbor search
std::priority_queue<nn4heap, std::vector<nn4heap>, compare_nn4heap>*
neighborheap;
std::vector<size_t> range_result;
// helper variable to check the distance method
int distance_type;
bool neighbor_search(const CoordPoint& point, kdtree_node* node, size_t k);
void range_search(const CoordPoint& point, kdtree_node* node, double r);
bool bounds_overlap_ball(const CoordPoint& point, double dist,
kdtree_node* node);
bool ball_within_bounds(const CoordPoint& point, double dist,
kdtree_node* node);
// class implementing the distance computation
DistanceMeasure* distance;
// search predicate in knn searches
KdNodePredicate* searchpredicate;
public:
KdNodeVector allnodes;
size_t dimension;
kdtree_node* root;
// distance_type can be 0 (max), 1 (city block), or 2 (euklid)
KdTree(const KdNodeVector* nodes, int distance_type = 2);
~KdTree();
void set_distance(int distance_type, const DoubleVector* weights = NULL);
void k_nearest_neighbors(const CoordPoint& point, size_t k,
KdNodeVector* result, KdNodePredicate* pred = NULL);
void range_nearest_neighbors(const CoordPoint& point, double r,
KdNodeVector* result);
};
} // end namespace Kdtree
#endif