BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/nearest_neighbor_delaunay_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/nearest_neighbor_delaunay_2.h $
00015 // $Id: nearest_neighbor_delaunay_2.h 29694 2006-03-22 16:11:11Z afabri $
00016 // 
00017 //
00018 // Author(s)     : Matthias Baesken
00019 
00020 #ifndef CGAL_NEAREST_NEIGHBOR_DELAUNAY_2_H
00021 #define CGAL_NEAREST_NEIGHBOR_DELAUNAY_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 
00034 CGAL_BEGIN_NAMESPACE
00035 
00036 
00037 
00038 template<class Dt>
00039 typename Dt::Vertex_handle  nearest_neighbor(const Dt& delau, typename Dt::Vertex_handle v)
00040 {
00041   typedef typename Dt::Geom_traits                    Gt;
00042   typedef typename Dt::Point                          Point;  
00043   typedef typename Dt::Vertex_circulator              Vertex_circulator;
00044   typedef typename Dt::Vertex_handle                  Vertex_handle;
00045   typedef typename Gt::Compare_distance_2             Compare_dist_2;
00046   
00047   if (delau.number_of_vertices() <= 1) return NULL;    
00048   Point p = v->point();
00049      
00050   Vertex_circulator vc = delau.incident_vertices(v);  
00051   Vertex_circulator start =vc;
00052      
00053   Vertex_handle min_v = vc;
00054   if (delau.is_infinite(min_v)){
00055      vc++;
00056      min_v = vc;
00057   }
00058      
00059   Vertex_handle act;
00060      
00061   // go through the vertices ...
00062   do {
00063        act = vc;
00064  
00065        if (! delau.is_infinite(act)) {
00066         if ( Compare_dist_2()(p,act->point(), min_v->point()) == SMALLER ) min_v = act;
00067        }   
00068            
00069        vc++;
00070   } while (vc != start);     
00071    
00072   return min_v;
00073 }
00074 
00075 
00076 template<class Dt>
00077 typename Dt::Vertex_handle lookup(const Dt& delau, const typename Dt::Point& p)
00078 { 
00079  typedef typename Dt::Face                      Face;
00080  typedef typename Dt::Locate_type               Locate_type;
00081  typedef typename Dt::Face_handle               Face_handle;
00082   
00083  if (delau.number_of_vertices() == 0) return NULL;   
00084      
00085  // locate ...
00086  Locate_type lt;
00087  int li;
00088  Face_handle fh = delau.locate(p,lt,li);
00089      
00090  if (lt == Dt::VERTEX){
00091       Face f = *fh;
00092       return f.vertex(li);
00093  }
00094  else return NULL;
00095 }   
00096    
00097    
00098 template<class Dt, class OutputIterator>
00099 OutputIterator   nearest_neighbors(Dt& delau, const typename Dt::Point& p, int k, OutputIterator res)
00100 {
00101   typedef typename Dt::Geom_traits                    Gt;
00102   typedef typename Dt::Vertex_handle                  Vertex_handle;
00103   typedef typename Dt::Vertex_iterator                Vertex_iterator;
00104 
00105    int n = delau.number_of_vertices();
00106 
00107    if ( k <= 0 ) return res;
00108    if ( n <= k ) { // return all finite vertices ...
00109    
00110      Vertex_iterator vit = delau.finite_vertices_begin();
00111      for (; vit != delau.finite_vertices_end(); vit++) { *res= vit; res++; }    
00112    
00113      return res;
00114    }
00115 
00116    // insert p, if necessary
00117    
00118    Vertex_handle vh = lookup(delau,p);
00119    bool old_node = true;
00120     
00121    // we have to add a new vertex ...
00122    if (vh == NULL){
00123       vh = delau.insert(p);
00124       old_node = false;
00125       k++;
00126    }
00127 
00128    std::list<Vertex_handle> res_list;
00129    nearest_neighbors_list(delau, vh, k, res_list);
00130    
00131    if ( !old_node ) 
00132    { 
00133      res_list.pop_front();
00134      delau.remove(vh);
00135    }
00136     
00137    typename std::list<Vertex_handle>::iterator it = res_list.begin();
00138     
00139    for (; it != res_list.end(); it++) { *res= *it; res++; }
00140    return res;  
00141 }
00142 
00143 
00144    
00145 template<class Dt, class OutputIterator>  
00146 OutputIterator  nearest_neighbors(const Dt& delau, typename Dt::Vertex_handle v, int k, OutputIterator res)
00147 {  
00148   typedef typename Dt::Geom_traits                    Gt;
00149   typedef typename Dt::Vertex_handle                  Vertex_handle;
00150   typedef typename Dt::Vertex_iterator                Vertex_iterator;
00151 
00152    int n = delau.number_of_vertices();
00153 
00154    if ( k <= 0 ) return res;
00155    if ( n <= k ) { // return all (finite) vertices ...
00156    
00157      Vertex_iterator vit = delau.finite_vertices_begin();
00158      for (; vit != delau.finite_vertices_end(); vit++) { *res= vit; res++; }    
00159    
00160      return res;
00161    }
00162    
00163    std::list<Vertex_handle> res_list;
00164    nearest_neighbors_list(delau, v, k, res_list); 
00165    
00166    typename std::list<Vertex_handle>::iterator it = res_list.begin();
00167     
00168    for (; it != res_list.end(); it++) { *res= *it; res++; }
00169 
00170    return res;     
00171 }
00172 
00173 
00174 template<class Dt, class OutputIterator>
00175 OutputIterator get_vertices(const Dt& delau, OutputIterator res)
00176 {    
00177   typedef typename Dt::Vertex_iterator                Vertex_iterator;
00178 
00179   Vertex_iterator vit = delau.finite_vertices_begin();
00180   for (; vit != delau.finite_vertices_end(); vit++) { *res= vit; res++; }  
00181   return res;   
00182 }
00183 
00184 
00185 // second template argument for VC ...
00186 
00187 template<class Dt, class T2>
00188 void nearest_neighbors_list(const Dt& delau, typename Dt::Vertex_handle v, int k, std::list<T2>& res) 
00189 {  
00190   typedef typename Dt::Geom_traits                    Gt;
00191   typedef typename Dt::Vertex_handle                  Vertex_handle;
00192   typedef typename Dt::Vertex_iterator                Vertex_iterator;
00193   typedef typename Dt::Vertex_circulator              Vertex_circulator;
00194   typedef typename Dt::Vertex                         Vertex;
00195   typedef typename Dt::Point                          Point;
00196   typedef typename Gt::FT                             Numb_type;  // field number type ...
00197   typedef typename Gt::Compute_squared_distance_2     Compute_squared_distance_2;   
00198   typedef Unique_hash_map<Vertex_handle, Numb_type>         MAP_TYPE;
00199 
00200   int n = delau.number_of_vertices();
00201    
00202   if ( k <= 0 ) return;
00203   if ( n <= k ) { 
00204       get_vertices(delau, std::back_inserter(res)); 
00205       return; 
00206   }
00207      
00208   Point p = v->point();
00209      
00210   Unique_hash_map<Vertex_handle, int>  mark;
00211   int cur_mark = 1;
00212 
00213   MAP_TYPE  priority_number; // here we save the priorities ...
00214   
00215   CGALi::compare_vertices<Vertex_handle,Numb_type,MAP_TYPE> comp(& priority_number);      // comparison object ...
00216   std::priority_queue<Vertex_handle, std::vector<Vertex_handle>, CGALi::compare_vertices<Vertex_handle,Numb_type,MAP_TYPE> > PQ(comp);
00217 
00218   priority_number[v] = 0;
00219   PQ.push(v);
00220      
00221   // mark vertex v
00222   mark[v] = cur_mark;
00223       
00224   while ( k > 0 )
00225   { 
00226     // find minimum from PQ ...
00227     Vertex_handle w = PQ.top(); 
00228     PQ.pop();
00229    
00230     res.push_back(w);
00231     k--; 
00232 
00233     // get the incident vertices of w ...
00234     Vertex_circulator vc = delau.incident_vertices(w);
00235     Vertex_circulator start =vc;
00236     Vertex_handle act;
00237      
00238     do {
00239          act = vc;
00240          
00241          // test, if act is marked ...
00242          bool is_marked = mark.is_defined(act);  
00243          
00244          if ( (! is_marked) && (! delau.is_infinite(act)) )
00245          { 
00246              priority_number[act] = Compute_squared_distance_2()(p,act->point());
00247              PQ.push(act);
00248              mark[act] = cur_mark;
00249          }         
00250                      
00251          vc++;
00252        } while (vc != start);   
00253         
00254    }
00255 } 
00256 
00257 
00258 CGAL_END_NAMESPACE
00259 
00260 #endif
00261 
00262 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines