cgma
|
00001 //--------------------------------------------------------------------------- 00002 // Class Name: RStarTree 00003 // Description: Rectangle tree. Multidimensional access method (efficient 00004 // method to find ranges of boxes. 00005 // The algorithm was taken from the following paper: 00006 // Norbert Beckmann, H. Kriegel, R. Schnieder, and B. Seegar, 00007 // "The R*-tree: An Efficient and Robust Access Method 00008 // for Points and Rectangles", Proceedings of ACM SIGMOD 00009 // Int'l. Conf. on Management of Data, pp. 322-331, 1990. 00010 // Creation Date: 7/20/02 00011 // Owner: David R. White 00012 //--------------------------------------------------------------------------- 00013 00014 //--------------------------------- 00015 //Include Files 00016 //--------------------------------- 00017 #include "RStarTree.hpp" 00018 #include "RStarTreeNode.hpp" 00019 #include "CubitBox.hpp" 00020 #include "CubitVector.hpp" 00021 #include "DLIList.hpp" 00022 #include "PriorityQueue.hpp" 00023 //--------------------------- 00024 //Initialize Static Members 00025 //--------------------------- 00026 00027 #ifdef INLINE_TEMPLATES 00028 #define MY_INLINE inline 00029 #else 00030 #define MY_INLINE 00031 #endif 00032 00033 template <class Z> MY_INLINE RStarTree<Z>::~RStarTree() 00034 { 00035 if ( myRoot != NULL ) 00036 { 00037 //Go through and get all the children in a list. 00038 DLIList <RStarTreeNode<Z>*> to_delete; 00039 to_list(to_delete, myRoot); 00040 int ii; 00041 for(ii = to_delete.size(); ii > 0; ii-- ) 00042 delete to_delete.pop(); 00043 delete myRoot; 00044 } 00045 } 00046 template <class Z> MY_INLINE void RStarTree<Z>::to_list(DLIList <RStarTreeNode<Z>*> &member_list, 00047 RStarTreeNode<Z> *top) 00048 { 00049 //Get the children of the top into the list. 00050 int ii; 00051 RStarTreeNode <Z> *curr_node; 00052 for ( ii = 0; ii < top->num_children(); ii++ ) 00053 { 00054 curr_node = top->get_child(ii); 00055 member_list.append(curr_node); 00056 //don't go below the bottom level... 00057 if ( curr_node->get_leaf_level() == 0 ) 00058 continue; 00059 to_list(member_list, curr_node); 00060 } 00061 return; 00062 } 00063 00064 template <class Z> MY_INLINE CubitStatus RStarTree<Z>::recursive_find(RStarTreeNode<Z> *rect_tree, 00065 const CubitBox &range_box, 00066 DLIList <Z> &range_members ) 00067 { 00068 CubitBox rect_box = rect_tree->bounding_box(); 00069 if ( !range_box.overlap(myTolerance, rect_box ) ) 00070 return CUBIT_SUCCESS; 00071 00072 //Now see if this is a data member. If it is, append the data to the 00073 //list. 00074 if (rect_tree->is_data() ) 00075 { 00076 range_members.append(rect_tree->get_data()); 00077 return CUBIT_SUCCESS; 00078 } 00079 //Now if this is anything else we need to keep iterating... 00080 int loop_size = rect_tree->num_children(); 00081 //We are doing a depth-first search of the tree. Not 00082 //all branches will need to be followed since they won't 00083 //all overlap... 00084 int ii; 00085 RStarTreeNode<Z> *curr_node; 00086 CubitStatus stat; 00087 for ( ii = 0; ii < loop_size; ii++ ) 00088 { 00089 curr_node = rect_tree->get_child(ii); 00090 if ( curr_node == NULL ) 00091 { 00092 PRINT_ERROR("Problems finding boxes in range.\n"); 00093 assert(curr_node != NULL); 00094 return CUBIT_FAILURE; 00095 } 00096 stat = recursive_find(curr_node, range_box, range_members); 00097 if ( stat != CUBIT_SUCCESS ) 00098 return stat; 00099 } 00100 00101 return CUBIT_SUCCESS; 00102 } 00103 //-------------------------------------------------------------------------- 00104 //Algorithm: min_dist_sq 00105 //Description: Finds the minimum distance squared between the given 00106 // point and the box. If the point is on or in the box, the 00107 // min distance is zero. 00108 //-------------------------------------------------------------------------- 00109 template <class Z> MY_INLINE 00110 double RStarTree<Z>::min_dist_sq(CubitVector &q, 00111 CubitBox &b_box) 00112 { 00113 CubitVector b_min, b_max; 00114 b_min = b_box.minimum(); 00115 b_max = b_box.maximum(); 00116 double dist; 00117 CubitVector r; 00118 00119 if ( q.x() < b_min.x() ) 00120 r.x(b_min.x()); 00121 else if ( q.x() > b_max.x() ) 00122 r.x(b_max.x()); 00123 else 00124 r.x(q.x()); 00125 00126 if ( q.y() < b_min.y() ) 00127 r.y(b_min.y()); 00128 else if ( q.y() > b_max.y() ) 00129 r.y(b_max.y()); 00130 else 00131 r.y(q.y()); 00132 00133 if ( q.z() < b_min.z() ) 00134 r.z(b_min.z()); 00135 else if ( q.z() > b_max.z() ) 00136 r.z(b_max.z()); 00137 else 00138 r.z(q.z()); 00139 00140 dist = (q-r).length_squared(); 00141 00142 return dist; 00143 } 00144 00145 00146