BWAPI
|
00001 // Copyright (c) 2002 Utrecht University (The Netherlands). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Spatial_searching/include/CGAL/Kd_tree_node.h $ 00015 // $Id: Kd_tree_node.h 32847 2006-07-31 22:33:02Z afabri $ 00016 // 00017 // 00018 // Authors : Hans Tangelder (<hanst@cs.uu.nl>) 00019 00020 #ifndef CGAL_KD_TREE_NODE_H 00021 #define CGAL_KD_TREE_NODE_H 00022 00023 00024 #include <CGAL/Splitters.h> 00025 #include <CGAL/Compact_container.h> 00026 namespace CGAL { 00027 00028 template <class SearchTraits, class Splitter, class UseExtendedNode> 00029 class Kd_tree; 00030 00031 template < class TreeTraits, class Splitter, class UseExtendedNode > 00032 class Kd_tree_node { 00033 00034 friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>; 00035 00036 typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_handle Node_handle; 00037 enum Node_type {LEAF, INTERNAL, EXTENDED_INTERNAL}; 00038 typedef typename TreeTraits::Point_d Point_d; 00039 00040 typedef typename TreeTraits::FT FT; 00041 typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Separator Separator; 00042 typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Point_d_iterator Point_d_iterator; 00043 00044 private: 00045 00046 // node type identifier 00047 Node_type the_node_type; 00048 00049 // private variables for leaf nodes 00050 unsigned int n; // denotes number of items in a leaf node 00051 Point_d_iterator data; // iterator to data in leaf node 00052 00053 // private variables for internal nodes 00054 00055 Node_handle lower_ch, upper_ch; 00056 00057 Separator sep; 00058 00059 // private variables for extended internal nodes 00060 FT low_val; 00061 FT high_val; 00062 00063 public: 00064 00065 void * for_compact_container() const { return lower_ch.for_compact_container(); } 00066 void * & for_compact_container() { return lower_ch.for_compact_container(); } 00067 00068 // default constructor 00069 Kd_tree_node() 00070 {} 00071 00072 Kd_tree_node(Node_type t ) 00073 : the_node_type(t) 00074 {} 00075 00076 Kd_tree_node(int n_, Node_type t ) 00077 : the_node_type(t), n(n_) 00078 {} 00079 00080 // members for all nodes 00081 inline 00082 bool 00083 is_leaf() const 00084 { 00085 return (the_node_type==LEAF); 00086 } 00087 00088 // members for leaf nodes only 00089 inline 00090 unsigned int 00091 size() const 00092 { 00093 return n; 00094 } 00095 00096 inline 00097 Point_d_iterator 00098 begin() const 00099 { 00100 return data; 00101 } 00102 00103 inline 00104 Point_d_iterator 00105 end() const 00106 { 00107 return data + n; 00108 } 00109 00110 // members for internal node and extended internal node 00111 00112 inline 00113 Node_handle 00114 lower() const 00115 { 00116 return lower_ch; 00117 } 00118 00119 inline 00120 Node_handle 00121 upper() const 00122 { 00123 return upper_ch; 00124 } 00125 00126 // inline Separator& separator() {return sep; } 00127 // use instead 00128 00129 inline 00130 FT 00131 cutting_value() const 00132 { 00133 return sep.cutting_value(); 00134 } 00135 00136 inline 00137 int 00138 cutting_dimension() const 00139 { 00140 return sep.cutting_dimension(); 00141 } 00142 00143 // members for extended internal node only 00144 inline 00145 FT 00146 low_value() const 00147 { 00148 return low_val; 00149 } 00150 00151 inline 00152 FT 00153 high_value() const 00154 { 00155 return high_val; 00156 } 00157 00158 00159 Separator& 00160 separator() 00161 { 00162 return sep; 00163 } 00164 00165 00166 unsigned int 00167 num_items() 00168 { 00169 if (is_leaf()) return size(); 00170 else 00171 return lower()->num_items() + upper()->num_items(); 00172 } 00173 00174 unsigned int 00175 num_nodes() 00176 { 00177 if (is_leaf()) return 1; 00178 else 00179 return lower()->num_nodes() + upper()->num_nodes(); 00180 } 00181 00182 int 00183 depth(const int current_max_depth) const 00184 { 00185 if (is_leaf()){ 00186 return current_max_depth; 00187 } 00188 else return 00189 (std::max)( lower()->depth(current_max_depth + 1), 00190 upper()->depth(current_max_depth + 1)); 00191 } 00192 00193 int 00194 depth() const 00195 { 00196 return depth(1); 00197 } 00198 00199 template <class OutputIterator> 00200 OutputIterator 00201 tree_items(OutputIterator it) { 00202 if (is_leaf()) 00203 { 00204 if (n>0) 00205 for (Point_d_iterator i=begin(); i != end(); i++) 00206 {*it=**i; ++it;} 00207 } 00208 else { 00209 it=lower_ch->tree_items(it); 00210 it=upper_ch->tree_items(it); 00211 }; 00212 return it; 00213 } 00214 00215 00216 void 00217 indent(int d) const 00218 { 00219 for(int i = 0; i < d; i++){ 00220 std::cout << " "; 00221 } 00222 } 00223 00224 00225 void 00226 print(int d = 0) const 00227 { 00228 if (is_leaf()) 00229 { 00230 indent(d); 00231 std::cout << "leaf" << std::endl; 00232 if (n>0) 00233 for (Point_d_iterator i=begin(); i != end(); i++) 00234 {indent(d);std::cout << **i << std::endl;} 00235 } 00236 else { 00237 indent(d); 00238 std::cout << "lower tree" << std::endl; 00239 lower_ch->print(d+1); 00240 indent(d); 00241 std::cout << "separator: dim = " << sep.cutting_dimension() << " val = " << sep.cutting_value() << std::endl; 00242 indent(d); 00243 std::cout << "upper tree" << std::endl; 00244 upper_ch->print(d+1); 00245 } 00246 } 00247 00248 template <class OutputIterator, class FuzzyQueryItem> 00249 OutputIterator 00250 search(OutputIterator it, const FuzzyQueryItem& q, 00251 Kd_tree_rectangle<TreeTraits>& b) 00252 { 00253 if (is_leaf()) { 00254 if (n>0) 00255 for (Point_d_iterator i=begin(); i != end(); i++) 00256 if (q.contains(**i)) 00257 {*it=**i; ++it;} 00258 } 00259 else { 00260 // after splitting b denotes the lower part of b 00261 Kd_tree_rectangle<TreeTraits> b_upper(b); 00262 b.split(b_upper, sep.cutting_dimension(), 00263 sep.cutting_value()); 00264 00265 if (q.outer_range_contains(b)) 00266 it=lower_ch->tree_items(it); 00267 else 00268 if (q.inner_range_intersects(b)) 00269 it=lower_ch->search(it,q,b); 00270 if (q.outer_range_contains(b_upper)) 00271 it=upper_ch->tree_items(it); 00272 else 00273 if (q.inner_range_intersects(b_upper)) 00274 it=upper_ch->search(it,q,b_upper); 00275 }; 00276 return it; 00277 } 00278 00279 00280 }; 00281 00282 00283 } // namespace CGAL 00284 #endif // CGAL_KDTREE_NODE_H