|
BWAPI
|
00001 // Copyright (c) 1999 Martin-Luther-University Halle-Wittenberg (Germany). 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/Point_set_2/include/CGAL/Point_set_2.h $ 00015 // $Id: Point_set_2.h 40729 2007-10-27 08:36:01Z spion $ 00016 // 00017 // 00018 // Author(s) : Matthias Baesken 00019 00020 #ifndef CGAL_POINT_SET_2_H 00021 #define CGAL_POINT_SET_2_H 00022 00023 #include <CGAL/basic.h> 00024 #include <CGAL/Unique_hash_map.h> 00025 #include <CGAL/Delaunay_triangulation_2.h> 00026 #include <CGAL/squared_distance_2_1.h> 00027 #include <CGAL/compare_vertices.h> 00028 #include <list> 00029 #include <queue> 00030 #include <map> 00031 #include <stack> 00032 #include <cmath> 00033 #include <climits> 00034 00035 CGAL_BEGIN_NAMESPACE 00036 00037 template<class Gt, class Tds = Triangulation_data_structure_2 <Triangulation_vertex_base_2<Gt> > > 00038 class Point_set_2 : public Delaunay_triangulation_2<Gt,Tds> 00039 { 00040 00041 public: 00042 typedef Gt Geom_traits; 00043 00044 typedef typename Geom_traits::Point_2 Point; 00045 typedef typename Geom_traits::Segment_2 Segment; 00046 00047 typedef typename Geom_traits::Circle_2 Circle; 00048 00049 typedef typename Geom_traits::Orientation_2 Orientation_2; 00050 typedef typename Geom_traits::Side_of_oriented_circle_2 Side_of_oriented_circle_2; 00051 typedef typename Geom_traits::Construct_circle_2 Construct_circle_2; 00052 typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance_2; 00053 typedef typename Geom_traits::FT Numb_type; // field number type ... 00054 00055 00056 typedef Triangulation_2<Gt,Tds> Triangulation; 00057 typedef typename Triangulation::Locate_type Locate_type; 00058 typedef typename Triangulation::Face_handle Face_handle; 00059 typedef typename Triangulation::Vertex_handle Vertex_handle; 00060 typedef typename Triangulation::Edge Edge; 00061 typedef typename Triangulation::Vertex Vertex; 00062 typedef typename Triangulation::Face Face; 00063 typedef typename Triangulation::Edge_circulator Edge_circulator; 00064 typedef typename Triangulation::Finite_edges_iterator Finite_edges_iterator; 00065 typedef typename Triangulation::Vertex_iterator Vertex_iterator; 00066 typedef typename Triangulation::Vertex_circulator Vertex_circulator; 00067 typedef typename Triangulation::Edge_iterator Edge_iterator; 00068 00069 typedef typename Geom_traits::Bounded_side_2 Circleptori; 00070 typedef typename Geom_traits::Compare_distance_2 Comparedist; 00071 typedef typename Geom_traits::Construct_center_2 Circlecenter; 00072 00073 typedef Unique_hash_map<Vertex_handle, Numb_type> MAP_TYPE; 00074 typedef Delaunay_triangulation_2<Gt,Tds> Base; 00075 00076 using Base::finite_vertices_begin; 00077 using Base::finite_vertices_end; 00078 using Base::number_of_vertices; 00079 using Base::VERTEX; 00080 using Base::insert; 00081 using Base::remove; 00082 00083 Comparedist tr_comparedist; 00084 Orientation_2 tr_orientation; 00085 Side_of_oriented_circle_2 tr_so_circle; 00086 Compute_squared_distance_2 tr_sqrdist; 00087 Circleptori tr_circleptori; 00088 Circlecenter tr_circlecenter; 00089 00090 //constructions... 00091 Construct_circle_2 tr_createcircle_3p; 00092 00093 Point_set_2() 00094 { 00095 init_vertex_marks(); 00096 } 00097 00098 template<class InputIterator> 00099 Point_set_2(InputIterator first, InputIterator last) 00100 { 00101 init_vertex_marks(); 00102 insert(first,last); 00103 } 00104 00105 ~Point_set_2() {} 00106 00107 template<class OutputIterator> 00108 OutputIterator vertices(OutputIterator res) 00109 // return vertex handles ... 00110 { 00111 Vertex_iterator vit = finite_vertices_begin(); 00112 for (; vit != finite_vertices_end(); vit++) { *res= vit; res++; } 00113 return res; 00114 } 00115 00116 00117 Vertex_handle lookup(Point p) const 00118 { 00119 if (number_of_vertices() == 0) return NULL; 00120 00121 // locate ... 00122 Locate_type lt; 00123 int li; 00124 Face_handle fh = locate(p,lt,li); 00125 00126 if (lt == VERTEX){ 00127 Face f = *fh; 00128 return f.vertex(li); 00129 } 00130 else return NULL; 00131 } 00132 00133 00134 Vertex_handle nearest_neighbor(Point p) 00135 { 00136 if (number_of_vertices() == 0) return NULL; 00137 return nearest_vertex(p); 00138 } 00139 00140 00141 Vertex_handle nearest_neighbor(Vertex_handle v) const 00142 { 00143 if (number_of_vertices() <= 1) return NULL; 00144 Point p = v->point(); 00145 00146 Vertex_circulator vc = incident_vertices(v); 00147 Vertex_circulator start =vc; 00148 00149 Vertex_handle min_v = vc; 00150 if (is_infinite(min_v)){ 00151 vc++; 00152 min_v = vc; 00153 } 00154 00155 Vertex_handle act; 00156 00157 // go through the vertices ... 00158 do { 00159 act = vc; 00160 00161 if (! is_infinite(act)) { 00162 if ( tr_comparedist(p,act->point(), min_v->point()) == SMALLER ) { 00163 min_v = act; 00164 } 00165 } 00166 00167 vc++; 00168 } while (vc != start); 00169 00170 return min_v; 00171 } 00172 00173 template<class OutputIterator> 00174 OutputIterator nearest_neighbors(Point p, int k, OutputIterator res) 00175 { 00176 int n = number_of_vertices(); 00177 00178 if ( k <= 0 ) return res; 00179 if ( n <= k ) { // return all finite vertices ... 00180 return vertices(res); 00181 } 00182 00183 // insert p, if nesessary 00184 00185 Vertex_handle vh = lookup(p); 00186 bool old_node = true; 00187 00188 // we have to add a new vertex ... 00189 if (vh == NULL){ 00190 vh = insert(p); 00191 old_node = false; 00192 k++; 00193 } 00194 00195 std::list<Vertex_handle> res_list; 00196 nearest_neighbors_list(vh, k, res_list); 00197 00198 if ( !old_node ) 00199 { 00200 res_list.pop_front(); 00201 remove(vh); 00202 } 00203 00204 typename std::list<Vertex_handle>::iterator it = res_list.begin(); 00205 00206 for (; it != res_list.end(); it++) { *res= *it; res++; } 00207 00208 return res; 00209 } 00210 00211 template<class OutputIterator> 00212 OutputIterator nearest_neighbors(Vertex_handle v, int k,OutputIterator res) 00213 { 00214 int n = number_of_vertices(); 00215 00216 if ( k <= 0 ) return res; 00217 if ( n <= k ) { // return all (finite) vertices ... 00218 return vertices(res); 00219 } 00220 00221 std::list<Vertex_handle> res_list; 00222 nearest_neighbors_list(v, k, res_list); 00223 00224 typename std::list<Vertex_handle>::iterator it = res_list.begin(); 00225 00226 for (; it != res_list.end(); it++) { *res= *it; res++; } 00227 00228 return res; 00229 } 00230 00231 00232 void nearest_neighbors_list(Vertex_handle v, 00233 int k, 00234 std::list<Vertex_handle>& res) 00235 { 00236 int n = number_of_vertices(); 00237 00238 if ( k <= 0 ) return; 00239 if ( n <= k ) { vertices(std::back_inserter(res)); return; } 00240 00241 Point p = v->point(); 00242 00243 // "unmark" the vertices ... 00244 init_dfs(); 00245 00246 MAP_TYPE priority_number; // here we save the priorities ... 00247 CGALi::compare_vertices<Vertex_handle,Numb_type,MAP_TYPE> 00248 comp(& priority_number); // comparison object ... 00249 std::priority_queue<Vertex_handle, std::vector<Vertex_handle>, CGALi::compare_vertices<Vertex_handle,Numb_type,MAP_TYPE> > PQ(comp); 00250 00251 priority_number[v] = 0; 00252 PQ.push(v); 00253 00254 mark_vertex(v); 00255 00256 while ( k > 0 ) 00257 { 00258 // find minimum from PQ ... 00259 Vertex_handle w = PQ.top(); 00260 PQ.pop(); 00261 00262 res.push_back(w); 00263 k--; 00264 00265 // get the incident vertices of w ... 00266 Vertex_circulator vc = incident_vertices(w); 00267 Vertex_circulator start =vc; 00268 Vertex_handle act; 00269 00270 do { 00271 act = vc; 00272 00273 if ( (!is_marked(act)) && (! is_infinite(act)) ) 00274 { 00275 priority_number[act] = tr_sqrdist(p,act->point()); 00276 PQ.push(act); 00277 mark_vertex(act); 00278 } 00279 00280 vc++; 00281 } while (vc != start); 00282 00283 } 00284 } 00285 00286 00287 // dfs 00288 // for marking nodes in search procedures 00289 int cur_mark; 00290 00291 Unique_hash_map<Vertex_handle, int> mark; 00292 00293 void init_vertex_marks() 00294 { 00295 cur_mark = 0; 00296 mark.clear(); 00297 } 00298 00299 void init_dfs() 00300 { 00301 cur_mark++; 00302 if (cur_mark == INT_MAX) init_vertex_marks(); 00303 } 00304 00305 void mark_vertex(Vertex_handle vh) 00306 // mark vh as visited ... 00307 { 00308 mark[vh] = cur_mark; 00309 } 00310 00311 bool is_marked(Vertex_handle vh) 00312 { 00313 if (! mark.is_defined(vh)) return false; 00314 00315 return (mark[vh] == cur_mark); 00316 } 00317 00318 void dfs(Vertex_handle v,const Circle& C, std::list<Vertex_handle>& L) 00319 { 00320 L.push_back(v); 00321 mark_vertex(v); 00322 00323 // get incident vertices of v ... 00324 Vertex_circulator vc = incident_vertices(v); 00325 Vertex_circulator start =vc; 00326 00327 Vertex_handle act; 00328 00329 // go through the vertices ... 00330 do { 00331 act = vc; 00332 00333 if (! is_infinite(act)) { 00334 if (!is_marked(act) && ! (tr_circleptori(C,act->point())==ON_UNBOUNDED_SIDE) ) 00335 dfs(act,C,L); 00336 } 00337 vc++; 00338 } while (vc != start); 00339 } 00340 00341 00342 template<class OutputIterator> 00343 OutputIterator range_search(const Circle& C, OutputIterator res) 00344 { 00345 if (number_of_vertices() == 0) return res; 00346 if (number_of_vertices() == 1) 00347 { 00348 // get the one vertex ... 00349 Vertex_iterator vit = finite_vertices_begin(); 00350 Point p = vit->point(); 00351 00352 if (! (tr_circleptori(C, p) == ON_UNBOUNDED_SIDE)){ 00353 *res= vit; res++; 00354 } 00355 return res; 00356 } 00357 00358 // normal case ... 00359 Point p = tr_circlecenter(C); 00360 Vertex_handle v = lookup(p); 00361 bool new_v = false; 00362 00363 if ( v == NULL ) 00364 { 00365 new_v = true; 00366 v = insert(p); 00367 } 00368 00369 init_dfs(); 00370 00371 std::list<Vertex_handle> L; 00372 dfs(v,C,L); 00373 00374 if (new_v) 00375 { L.pop_front(); //first one was inserted in range_search ... 00376 remove(v); 00377 } 00378 00379 typename std::list<Vertex_handle>::const_iterator iter = L.begin(); 00380 for(;iter != L.end() ;iter++){ *res= *iter; res++; } 00381 return res; 00382 } 00383 00384 00385 template<class OutputIterator> 00386 OutputIterator range_search(const Point& a, const Point& b, const Point& c,OutputIterator res) 00387 { int orient = (int)(tr_orientation(a,b,c)); 00388 Circle C = tr_createcircle_3p(a,b,c); 00389 std::list<Vertex_handle> L; 00390 range_search(C,std::back_inserter(L)); 00391 00392 typename std::list<Vertex_handle>::const_iterator it = L.begin(); 00393 00394 for(;it != L.end();it++) 00395 { Point p = (*it)->point(); 00396 if ( ((int)(tr_orientation(a,b,p))) == - orient || 00397 ((int)(tr_orientation(b,c,p))) == - orient || 00398 ((int)(tr_orientation(c,a,p))) == - orient ) { } 00399 else { *res = *it; res++; } 00400 } 00401 return res; 00402 } 00403 00404 00405 template<class OutputIterator> 00406 OutputIterator range_search(const Point& a1, const Point& b1, const Point& c1,const Point& 00407 d1,OutputIterator res) 00408 // a1 upper left, b1 lower left , c1 lower right 00409 { 00410 //Point b(c.xcoord(),a.ycoord()); 00411 //Point d(a.xcoord(),c.ycoord()); 00412 Point a=a1,b=b1,c=c1,d=d1; 00413 00414 if (tr_orientation(a,b,c) == RIGHT_TURN) 00415 { Point tmp = b; 00416 b = d; 00417 d = tmp; 00418 } 00419 00420 Circle C = tr_createcircle_3p(a,b,c); 00421 00422 std::list<Vertex_handle> L; 00423 range_search(C,std::back_inserter(L)); 00424 typename std::list<Vertex_handle>::const_iterator it = L.begin(); 00425 00426 for(;it != L.end();it++) 00427 { Point p = (*it)->point(); 00428 if ( tr_orientation(a,b,p) == RIGHT_TURN || tr_orientation(b,c,p) == RIGHT_TURN || 00429 tr_orientation(c,d,p) == RIGHT_TURN || tr_orientation(d,a,p) == RIGHT_TURN ) { } 00430 else { *res = *it; res++; } 00431 } 00432 return res; 00433 } 00434 00435 }; 00436 00437 00438 CGAL_END_NAMESPACE 00439 00440 00441 #endif 00442
1.7.6.1