|
Space-efficient geometric algorithms and data structuresBy Ilya Katz and Hervé Brönnimann |
00001 /* 00002 * Copyright © Ilya Katz and Herve Bronnimann, 2005. 00003 */ 00004 00018 #ifndef DYNAMIC_KD_TREE_HPP 00019 #define DYNAMIC_KD_TREE_HPP 00020 00021 #include <iterator> 00022 #include "static_kd_tree.hpp" 00023 00024 namespace inplaceds 00025 { 00026 00039 //\O(n\log{n}) 00040 template <class RandomAccessIterator, class AxisAlignedGeometry> 00041 inline void 00042 build_dynamic_kdtree(RandomAccessIterator first, RandomAccessIterator last, 00043 AxisAlignedGeometry geom) 00044 { 00045 if((last-first)%STATIC_KD_TREE_CUTOFF !=0 ) 00046 { 00047 00048 build_static_kdtree( 00049 last - (last-first) % STATIC_KD_TREE_CUTOFF, last, geom); 00050 00051 } 00052 00053 typedef typename 00054 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00055 00056 Distance block = STATIC_KD_TREE_CUTOFF, 00057 n = (last-first) / STATIC_KD_TREE_CUTOFF, 00058 t = (last-first) % STATIC_KD_TREE_CUTOFF; 00059 00060 while(n!=0) 00061 { 00062 if(n%2!=0) 00063 { 00064 00065 build_static_kdtree(last-t-block, last-t, geom); 00066 t = t+block; 00067 } 00068 00069 block*=2; 00070 n/=2; 00071 } 00072 } 00073 00093 template <class RandomAccessIterator, class AxisAlignedGeometry> 00094 void 00095 insert_dynamic_kdtree(RandomAccessIterator first, RandomAccessIterator last, 00096 AxisAlignedGeometry geom) 00097 { 00098 00099 //last-first is the new size 00100 if((last-first)%STATIC_KD_TREE_CUTOFF != 0) 00101 { 00102 return; 00103 00104 } 00105 00106 typedef typename 00107 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00108 00109 Distance block = STATIC_KD_TREE_CUTOFF, 00110 n = (last-first-1) / STATIC_KD_TREE_CUTOFF; 00111 00112 while(n%2!=0) 00113 { 00114 block*=2; 00115 n/=2; 00116 } 00117 00118 build_dynamic_kdtree(last-block, last, geom); 00119 } 00120 00140 template <class Box, class RandomAccessIterator, class OutputIterator, 00141 class AxisAlignedGeometry> 00142 OutputIterator 00143 window_query_dynamic_kdtree(RandomAccessIterator first, RandomAccessIterator last, 00144 AxisAlignedGeometry geom, Box Q, OutputIterator result) 00145 { 00146 00147 if((last-first)%STATIC_KD_TREE_CUTOFF < 00148 STATIC_KD_TREE_CUTOFF -1) 00149 { 00150 window_query_static_kdtree( 00151 last - (last-first) % STATIC_KD_TREE_CUTOFF, last, geom, Q, result); 00152 00153 } 00154 00155 typedef typename 00156 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00157 00158 Distance block = STATIC_KD_TREE_CUTOFF, 00159 n = (last-first) / STATIC_KD_TREE_CUTOFF, 00160 t = (last-first) % STATIC_KD_TREE_CUTOFF; 00161 00162 while(n!=0) 00163 { 00164 if(n%2 !=0) 00165 { 00166 window_query_static_kdtree (last-t-block, last-t, geom, Q, result); 00167 t = t+block; 00168 } 00169 00170 block*=2; 00171 n/=2; 00172 } 00173 00174 } 00175 00176 template <class Halfplane, class RandomAccessIterator, class OutputIterator, 00177 class AxisAlignedGeometry> 00178 OutputIterator 00179 halfplane_query_dynamic_kdtree(RandomAccessIterator first, RandomAccessIterator last, 00180 AxisAlignedGeometry geom, Halfplane Q, OutputIterator result) 00181 { 00182 00183 if((last-first)%STATIC_KD_TREE_CUTOFF < 00184 STATIC_KD_TREE_CUTOFF -1) 00185 { 00186 halfplane_query_static_kdtree( 00187 last - (last-first) % STATIC_KD_TREE_CUTOFF, last, geom, Q, result); 00188 00189 } 00190 00191 typedef typename 00192 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00193 00194 Distance block = STATIC_KD_TREE_CUTOFF, 00195 n = (last-first) / STATIC_KD_TREE_CUTOFF, 00196 t = (last-first) % STATIC_KD_TREE_CUTOFF; 00197 00198 while(n!=0) 00199 { 00200 if(n%2 !=0) 00201 { 00202 halfplane_query_static_kdtree (last-t-block, last-t, geom, Q, result); 00203 t = t+block; 00204 } 00205 00206 block*=2; 00207 n/=2; 00208 } 00209 00210 } 00211 00230 template <class RandomAccessIterator, class AxisAlignedGeometry> 00231 void 00232 remove_dynamic_kdtree(RandomAccessIterator first, RandomAccessIterator pos, RandomAccessIterator last, 00233 AxisAlignedGeometry geom) 00234 { 00235 --last; 00236 std::swap(*pos,*last); 00237 00238 typedef typename 00239 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00240 00241 Distance block = STATIC_KD_TREE_CUTOFF, 00242 n = (last-first) / STATIC_KD_TREE_CUTOFF, 00243 t = (last-first) % STATIC_KD_TREE_CUTOFF; 00244 00245 if(t!=0) 00246 { 00247 build_static_kdtree(last-t, last, geom); 00248 } 00249 00250 while(last-t >= pos && n!=0) 00251 { 00252 if(n%2!=0) 00253 { 00254 build_static_kdtree(last-block-t, last-t, geom); 00255 t+=block; 00256 } 00257 00258 block*=2; 00259 n/=2; 00260 } 00261 } 00262 00263 }//namespace 00264 #endif
Code Documentation generated Using Doxygen
Copyright © Ilya Katz and Hervé Brönnimann, 2005, 2006.