30 #define Magnitude(X) ((X) < 0 ? -(X) : (X)) 31 #define NodeFound(N,K,D) (((N)->Key == (K)) && ((N)->Data == (D))) 36 #define MINSEARCH -FLT_MAX 37 #define MAXSEARCH FLT_MAX 40 static int NextLevel(
KDTREE *tree,
int level) {
51 template<
typename Key,
typename Value>
54 MinK(Key max_key,
int k);
65 bool insert(Key k, Value v);
69 const Element*
elements() {
return elements_; }
79 template<
typename Key,
typename Value>
81 max_key_(max_key), elements_count_(0), k_(k < 1 ? 1 : k), max_index_(0) {
82 elements_ =
new Element[k_];
85 template<
typename Key,
typename Value>
90 template<
typename Key,
typename Value>
92 if (elements_count_ < k_)
94 return elements_[max_index_].key;
97 template<
typename Key,
typename Value>
99 if (elements_count_ < k_) {
100 elements_[elements_count_++] = Element(key, value);
101 if (key > elements_[max_index_].key)
102 max_index_ = elements_count_ - 1;
104 }
else if (key < elements_[max_index_].key) {
106 elements_[max_index_] = Element(key, value);
108 for (
int i = 0; i < elements_count_; i++) {
109 if (elements_[i].key > elements_[max_index_].key)
127 void Search(
int *result_count,
float *distances,
void **results);
130 void SearchRec(
int Level,
KDNODE *SubTree);
131 bool BoxIntersectsSearch(
float *lower,
float *upper);
141 : tree_(tree), query_point_(query_point), results_(
MAXSEARCH, k_closest) {
142 sb_min_ =
new float[tree->
KeySize];
143 sb_max_ =
new float[tree->
KeySize];
159 for (
int i = 0; i < tree_->
KeySize; i++) {
165 *result_count =
count;
166 for (
int j = 0; j <
count; j++) {
169 distances[j] = (float)sqrt((
double)results_.
elements()[j].key);
170 results[j] = results_.
elements()[j].value;
184 for (
int i = 0; i < KeySize; i++) {
187 if (KeyDesc[i].Circular) {
220 Level = NextLevel(Tree, -1);
221 while (Node !=
nullptr) {
223 PtrToNode = &(Node->
Left);
228 PtrToNode = &(Node->
Right);
232 Level = NextLevel(Tree, Level);
236 *PtrToNode =
MakeKDNode(Tree, Key, (
void *) Data, Level);
260 Father = &(Tree->
Root);
261 Current = Father->
Left;
262 Level = NextLevel(Tree, -1);
265 while ((Current !=
nullptr) && (!
NodeFound (Current, Key, Data))) {
268 Current = Current->
Left;
270 Current = Current->
Right;
272 Level = NextLevel(Tree, Level);
275 if (Current !=
nullptr) {
276 if (Current == Father->
Left) {
277 Father->
Left =
nullptr;
280 Father->
Right =
nullptr;
307 KDTREE *Tree,
float Query[],
int QuerySize,
float MaxDistance,
308 int *NumberOfResults,
void **NBuffer,
float DBuffer[]) {
310 search.Search(NumberOfResults, DBuffer, NBuffer);
318 Walk(Tree, action, context, Tree->
Root.
Left, NextLevel(Tree, -1));
360 NewNode->
Data = Data;
364 NewNode->
Left =
nullptr;
365 NewNode->
Right =
nullptr;
380 void KDTreeSearch::SearchRec(
int level,
KDNODE *sub_tree) {
384 if (!BoxIntersectsSearch(sb_min_, sb_max_))
392 if (sub_tree->
Left !=
nullptr) {
393 float tmp = sb_max_[level];
395 SearchRec(NextLevel(tree_, level), sub_tree->
Left);
396 sb_max_[level] = tmp;
398 if (sub_tree->
Right !=
nullptr) {
399 float tmp = sb_min_[level];
401 SearchRec(NextLevel(tree_, level), sub_tree->
Right);
402 sb_min_[level] = tmp;
405 if (sub_tree->
Right !=
nullptr) {
406 float tmp = sb_min_[level];
408 SearchRec(NextLevel(tree_, level), sub_tree->
Right);
409 sb_min_[level] = tmp;
411 if (sub_tree->
Left !=
nullptr) {
412 float tmp = sb_max_[level];
414 SearchRec(NextLevel(tree_, level), sub_tree->
Left);
415 sb_max_[level] = tmp;
430 float total_distance = 0;
432 for (; k > 0; k--, p1++, p2++, dim++) {
436 float dimension_distance = *p1 - *p2;
440 dimension_distance =
Magnitude(dimension_distance);
441 float wrap_distance = dim->
Max - dim->
Min - dimension_distance;
442 dimension_distance = std::min(dimension_distance, wrap_distance);
445 total_distance += dimension_distance * dimension_distance;
447 return total_distance;
459 bool KDTreeSearch::BoxIntersectsSearch(
float *lower,
float *upper) {
460 float *query = query_point_;
462 double total_distance = 0.0;
467 for (
int i = tree_->
KeySize; i > 0; i--, dim++, query++, lower++, upper++) {
471 float dimension_distance;
473 dimension_distance = *lower - *query;
474 else if (*query > *upper)
475 dimension_distance = *query - *upper;
477 dimension_distance = 0;
481 float wrap_distance = FLT_MAX;
483 wrap_distance = *query + dim->
Max - dim->
Min - *upper;
484 else if (*query > *upper)
485 wrap_distance = *lower - (*query - (dim->
Max - dim->
Min));
486 dimension_distance = std::min(dimension_distance, wrap_distance);
490 static_cast<double>(dimension_distance) * dimension_distance;
491 if (total_distance >= radius_squared)
515 KDNODE *sub_tree, int32_t level) {
516 (*action)(context, sub_tree->
Data, level);
517 if (sub_tree->
Left !=
nullptr)
518 Walk(tree, action, context, sub_tree->
Left, NextLevel(tree, level));
519 if (sub_tree->
Right !=
nullptr)
520 Walk(tree, action, context, sub_tree->
Right, NextLevel(tree, level));
525 if (nodes ==
nullptr)
535 if (sub_tree !=
nullptr) {
KDTreeSearch(KDTREE *tree, float *query_point, int k_closest)
KDTREE * MakeKDTree(int16_t KeySize, const PARAM_DESC KeyDesc[])
float DistanceSquared(int k, PARAM_DESC *dim, float p1[], float p2[])
const Key & max_insertable_key()
KDNODE * MakeKDNode(KDTREE *tree, float Key[], void *Data, int Index)
void FreeKDTree(KDTREE *Tree)
void Walk(KDTREE *tree, void_proc action, void *context, KDNODE *sub_tree, int32_t level)
void InsertNodes(KDTREE *tree, KDNODE *nodes)
void KDStore(KDTREE *Tree, float *Key, void *Data)
void FreeKDNode(KDNODE *Node)
void FreeSubTree(KDNODE *sub_tree)
void KDDelete(KDTREE *Tree, float Key[], void *Data)
LIST search(LIST list, void *key, int_compare is_equal)
void KDNearestNeighborSearch(KDTREE *Tree, float Query[], int QuerySize, float MaxDistance, int *NumberOfResults, void **NBuffer, float DBuffer[])
void Search(int *result_count, float *distances, void **results)
#define NodeFound(N, K, D)
void KDWalk(KDTREE *Tree, void_proc action, void *context)
Element(const Key &k, const Value &v)
bool insert(Key k, Value v)
float ComputeDistance(int k, PARAM_DESC *dim, float p1[], float p2[])
const Element * elements()