cgma
RStarTree.cpp
Go to the documentation of this file.
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     
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines