BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Point_set_2.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines