cgma
|
#include <RTree.hpp>
Classes | |
class | LessThan |
Public Types | |
typedef double(* | DistSqFunc )(CubitVector &a, Z &b) |
Public Member Functions | |
RTree (double tol=GEOMETRY_RESABS) | |
RTree (double tol, int max_c, int min_c) | |
~RTree () | |
CubitStatus | add (Z data) |
CubitStatus | find (const CubitBox &range_box, DLIList< Z > &range_members) |
CubitStatus | find (const CubitVector &ray_origin, const CubitVector &ray_direction, DLIList< Z > &range_members) |
CubitBoolean | remove (Z data) |
CubitStatus | k_nearest_neighbor (CubitVector &q, int k, double &closest_dist, DLIList< Z > &nearest_neighbors, DistSqFunc dist_sq_point_data) |
void | set_tol (double tol) |
double | get_tol () |
Static Public Member Functions | |
static bool | less_than_func (RTreeNode< Z > *&node_a, RTreeNode< Z > *&node_b) |
Private Member Functions | |
CubitStatus | recursive_find (RTreeNode< Z > *rect_tree, const CubitBox &range_box, DLIList< Z > &range_members) |
CubitStatus | recursive_find (RTreeNode< Z > *rect_tree, const CubitVector &ray_origin, const CubitVector &ray_direction, DLIList< Z > &range_members) |
void | to_list (DLIList< RTreeNode< Z > * > &member_list, RTreeNode< Z > *top) |
double | min_dist_sq (CubitVector &q, CubitBox &b_box) |
Private Attributes | |
double | myTolerance |
int | maxChildren |
int | minChildren |
RTreeNode< Z > * | myRoot |
typedef double(* RTree< Z >::DistSqFunc)(CubitVector &a, Z &b) |
Reimplemented from AbstractTree< Z >.
MY_INLINE RTree< Z >::RTree | ( | double | tol = GEOMETRY_RESABS | ) |
Definition at line 31 of file RTree.cpp.
{ myRoot = NULL; myTolerance = tol; maxChildren = 8; minChildren = 2; }
Definition at line 38 of file RTree.cpp.
{ myRoot = NULL; myTolerance = tol; maxChildren = max_c; minChildren = min_c; }
Implements AbstractTree< Z >.
Definition at line 76 of file RTree.cpp.
{ CubitStatus stat; RTreeNode<Z> *new_root; RTreeNode<Z> *new_node = new RTreeNode<Z> (data, myTolerance, maxChildren, minChildren); if ( myRoot == NULL ) { CubitBox b_box = data->bounding_box(); myRoot = new RTreeNode <Z> (b_box, maxChildren, minChildren); myRoot->set_leaf_level(LEAF_RNODE); stat = myRoot->insert(new_node, new_root); //this shouldn't change the root, or fail! if ( stat != CUBIT_SUCCESS || new_root != NULL ) { PRINT_ERROR("Insertion into RTree failed.\n"); return CUBIT_FAILURE; } return CUBIT_SUCCESS; } stat = myRoot->insert(new_node, new_root); if ( stat != CUBIT_SUCCESS ) { PRINT_ERROR("Insertion into RTree failed.\n"); return CUBIT_FAILURE; } if ( new_root != NULL ) { //this is fine, it just means we are adding more //so the root had to be split... myRoot = new_root; } return CUBIT_SUCCESS; }
MY_INLINE CubitStatus RTree< Z >::find | ( | const CubitBox & | range_box, |
DLIList< Z > & | range_members | ||
) | [virtual] |
Implements AbstractTree< Z >.
Definition at line 111 of file RTree.cpp.
{ //Find all of the members of the RTree that intersect this range_box. if ( myRoot == NULL ) { // Nothing has been added to this Tree yet, so we are not going to find this // object in it. return CUBIT_SUCCESS; } CubitStatus stat = recursive_find(myRoot, range_box, range_members); if ( stat != CUBIT_SUCCESS ) return CUBIT_FAILURE; else return CUBIT_SUCCESS; }
MY_INLINE CubitStatus RTree< Z >::find | ( | const CubitVector & | ray_origin, |
const CubitVector & | ray_direction, | ||
DLIList< Z > & | range_members | ||
) |
Definition at line 296 of file RTree.cpp.
{ //Find all of the members of the RTree that intersect this ray. if ( myRoot == NULL ) { // Nothing has been added to this Tree yet, so we are not going to find this // object in it. return CUBIT_SUCCESS; } CubitStatus stat = recursive_find(myRoot, ray_origin, ray_direction, range_members); if ( stat != CUBIT_SUCCESS ) return CUBIT_FAILURE; else return CUBIT_SUCCESS; }
MY_INLINE CubitStatus RTree< 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 234 of file RTree.cpp.
{ //first create the priority queue. PriorityQueue< RTreeNode<Z>*> near_queue(RTree<Z>::less_than_func); myRoot->set_dist(0.0); near_queue.push(myRoot); RTreeNode<Z> *element, *child_element; int num_found = 0; int ii; double data_dist, box_dist; Z data; while( !near_queue.empty() ) { element = near_queue.top(); near_queue.pop(); if ( element->is_data() ) { data = element->get_data(); //calculate the exact distance. data_dist = dist_sq_point_data(q, data); //compare this distance with the next item's distance. if ( element->dist_is_box() && !near_queue.empty() && data_dist > near_queue.top()->get_dist()) { //If its bigger, add it back into the list //with the updated distance. element->set_dist(data_dist); near_queue.push(element); element->set_dist_is_box(0); } else { nearest_neighbors.append(element->get_data()); if ( num_found == 0 ) closest_dist = element->get_dist(); num_found++; if ( num_found == k ) return CUBIT_SUCCESS; } } else { for ( ii = 0; ii < element->num_children(); ii++ ) { child_element = element->get_child(ii); CubitBox bounding_box = child_element->bounding_box(); box_dist = min_dist_sq(q, bounding_box); child_element->set_dist(box_dist); near_queue.push(child_element); } } } return CUBIT_FAILURE; }
MY_INLINE double RTree< Z >::min_dist_sq | ( | CubitVector & | q, |
CubitBox & | b_box | ||
) | [private] |
Definition at line 189 of file RTree.cpp.
{ CubitVector b_min, b_max; b_min = b_box.minimum(); b_max = b_box.maximum(); double dist; 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()); dist = (q-r).length_squared(); return dist; }
MY_INLINE CubitStatus RTree< Z >::recursive_find | ( | RTreeNode< Z > * | rect_tree, |
const CubitBox & | range_box, | ||
DLIList< Z > & | range_members | ||
) | [private] |
Definition at line 127 of file RTree.cpp.
{ CubitBox rect_box = rect_tree->bounding_box(); if ( !range_box.overlap(myTolerance, rect_box ) ) return CUBIT_SUCCESS; //Now see if this is a data member. If it is, append the data to the //list. if (rect_tree->is_data() ) { range_members.append(rect_tree->get_data()); return CUBIT_SUCCESS; } //Now if this is anything else we need to keep iterating... int loop_size = rect_tree->num_children(); //We are doing a depth-first search of the tree. Not //all branches will need to be followed since they won't //all overlap... int ii; RTreeNode<Z> *curr_node; CubitStatus stat; for ( ii = 0; ii < loop_size; ii++ ) { curr_node = rect_tree->get_child(ii); if ( curr_node == NULL ) { PRINT_ERROR("Problems finding boxes in range.\n"); assert(curr_node != NULL); return CUBIT_FAILURE; } stat = recursive_find(curr_node, range_box, range_members); if ( stat != CUBIT_SUCCESS ) return stat; } return CUBIT_SUCCESS; }
MY_INLINE CubitStatus RTree< Z >::recursive_find | ( | RTreeNode< Z > * | rect_tree, |
const CubitVector & | ray_origin, | ||
const CubitVector & | ray_direction, | ||
DLIList< Z > & | range_members | ||
) | [private] |
Definition at line 314 of file RTree.cpp.
{ CubitBox rect_box = rect_tree->bounding_box(); //if ( !range_box.overlap(myTolerance, rect_box ) ) if ( !rect_box.intersect(ray_origin, ray_direction) ) return CUBIT_SUCCESS; //Now see if this is a data member. If it is, append the data to the //list. if (rect_tree->is_data() ) { range_members.append(rect_tree->get_data()); return CUBIT_SUCCESS; } //Now if this is anything else we need to keep iterating... int loop_size = rect_tree->num_children(); //We are doing a depth-first search of the tree. Not //all branches will need to be followed since they won't //all overlap... int ii; RTreeNode<Z> *curr_node; CubitStatus stat; for ( ii = 0; ii < loop_size; ii++ ) { curr_node = rect_tree->get_child(ii); if ( curr_node == NULL ) { PRINT_ERROR("Problems finding boxes in range.\n"); assert(curr_node != NULL); return CUBIT_FAILURE; } stat = recursive_find(curr_node, ray_origin, ray_direction, range_members); if ( stat != CUBIT_SUCCESS ) return stat; } return CUBIT_SUCCESS; }
Implements AbstractTree< Z >.
Definition at line 166 of file RTree.cpp.
{ RTreeNode<Z> *new_root = NULL; CubitBoolean delete_root = CUBIT_FALSE; CubitBoolean return_val = myRoot->remove( data, new_root, delete_root ); if ( new_root != NULL ) { //Only if we are condensing the tree do we want to delete the root node. //There are other reasons the root has changed (rebalance...), in which //cases the root is now a child of the new root... if ( delete_root ) delete myRoot; myRoot = new_root; } return return_val; }
MY_INLINE void RTree< Z >::to_list | ( | DLIList< RTreeNode< Z > * > & | member_list, |
RTreeNode< Z > * | top | ||
) | [private] |
Definition at line 58 of file RTree.cpp.
{ //Get the children of the top into the list. int ii; RTreeNode <Z> *curr_node; for ( ii = 0; ii < top->num_children(); ii++ ) { curr_node = top->get_child(ii); member_list.append(curr_node); //don't go below the bottom level... if ( curr_node->get_leaf_level() == 0 ) continue; to_list(member_list, curr_node); } return; }
int RTree< Z >::maxChildren [private] |
int RTree< Z >::minChildren [private] |
double RTree< Z >::myTolerance [private] |