Space-efficient geometric algorithms and data structures

By Ilya Katz and Hervé Brönnimann    

dynamic_kd_tree.hpp

Go to the documentation of this file.
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.