|
cgma
|
#include <KDDTree.hpp>
Definition at line 38 of file KDDTree.hpp.
| typedef double(* KDDTree< Z >::DistSqFunc)(CubitVector &a, Z &b) |
Reimplemented from AbstractTree< Z >.
Definition at line 112 of file KDDTree.hpp.
| KDDTree< Z >::KDDTree | ( | double | tol = GEOMETRY_RESABS, |
| CubitBoolean | selfBalancingOn = CUBIT_TRUE, |
||
| double | selfBalancingDeletionTolerance = KDDTREE_DEFAULT_SELF_BALANCING_DELETION_TOLERANCE, |
||
| CubitBoolean | randomOn = CUBIT_FALSE |
||
| ) |
Definition at line 46 of file KDDTree.cpp.
{
root = NULL;
myTolerance = tol;
mySelfBalancingOn = selfBalancingOn;
myDeletionTolerance = selfBalancingDeletionTolerance;
myMarkedNodes = 0;
myRandomOn = randomOn;
if (myRandomOn)
{
srand( (unsigned)time( NULL ) );
}
}
Definition at line 66 of file KDDTree.cpp.
{
int i;
for (i = myAddList.size(); i > 0; i--)
{
delete myAddList.pop();
}
for (i = myNodeList.size(); i > 0; i--)
{
KDDTreeNode<Z> *node = myNodeList.pop();
delete node;
}
}
| CubitStatus KDDTree< Z >::add | ( | Z | data | ) | [virtual] |
Implements AbstractTree< Z >.
Definition at line 391 of file KDDTree.cpp.
{
KDDTreeNode<Z> *P = new KDDTreeNode<Z> (data);
P->safetyBox.reset (data->bounding_box());
myAddList.push (P);
return CUBIT_SUCCESS;
}
| CubitStatus KDDTree< Z >::balance | ( | ) | [virtual] |
Reimplemented from AbstractTree< Z >.
Definition at line 266 of file KDDTree.cpp.
{
int arraypos = 0;
KDDTreeNode<Z> ** array = new KDDTreeNode<Z>*[myAddList.size () + myNodeList.size ()];
root = NULL;
while (myAddList.size () > 0)
{
array[arraypos] = myAddList.pop();
arraypos++;
}
while (myNodeList.size () > 0)
{
array[arraypos] = myNodeList.pop();
if (array[arraypos]->valid == CUBIT_FALSE)
{
array[arraypos]->left = NULL;
array[arraypos]->right = NULL;
delete array[arraypos];
}
else
{
arraypos++;
}
}
int left = 0;
int right = (arraypos - 1);
root = recursive_balance (DIMX, left, right, array, NULL);
myMarkedNodes = 0;
delete [] array;
return CUBIT_SUCCESS;
}
| CubitStatus KDDTree< Z >::dump_list | ( | ) | [private] |
Definition at line 81 of file KDDTree.cpp.
{
while (myAddList.size() > 0)
{
KDDTreeNode<Z> *node = myAddList.pop();
insert_node (node);
}
return CUBIT_SUCCESS;
}
| CubitStatus KDDTree< Z >::find | ( | const CubitBox & | range_box, |
| DLIList< Z > & | range_members | ||
| ) | [virtual] |
Implements AbstractTree< Z >.
Definition at line 510 of file KDDTree.cpp.
{
if (myAddList.size() > 0)
{
if (mySelfBalancingOn == CUBIT_TRUE) // self-balancing is on, so rebalance the tree
{
balance ();
}
else // self-balancing is off, so put everything in the Add List onto the tree
{
dump_list ();
}
}
if (root != NULL)
{
recursive_find (root, range_box, range_members);
}
return CUBIT_SUCCESS;
}
| int KDDTree< Z >::find_max_height | ( | ) |
Definition at line 366 of file KDDTree.cpp.
{
int depth = 0, maxdepth = 0;
recursive_find_max_height (root, depth, &maxdepth);
return maxdepth;
}
| KDDTreeNode<Z>* KDDTree< Z >::find_minimum_node_of_dimension | ( | KDDTreeNode< Z > * | P, |
| DIMENSION | D | ||
| ) | [private] |
| KDDTreeNode< Z > * KDDTree< Z >::find_node_containing_data | ( | KDDTreeNode< Z > * | subtreeRoot, |
| Z | data | ||
| ) | [private] |
Definition at line 402 of file KDDTree.cpp.
{
KDDTreeNode<Z> *T = new KDDTreeNode<Z>(data); // temp node to use in searching
KDDTreeNode<Z> *P = subtreeRoot; // node to delete
DIRECTION D;
while (P != NULL)
{
if ((P->boundingBox.minimum() == T->boundingBox.minimum()) &&
(P->boundingBox.maximum() == T->boundingBox.maximum()))
{
if (P->valid == CUBIT_TRUE)
{
break; // the bounding boxes match and this node has not been deleted
}
}
D = T->compare_with_equality (P);
if (D == DIR_EITHER)
{
KDDTreeNode<Z> *leftResult = find_node_containing_data (P->get_child (DIR_LEFT), data);
if (leftResult != NULL)
{
P = leftResult;
break;
}
KDDTreeNode<Z> *rightResult = find_node_containing_data (P->get_child (DIR_RIGHT), data);
if (rightResult != NULL)
{
P = rightResult;
break;
}
P = NULL;
}
else
{
P = P->get_child (D);
}
}
delete T;
return P;
}
| CubitStatus KDDTree< Z >::insert_node | ( | KDDTreeNode< Z > * | P | ) | [private] |
Definition at line 113 of file KDDTree.cpp.
{
KDDTreeNode<Z> *F = NULL; // father node
KDDTreeNode<Z> *T; // temp node
if (root == NULL)
{
root = P;
P->set_disc (DIMX);
}
else
{
T = root;
DIRECTION direction = DIR_NULL;
while (T != NULL)
{
F = T; // remember the father
direction = P->compare (T);
CubitVector tmin = T->safetyBox.minimum();
CubitVector tmax = T->safetyBox.maximum();
CubitVector pmin = P->safetyBox.minimum();
CubitVector pmax = P->safetyBox.maximum();
if (pmin.x() < tmin.x()) tmin.x (pmin.x());
if (pmin.y() < tmin.y()) tmin.y (pmin.y());
if (pmin.z() < tmin.z()) tmin.z (pmin.z());
if (pmax.x() > tmax.x()) tmax.x (pmax.x());
if (pmax.y() > tmax.y()) tmax.y (pmax.y());
if (pmax.z() > tmax.z()) tmax.z (pmax.z());
T->safetyBox.reset (tmin, tmax);
T = T->get_child (direction);
}
F->set_child (P, direction);
P->set_disc (F->next_disc());
P->parent = F;
}
myNodeList.push (P);
return CUBIT_SUCCESS;
}
| CubitStatus KDDTree< Z >::k_nearest_neighbor | ( | CubitVector & | q, |
| int | k, | ||
| double & | closest_dist, | ||
| DLIList< Z > & | nearest_neighbors, | ||
| DistSqFunc | dist_sq_point_data | ||
| ) | [virtual] |
Implements AbstractTree< Z >.
Definition at line 646 of file KDDTree.cpp.
{
PriorityQueue<KDDTreeNode<Z>*> *queue = new PriorityQueue<KDDTreeNode<Z>*> (KDDTree<Z>::less_than_func);
PriorityQueue<KDDTreeNode<Z>*> *queueTemp = new PriorityQueue<KDDTreeNode<Z>*> (KDDTree<Z>::less_than_func);
KDDTreeNode<Z> *element = root;
// push this node on the queue
element->set_dist (min_dist_sq (q, element->safetyBox));
element->set_dist_data (DD_SAFETY);
queue->push (element);
// if the k closest nodes on the tree are not leaf-nodes, expand the closest
// non-leaf node
while ( !queue->empty() )
{
element = queue->top();
queue->pop();
if (element->get_dist_data() == DD_LEAF)
{
// this node is a leaf, so it can be pushed onto the temporary queue
queueTemp->push (element);
}
else
{
// one of the top k nodes is a non-leaf node, so expand it
if (element->left)
{
element->left->set_dist (min_dist_sq (q, element->left->safetyBox));
element->left->set_dist_data (DD_SAFETY);
queue->push (element->left);
}
if (element->right)
{
element->right->set_dist (min_dist_sq (q, element->right->safetyBox));
element->right->set_dist_data (DD_SAFETY);
queue->push (element->right);
}
element->set_dist (dist_sq_point_data (q, element->data));
element->set_dist_data (DD_LEAF);
queue->push (element);
// take all the elements in the temporary queue and reinsert them into
// the actual queue
while ( !queueTemp->empty() )
{
queue->push ( queueTemp->top() );
queueTemp->pop ();
}
}
if (queueTemp->size() == k)
{
// success-- place the k nodes into the nearest_neighbors list
element = queueTemp->top();
queueTemp->pop();
closest_dist = element->get_dist();
nearest_neighbors.append (element->data);
while ( !queueTemp->empty() )
{
nearest_neighbors.append ( queueTemp->top()->data );
queueTemp->pop();
}
return CUBIT_SUCCESS;
}
}
return CUBIT_FAILURE;
}
| bool KDDTree< Z >::less_than_func | ( | KDDTreeNode< Z > *& | node_a, |
| KDDTreeNode< Z > *& | node_b | ||
| ) | [static] |
Definition at line 623 of file KDDTree.cpp.
| double KDDTree< Z >::min_dist_sq | ( | CubitVector & | q, |
| CubitBox & | b_box | ||
| ) | [private] |
Definition at line 570 of file KDDTree.cpp.
{
CubitVector b_min = b_box.minimum();
CubitVector b_max = b_box.maximum();
CubitVector r;
if (q.x () < b_min.x ())
{
r.x (b_min.x ());
}
else if (q.x () > b_max.x ())
{
r.x (b_max.x ());
}
else
{
r.x (q.x ());
}
if (q.y () < b_min.y ())
{
r.y (b_min.y ());
}
else if (q.y () > b_max.y ())
{
r.y (b_max.y ());
}
else
{
r.y (q.y ());
}
if (q.z () < b_min.z ())
{
r.z (b_min.z ());
}
else if (q.z () > b_max.z ())
{
r.z (b_max.z ());
}
else
{
r.z (q.z ());
}
double dist = (q-r).length_squared();
return dist;
}
| int KDDTree< Z >::modifind | ( | DIMENSION | dim, |
| int | left, | ||
| int | right, | ||
| KDDTreeNode< Z > * | array[] | ||
| ) | [private] |
Definition at line 175 of file KDDTree.cpp.
{
int K = ((right - left + 1) / 2) + left + 1;
int L = left + 1;
int R = right + 1;
int I, J;
KDDTreeNode<Z>* node; // "X" in MODIFIND
KDDTreeNode<Z>* temp; // temp for swapping; "W" in MODIFIND
if (myRandomOn == CUBIT_TRUE)
{
int pivot = ( rand() % (right - left) ) + left; // create random pivot between left and right
temp = array[pivot];
array[pivot] = array[K - 1];
array[K - 1] = temp;
}
while (L < R)
{
node = array[K - 1];
I = L;
J = R;
while (! ((J < K) || (K < I)) )
{
if (dim == DIMX)
{
while (array[I - 1]->x < node->x) {
I++;
}
while (node->x < array[J - 1]->x) {
J--;
}
}
else if (dim == DIMY)
{
while (array[I - 1]->y < node->y) {
I++;
}
while (node->y < array[J - 1]->y) {
J--;
}
}
else
{
while (array[I - 1]->z < node->z) {
I++;
}
while (node->z < array[J - 1]->z) {
J--;
}
}
temp = array[I - 1];
array[I - 1] = array[J - 1];
array[J - 1] = temp;
I++;
J--;
}
if (J < K)
{
L = I;
}
if (K < I)
{
R = J;
}
}
return K - 1;
}
| KDDTreeNode< Z > * KDDTree< Z >::recursive_balance | ( | DIMENSION | dim, |
| int | left, | ||
| int | right, | ||
| KDDTreeNode< Z > * | array[], | ||
| KDDTreeNode< Z > * | parent | ||
| ) | [private] |
Definition at line 305 of file KDDTree.cpp.
{
if (left > right)
{
return NULL;
}
else
{
KDDTreeNode<Z>* P;
int K;
if (left != right)
{
K = modifind (dim, left, right, array);
P = array[K];
}
else
{
K = left;
P = array[left];
}
myNodeList.push (P);
P->safetyBox.reset (P->boundingBox);
for (int i = left; i <= right; i++)
{
CubitVector imin = array[i]->safetyBox.minimum();
CubitVector imax = array[i]->safetyBox.maximum();
CubitVector pmin = P->safetyBox.minimum();
CubitVector pmax = P->safetyBox.maximum();
if (imin.x() < pmin.x()) pmin.x (imin.x());
if (imin.y() < pmin.y()) pmin.y (imin.y());
if (imin.z() < pmin.z()) pmin.z (imin.z());
if (imax.x() > pmax.x()) pmax.x (imax.x());
if (imax.y() > pmax.y()) pmax.y (imax.y());
if (imax.z() > pmax.z()) pmax.z (imax.z());
P->safetyBox.reset (pmin, pmax);
}
DIMENSION nextDim;
switch (dim)
{
case DIMX: nextDim = DIMY; break;
case DIMY: nextDim = DIMZ; break;
default: nextDim = DIMX;
}
P->set_disc (dim);
P->parent = parent;
P->left = recursive_balance (nextDim, left, K - 1, array, P);
P->right = recursive_balance (nextDim, K + 1, right, array, P);
return P;
}
}
| void KDDTree< Z >::recursive_find | ( | KDDTreeNode< Z > * | rect_tree, |
| const CubitBox & | range_box, | ||
| DLIList< Z > & | range_members | ||
| ) | [private] |
Definition at line 536 of file KDDTree.cpp.
{
if ( ! range_box.overlap (myTolerance, rect_tree->safetyBox) )
{
return; // no overlap, return
}
if ( range_box.overlap (myTolerance, rect_tree->boundingBox) )
{
if (rect_tree->valid == CUBIT_TRUE)
{
range_members.append (rect_tree->data); // append the data to the list.
}
}
if (rect_tree->left != NULL)
{
recursive_find (rect_tree->left, range_box, range_members);
}
if (rect_tree->right != NULL)
{
recursive_find (rect_tree->right, range_box, range_members);
}
return;
}
| void KDDTree< Z >::recursive_find_max_height | ( | KDDTreeNode< Z > * | root, |
| int | depth, | ||
| int * | maxdepth | ||
| ) | [private] |
Definition at line 376 of file KDDTree.cpp.
{
if (root)
{
depth++;
if (depth > *maxdepth)
{
*maxdepth = depth;
}
recursive_find_max_height (root->left, depth, maxdepth);
recursive_find_max_height (root->right, depth, maxdepth);
}
}
| CubitBoolean KDDTree< Z >::remove | ( | Z | data | ) | [virtual] |
Implements AbstractTree< Z >.
Definition at line 455 of file KDDTree.cpp.
{
if (myAddList.size() > 0)
{
if (mySelfBalancingOn == CUBIT_TRUE) // self-balancing is on, so rebalance the tree
{
balance ();
}
else // self-balancing is off, so put everything in the Add List onto the tree
{
dump_list ();
}
}
if (root == NULL)
{
return CUBIT_FALSE;
}
else
{
KDDTreeNode<Z> *P = find_node_containing_data (root, data);
if (P == NULL) // no matching node was found
{
return CUBIT_FALSE;
}
else // mark the matching node for deletion
{
if (P->valid == CUBIT_FALSE)
{
return CUBIT_FALSE; // this node was already deleted
}
P->valid = CUBIT_FALSE; // set the node to be deleted
myMarkedNodes++;
if (myDeletionTolerance != 0)
{
if ( (((double)myMarkedNodes / myNodeList.size()) > myDeletionTolerance) &&
(myMarkedNodes > 1)
)
{
balance ();
}
}
return CUBIT_TRUE;
}
}
}
Definition at line 43 of file KDDTree.hpp.
KDDTreeNode<Z>* KDDTree< Z >::myDeepestLeaf [private] |
Definition at line 44 of file KDDTree.hpp.
double KDDTree< Z >::myDeletionTolerance [private] |
Definition at line 46 of file KDDTree.hpp.
int KDDTree< Z >::myMarkedNodes [private] |
Definition at line 45 of file KDDTree.hpp.
| DLIList<KDDTreeNode<Z>*> KDDTree< Z >::myNodeList |
Definition at line 79 of file KDDTree.hpp.
CubitBoolean KDDTree< Z >::myRandomOn [private] |
Definition at line 47 of file KDDTree.hpp.
CubitBoolean KDDTree< Z >::mySelfBalancingOn [private] |
Definition at line 41 of file KDDTree.hpp.
double KDDTree< Z >::myTolerance [private] |
Definition at line 42 of file KDDTree.hpp.
| KDDTreeNode<Z>* KDDTree< Z >::root |
Definition at line 80 of file KDDTree.hpp.