BWAPI
|
00001 // Copyright (c) 2005 Tel-Aviv University (Israel). 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/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_lm_grid_generator.h $ 00015 // $Id: Arr_lm_grid_generator.h 41847 2008-01-26 09:05:42Z golubevs $ 00016 // 00017 // Author(s) : Idit Haran <haranidi@post.tau.ac.il> 00018 // Ron Wein <wein@post.tau.ac.il> 00019 #ifndef CGAL_ARR_LM_GRID_GENERATOR_H 00020 #define CGAL_ARR_LM_GRID_GENERATOR_H 00021 00026 #include <CGAL/Arr_point_location/Arr_lm_generator_base.h> 00027 00028 CGAL_BEGIN_NAMESPACE 00029 00034 template <class Arrangement_, 00035 class Nearest_neighbor_ = 00036 Arr_landmarks_nearest_neighbor<typename 00037 Arrangement_::Geometry_traits_2> > 00038 class Arr_grid_landmarks_generator : 00039 public Arr_landmarks_generator_base<Arrangement_, Nearest_neighbor_> 00040 { 00041 public: 00042 00043 typedef Arrangement_ Arrangement_2; 00044 typedef Nearest_neighbor_ Nearest_neighbor; 00045 00046 typedef Arr_landmarks_generator_base<Arrangement_2, 00047 Nearest_neighbor> Base; 00048 typedef Arr_grid_landmarks_generator<Arrangement_2, 00049 Nearest_neighbor> Self; 00050 00051 typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; 00052 typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator; 00053 typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; 00054 typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; 00055 typedef typename Arrangement_2::Face_const_handle Face_const_handle; 00056 typedef typename Arrangement_2::Vertex_handle Vertex_handle; 00057 typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; 00058 typedef typename Arrangement_2::Face_handle Face_handle; 00059 typedef typename Arrangement_2::Ccb_halfedge_circulator 00060 Ccb_halfedge_circulator; 00061 00062 typedef typename Geometry_traits_2::Approximate_number_type ANT; 00063 00064 typedef typename Arrangement_2::Point_2 Point_2; 00065 00066 protected: 00067 00068 typedef typename Base::Points_set Points_set; 00069 typedef std::pair<Point_2,CGAL::Object> PL_pair; 00070 typedef std::vector<PL_pair> Pairs_set; 00071 00072 typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2; 00073 00074 // Data members: 00075 const Traits_adaptor_2 *m_traits; 00076 unsigned int num_landmarks; 00077 Pairs_set lm_pairs; 00078 00079 ANT x_min, y_min; // Bounding box for the 00080 ANT x_max, y_max; // arrangement vertices. 00081 ANT step_x, step_y; // Grid step sizes. 00082 unsigned int sqrt_n; 00083 00084 bool fixed_number_of_lm; // indicates if the constructor got 00085 // number of landmarks as parameter 00086 00087 private: 00088 00090 Arr_grid_landmarks_generator (const Self& ); 00091 00093 Self& operator= (const Self& ); 00094 00095 00096 public: 00097 00100 Arr_grid_landmarks_generator (const Arrangement_2& arr) : 00101 Base (arr), 00102 num_landmarks (0), 00103 fixed_number_of_lm (false) 00104 { 00105 m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits()); 00106 build_landmark_set();//this-> 00107 } 00108 00109 Arr_grid_landmarks_generator (const Arrangement_2& arr, 00110 unsigned int n_landmarks) : 00111 Base (arr), 00112 num_landmarks (n_landmarks), 00113 fixed_number_of_lm (true) 00114 { 00115 m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits()); 00116 build_landmark_set();//this-> 00117 } 00118 00123 virtual void build_landmark_set () 00124 { 00125 // Create a set of points on a grid. 00126 Points_set points; 00127 _create_points_set(points); 00128 // Locate the landmarks in the arrangement using batched point-location 00129 // global function. Note that the resulting pairs are returned sorted by 00130 // their lexicographic xy-order. 00131 lm_pairs.clear(); 00132 locate (*(this->arrangement()), points.begin(), points.end(), 00133 std::back_inserter(lm_pairs)); 00134 this->updated = true; 00135 return; 00136 } 00137 00141 virtual void clear_landmark_set () 00142 { 00143 lm_pairs.clear(); 00144 this->updated = false; 00145 return; 00146 } 00147 00155 virtual Point_2 closest_landmark (const Point_2& q, Object &obj) 00156 { 00157 CGAL_assertion(this->updated); 00158 00159 // Calculate the index of the nearest grid point point to q. 00160 const ANT qx = m_traits->approximate_2_object()(q, 0); 00161 const ANT qy = m_traits->approximate_2_object()(q, 1); 00162 unsigned int i, j; 00163 unsigned int index; 00164 00165 if (CGAL::compare (qx, x_min) == SMALLER) 00166 i = 0; 00167 else if (CGAL::compare (qx, x_max) == LARGER) 00168 i = sqrt_n - 1; 00169 else 00170 i = static_cast<int>(((qx - x_min) / step_x) + 0.5); 00171 00172 if (CGAL::compare (qy, y_min) == SMALLER) 00173 j = 0; 00174 else if (CGAL::compare (qy, y_max) == LARGER) 00175 j = sqrt_n - 1; 00176 else 00177 j = static_cast<int>(((qy - y_min) / step_y) + 0.5); 00178 00179 index = sqrt_n * i + j; 00180 00181 // Return the result. 00182 obj = lm_pairs[index].second; 00183 return (lm_pairs[index].first); 00184 } 00185 00186 protected: 00187 00191 virtual void _create_points_set (Points_set & points) 00192 { 00193 Arrangement_2 *arr = this->arrangement(); 00194 00195 if(arr->is_empty()) 00196 return; 00197 00198 // Locate the arrangement vertices with minimal and maximal x and 00199 // y-coordinates. 00200 Vertex_const_iterator vit = arr->vertices_begin(); 00201 x_min = x_max = m_traits->approximate_2_object()(vit->point(), 0); 00202 y_min = y_max = m_traits->approximate_2_object()(vit->point(), 1); 00203 00204 if(arr->number_of_vertices() == 1) 00205 { 00206 // There is only one isolated vertex at the arrangement: 00207 step_x = step_y = 1; 00208 sqrt_n = 1; 00209 points.push_back (Point_2 (x_min, y_min)); 00210 return; 00211 } 00212 00213 ANT x, y; 00214 Vertex_const_iterator left, right, top, bottom; 00215 00216 left = right = top = bottom = vit; 00217 00218 for (++vit; vit != arr->vertices_end(); ++vit) 00219 { 00220 x = m_traits->approximate_2_object()(vit->point(), 0); 00221 y = m_traits->approximate_2_object()(vit->point(), 1); 00222 00223 if (CGAL::compare (x, x_min) == SMALLER) 00224 { 00225 x_min = x; 00226 left = vit; 00227 } 00228 else if (CGAL::compare (x, x_max) == LARGER) 00229 { 00230 x_max = x; 00231 right = vit; 00232 } 00233 00234 if (CGAL::compare (y, y_min) == SMALLER) 00235 { 00236 y_min = y; 00237 bottom = vit; 00238 } 00239 else if (CGAL::compare (y, y_max) == LARGER) 00240 { 00241 y_max = y; 00242 top = vit; 00243 } 00244 } 00245 00246 // Create N Halton points. If N was not given to the constructor, 00247 // set it to be the number of vertices V in the arrangement (actually 00248 // we generate ceiling(sqrt(V))^2 landmarks to obtain a square grid). 00249 if (!fixed_number_of_lm) 00250 num_landmarks = arr->number_of_vertices(); 00251 00252 sqrt_n = static_cast<unsigned int> 00253 (std::sqrt(static_cast<double> (num_landmarks)) + 0.99999); 00254 num_landmarks = sqrt_n * sqrt_n; 00255 00256 CGAL_assertion (sqrt_n > 1); 00257 00258 // Calculate the step sizes for the grid. 00259 ANT delta_x = m_traits->approximate_2_object()(right->point(), 0) - 00260 m_traits->approximate_2_object()(left->point(), 0); 00261 ANT delta_y = m_traits->approximate_2_object()(top->point(), 1) - 00262 m_traits->approximate_2_object()(bottom->point(), 1); 00263 00264 if (CGAL::sign (delta_x) == CGAL::ZERO) 00265 delta_x = delta_y; 00266 00267 if (CGAL::sign (delta_y) == CGAL::ZERO) 00268 delta_y = delta_x; 00269 00270 CGAL_assertion (CGAL::sign (delta_x) == CGAL::POSITIVE && 00271 CGAL::sign (delta_y) == CGAL::POSITIVE); 00272 00273 step_x = delta_x / (sqrt_n - 1); 00274 step_y = delta_y / (sqrt_n - 1); 00275 00276 // Create the points on the grid. 00277 const double x_min = 00278 CGAL::to_double (m_traits->approximate_2_object()(left->point(), 0)); 00279 const double y_min = 00280 CGAL::to_double (m_traits->approximate_2_object()(bottom->point(), 1)); 00281 const double sx = CGAL::to_double (step_x); 00282 const double sy = CGAL::to_double (step_y); 00283 double px, py; 00284 unsigned int i, j; 00285 00286 for (i = 0; i< sqrt_n; i++) 00287 { 00288 px = x_min + i*sx; 00289 00290 for (j = 0; j< sqrt_n; j++) 00291 { 00292 py = y_min + j*sy; 00293 00294 points.push_back (Point_2 (px, py)); 00295 00296 } 00297 } 00298 00299 return; 00300 } 00301 00302 }; 00303 00304 CGAL_END_NAMESPACE 00305 00306 #endif