31 #define Magnitude(X) ((X) < 0 ? -(X) : (X)) 32 #define NodeFound(N,K,D) (( (N)->Key == (K) ) && ( (N)->Data == (D) )) 37 #define MINSEARCH -MAX_FLOAT32 38 #define MAXSEARCH MAX_FLOAT32 41 static int NextLevel(
KDTREE *tree,
int level) {
52 template<
typename Key,
typename Value>
55 MinK(Key max_key,
int k);
66 bool insert(Key k, Value v);
70 const Element*
elements() {
return elements_; }
80 template<
typename Key,
typename Value>
82 max_key_(max_key), elements_count_(0), k_(k < 1 ? 1 : k), max_index_(0) {
83 elements_ =
new Element[k_];
86 template<
typename Key,
typename Value>
91 template<
typename Key,
typename Value>
93 if (elements_count_ < k_)
95 return elements_[max_index_].key;
98 template<
typename Key,
typename Value>
100 if (elements_count_ < k_) {
101 elements_[elements_count_++] = Element(key, value);
102 if (key > elements_[max_index_].key)
103 max_index_ = elements_count_ - 1;
105 }
else if (key < elements_[max_index_].key) {
107 elements_[max_index_] = Element(key, value);
109 for (
int i = 0; i < elements_count_; i++) {
110 if (elements_[i].key > elements_[max_index_].key)
128 void Search(
int *result_count,
FLOAT32 *distances,
void **results);
131 void SearchRec(
int Level,
KDNODE *SubTree);
143 query_point_(query_point),
162 for (
int i = 0; i < tree_->
KeySize; i++) {
168 *result_count =
count;
169 for (
int j = 0; j <
count; j++) {
172 results[j] = results_.
elements()[j].value;
186 for (
int i = 0; i < KeySize; i++) {
189 if (KeyDesc[i].Circular) {
226 Level = NextLevel(Tree, -1);
227 while (Node != NULL) {
229 PtrToNode = &(Node->
Left);
234 PtrToNode = &(Node->
Right);
238 Level = NextLevel(Tree, Level);
242 *PtrToNode =
MakeKDNode(Tree, Key, (
void *) Data, Level);
271 Father = &(Tree->
Root);
272 Current = Father->
Left;
273 Level = NextLevel(Tree, -1);
276 while ((Current != NULL) && (!
NodeFound (Current, Key, Data))) {
279 Current = Current->
Left;
281 Current = Current->
Right;
283 Level = NextLevel(Tree, Level);
286 if (Current != NULL) {
287 if (Current == Father->
Left) {
291 Father->
Right = NULL;
323 int *NumberOfResults,
void **NBuffer,
FLOAT32 DBuffer[]) {
325 search.Search(NumberOfResults, DBuffer, NBuffer);
333 Walk(Tree, action, context, Tree->
Root.
Left, NextLevel(Tree, -1));
379 NewNode->
Data = Data;
383 NewNode->
Left = NULL;
384 NewNode->
Right = NULL;
402 void KDTreeSearch::SearchRec(
int level,
KDNODE *sub_tree) {
406 if (!BoxIntersectsSearch(sb_min_, sb_max_))
410 query_point_, sub_tree->
Key),
414 if (sub_tree->
Left != NULL) {
417 SearchRec(NextLevel(tree_, level), sub_tree->
Left);
418 sb_max_[level] = tmp;
420 if (sub_tree->
Right != NULL) {
423 SearchRec(NextLevel(tree_, level), sub_tree->
Right);
424 sb_min_[level] = tmp;
427 if (sub_tree->
Right != NULL) {
430 SearchRec(NextLevel(tree_, level), sub_tree->
Right);
431 sb_min_[level] = tmp;
433 if (sub_tree->
Left != NULL) {
436 SearchRec(NextLevel(tree_, level), sub_tree->
Left);
437 sb_max_[level] = tmp;
454 for (; k > 0; k--, p1++, p2++, dim++) {
458 FLOAT32 dimension_distance = *p1 - *p2;
462 dimension_distance =
Magnitude(dimension_distance);
463 FLOAT32 wrap_distance = dim->
Max - dim->
Min - dimension_distance;
464 dimension_distance =
MIN(dimension_distance, wrap_distance);
467 total_distance += dimension_distance * dimension_distance;
469 return total_distance;
481 bool KDTreeSearch::BoxIntersectsSearch(
FLOAT32 *lower,
FLOAT32 *upper) {
489 for (
int i = tree_->
KeySize; i > 0; i--, dim++, query++, lower++, upper++) {
495 dimension_distance = *lower - *query;
496 else if (*query > *upper)
497 dimension_distance = *query - *upper;
499 dimension_distance = 0;
505 wrap_distance = *query + dim->
Max - dim->
Min - *upper;
506 else if (*query > *upper)
507 wrap_distance = *lower - (*query - (dim->
Max - dim->
Min));
508 dimension_distance =
MIN(dimension_distance, wrap_distance);
511 total_distance += dimension_distance * dimension_distance;
512 if (total_distance >= radius_squared)
537 (*action)(context, sub_tree->
Data, level);
538 if (sub_tree->
Left != NULL)
539 Walk(tree, action, context, sub_tree->
Left, NextLevel(tree, level));
540 if (sub_tree->
Right != NULL)
541 Walk(tree, action, context, sub_tree->
Right, NextLevel(tree, level));
556 if (sub_tree != NULL) {
FLOAT32 ComputeDistance(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
void Walk(KDTREE *tree, void_proc action, void *context, KDNODE *sub_tree, inT32 level)
#define NodeFound(N, K, D)
void KDDelete(KDTREE *Tree, FLOAT32 Key[], void *Data)
void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data)
KDTREE * MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[])
void memfree(void *element)
Element(const Key &k, const Value &v)
void InsertNodes(KDTREE *tree, KDNODE *nodes)
void FreeKDNode(KDNODE *Node)
LIST search(LIST list, void *key, int_compare is_equal)
void KDNearestNeighborSearch(KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance, int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[])
void FreeSubTree(KDNODE *sub_tree)
const Key & max_insertable_key()
void FreeKDTree(KDTREE *Tree)
bool insert(Key k, Value v)
void Search(int *result_count, FLOAT32 *distances, void **results)
KDTreeSearch(KDTREE *tree, FLOAT32 *query_point, int k_closest)
KDNODE * MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index)
const Element * elements()
FLOAT32 DistanceSquared(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
void KDWalk(KDTREE *Tree, void_proc action, void *context)