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_rectangle.h $ 00015 // $Id: Kd_tree_rectangle.h 28567 2006-02-16 14:30:13Z lsaboret $ 00016 // 00017 // 00018 // Author(s) : Hans Tangelder (<hanst@cs.uu.nl>) 00019 00020 #ifndef CGAL_KD_TREE_RECTANGLE_H 00021 #define CGAL_KD_TREE_RECTANGLE_H 00022 00023 #include <functional> 00024 #include <algorithm> 00025 #include <new> 00026 #include <CGAL/assertions.h> 00027 00028 namespace CGAL { 00029 00030 template <class SearchTraits, class P, class T> 00031 struct set_bounds_from_pointer : public std::unary_function<P, void> { 00032 int dim; 00033 T *lower; 00034 T *upper; 00035 00036 set_bounds_from_pointer(int d, T *l, T *u) 00037 : dim(d), lower(l), upper(u) 00038 {} 00039 00040 void 00041 operator()(P p) 00042 { 00043 T h; 00044 typename SearchTraits::Construct_cartesian_const_iterator_d construct_it; 00045 typename SearchTraits::Cartesian_const_iterator_d pit = construct_it(*p); 00046 for (int i = 0; i < dim; ++i, ++pit) { 00047 h=(*pit); 00048 if (h < lower[i]) lower[i] = h; 00049 if (h > upper[i]) upper[i] = h; 00050 } 00051 } 00052 }; 00053 00054 00055 template <class SearchTraits> 00056 class Kd_tree_rectangle { 00057 public: 00058 typedef typename SearchTraits::FT FT; 00059 typedef FT T; 00060 00061 private: 00062 00063 int dim; 00064 T *lower_; 00065 T *upper_; 00066 int max_span_coord_; 00067 00068 public: 00069 00070 inline void 00071 set_upper_bound(int i, const FT& x) 00072 { 00073 CGAL_assertion(i >= 0 && i < dim); 00074 CGAL_assertion(x >= lower_[i]); 00075 upper_[i] = x; 00076 set_max_span(); 00077 } 00078 00079 inline void 00080 set_lower_bound(int i, const FT& x) 00081 { 00082 CGAL_assertion(i >= 0 && i < dim); 00083 CGAL_assertion(x <= upper_[i]); 00084 lower_[i] = x; 00085 set_max_span(); 00086 } 00087 00088 inline void 00089 set_max_span() 00090 { 00091 FT span = upper_[0]-lower_[0]; 00092 max_span_coord_ = 0; 00093 for (int i = 1; i < dim; ++i) { 00094 FT tmp = upper_[i] - lower_[i]; 00095 if (span < tmp) { 00096 span = tmp; 00097 max_span_coord_ = i; 00098 } 00099 } 00100 } 00101 00102 Kd_tree_rectangle(int d) 00103 : dim(d), lower_(new FT[d]), upper_(new FT[d]), max_span_coord_(0) 00104 { 00105 std::fill(lower_, lower_ + dim, 0); 00106 std::fill(upper_, upper_ + dim, 0); 00107 } 00108 00109 Kd_tree_rectangle() 00110 : dim(0), lower_(0), upper_(0) 00111 {} 00112 00113 00114 explicit 00115 Kd_tree_rectangle(const Kd_tree_rectangle<SearchTraits>& r) 00116 : dim(r.dim), lower_(new FT[dim]), upper_(new FT[dim]), 00117 max_span_coord_(r.max_span_coord_) 00118 { 00119 std::copy(r.lower_, r.lower_+dim, lower_); 00120 std::copy(r.upper_, r.upper_+dim, upper_); 00121 } 00122 00123 template <class PointPointerIter> // was PointIter 00124 Kd_tree_rectangle(int d, PointPointerIter begin, PointPointerIter end) 00125 : dim(d), lower_(new FT[d]), upper_(new FT[d]) 00126 { 00127 // initialize with values of first point 00128 typename SearchTraits::Construct_cartesian_const_iterator_d construct_it; 00129 typename SearchTraits::Cartesian_const_iterator_d bit = construct_it(**begin); 00130 00131 for (int i=0; i < dim; ++bit, ++i){ 00132 lower_[i]=(*bit); upper_[i]=lower_[i]; 00133 } 00134 begin++; 00135 typedef typename std::iterator_traits<PointPointerIter>::value_type P; 00136 00137 std::for_each(begin, end, set_bounds_from_pointer<SearchTraits, P,T>(dim, lower_, upper_)); 00138 set_max_span(); 00139 } 00140 00141 template <class PointPointerIter> 00142 void update_from_point_pointers(PointPointerIter begin, 00143 PointPointerIter end) 00144 { 00145 if (begin ==end) { // no points 00146 for (int i=0; i < dim; ++i) { 00147 lower_[i]= FT(1); upper_[i]= FT(-1); 00148 } 00149 } else { 00150 // initialize with values of first point 00151 typename SearchTraits::Construct_cartesian_const_iterator_d construct_it; 00152 typename SearchTraits::Cartesian_const_iterator_d bit = construct_it(**begin); 00153 00154 for (int i=0; i < dim; ++i, ++bit) { 00155 lower_[i]= *bit; upper_[i]=lower_[i]; 00156 } 00157 begin++; 00158 typedef typename std::iterator_traits<PointPointerIter>::value_type P; 00159 std::for_each(begin, end, 00160 set_bounds_from_pointer<SearchTraits,P,T>(dim, lower_, upper_)); 00161 } 00162 set_max_span(); 00163 } 00164 00165 inline int 00166 max_span_coord() const 00167 { 00168 return max_span_coord_; 00169 } 00170 00171 inline FT 00172 max_span() const 00173 { 00174 return upper_[max_span_coord_] - lower_[max_span_coord_]; 00175 } 00176 00177 inline FT 00178 min_coord(int i) const 00179 { 00180 CGAL_assertion(lower_ != NULL); 00181 return lower_[i]; 00182 } 00183 00184 inline FT 00185 max_coord(int i) const 00186 { 00187 return upper_[i]; 00188 } 00189 00190 std::ostream& 00191 print(std::ostream& s) const 00192 { 00193 s << "Rectangle dimension = " << dim; 00194 s << "\n lower: "; 00195 for (int i=0; i < dim; ++i) 00196 s << lower_[i] << " "; 00197 // std::copy(lower_, lower_ + dim, 00198 // std::ostream_iterator<FT>(s," ")); 00199 s << "\n upper: "; 00200 for (int j=0; j < dim; ++j) 00201 s << upper_[j] << " "; 00202 // std::copy(upper_, upper_ + dim, 00203 // std::ostream_iterator<FT>(s," ")); 00204 s << "\n maximum span " << max_span() << 00205 " at coordinate " << max_span_coord() << std::endl; 00206 return s; 00207 } 00208 00209 // Splits rectangle by modifying itself to lower half 00210 // and returns upper half 00211 // Kd_tree_rectangle* 00212 void 00213 split(Kd_tree_rectangle& r, int d, FT value) 00214 { 00215 CGAL_assertion(d >= 0 && d < dim); 00216 CGAL_assertion(lower_[d] <= value && value <= upper_[d]); 00217 00218 //Kd_tree_rectangle* r = new Kd_tree_rectangle(*this); 00219 upper_[d]=value; 00220 r.lower_[d]=value; 00221 //return r; 00222 } 00223 00224 00225 ~Kd_tree_rectangle() 00226 { 00227 if (dim) { 00228 if (lower_) delete [] lower_; 00229 if (upper_) delete [] upper_; 00230 } 00231 } 00232 00233 int 00234 dimension() const 00235 { 00236 return dim; 00237 } 00238 00239 00240 Kd_tree_rectangle<SearchTraits>& 00241 operator=(const Kd_tree_rectangle<SearchTraits>& r) 00242 { 00243 CGAL_assertion(dimension() == r.dimension()); 00244 if (this != &r) { 00245 std::copy(r.lower_, r.lower_+dim, lower_); 00246 std::copy(r.upper_, r.upper_+dim, upper_); 00247 set_max_span(); 00248 } 00249 return *this; 00250 } 00251 00252 00253 00254 }; // of class Kd_tree_rectangle 00255 00256 template <class SearchTraits> 00257 std::ostream& 00258 operator<<(std::ostream& s, const Kd_tree_rectangle<SearchTraits>& r) 00259 { 00260 return r.print(s); 00261 } 00262 00263 00264 } // namespace CGAL 00265 00266 #endif // CGAL_KD_TREE_RECTANGLE_H