BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_2/gen_point_location.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (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/Nef_2/include/CGAL/Nef_2/gen_point_location.h $
00015 // $Id: gen_point_location.h 41627 2008-01-14 23:06:54Z spion $
00016 // 
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
00019 
00020 
00021 #ifndef CGAL_NEF_2_GEN_POINT_LOCATION_H
00022 #define CGAL_NEF_2_GEN_POINT_LOCATION_H
00023 
00024 #include <CGAL/LEDA_basic.h>
00025 #if CGAL_LEDA_VERSION < 500
00026 #include <LEDA/pp_dictionary.h>
00027 #else
00028 #include <LEDA/core/pp_dictionary.h>
00029 #endif
00030 #include <sstream>
00031 #include <string>
00032 #include <list>
00033 #include <vector>
00034 #include <map>
00035 #include <CGAL/Nef_2/geninfo.h>
00036 
00037 #undef CGAL_NEF_DEBUG
00038 #define CGAL_NEF_DEBUG 17
00039 #include <CGAL/Nef_2/debug.h>
00040 
00041 // #define CHECKING_OFF
00042 
00043 // for dictionary
00044 template <class Node>
00045 inline std::ostream& operator<<(std::ostream& o, const std::list<Node>& n) 
00046 { return o; }
00047 
00048 /*{\Manpage {GenericLocation}{Node, Edge}
00049 {Return Type for Planar Point Location}{L}}*/
00050 
00051 template <class Node, class Edge>
00052 class GenericLocation {
00053 /*{\Mdefinition
00054   An instance of the data type |\Mtype| is used as return value for planar 
00055   point location. It can store a node or an edge of a graph or the special
00056   value |nil| which is used to signal that no node or edge could be found.
00057 }*/
00058   typedef void* GenPtr;
00059 public:
00060 /*{\Mtypes}*/ 
00061   enum Type { NIL, NODE, EDGE };
00062   /*{\Menum This enumeration allows to specify the 3 basic types of the 
00063      values that a |\Mtype| can represent.}*/
00064 
00065   /*{\Mcreation}*/ 
00066     GenericLocation()       { init(); }
00067     /*{\Mcreate creates a |\Mtype| and initializes with the value |nil|.}*/
00068     GenericLocation(Node n) { init(n); }
00069     /*{\Mcreate creates a |\Mtype| and initializes with the node |n|.}*/
00070     GenericLocation(Edge e) { init(e); }
00071     /*{\Mcreate creates a |\Mtype| and initializes with the edge |e|.}*/
00072 
00073     ~GenericLocation() { clear(); }
00074 
00075     GenericLocation(const GenericLocation<Node, Edge>& L) { assign(L); }
00076     GenericLocation<Node, Edge>& operator=(
00077       const GenericLocation<Node, Edge>& L)
00078     { clear(); assign(L); return *this; }
00079 
00080   /*{\Moperations}*/
00081     operator const Node&() const
00082     {
00083   #if !defined(CHECKING_OFF)
00084       if (type != NODE) 
00085         CGAL_LEDA_SCOPE::error_handler(1, "Location: not convertible to node");
00086   #endif
00087       return geninfo<Node>::const_access(value);
00088     }
00089     /*{\Mconversion converts |\Mvar| into a node.\\
00090        \precond |\Mvar| represents a node.}*/
00091 
00092     operator const Edge&() const
00093     { 
00094   #if !defined(CHECKING_OFF)
00095       if (type != EDGE) 
00096         CGAL_LEDA_SCOPE::error_handler(1, "Location: not convertible to edge");
00097   #endif
00098       return geninfo<Edge>::const_access(value);
00099     }
00100     /*{\Mconversion converts |\Mvar| into an edge.\\
00101        \precond |\Mvar| represents an edge.}*/
00102 
00103     GenericLocation<Node, Edge>& operator=(Node n)
00104     { clear(); init(n); return *this; }
00105     /*{\Mbinop makes |\Mvar| represent the node |n|.}*/
00106 
00107     GenericLocation<Node, Edge>& operator=(Edge e)
00108     { clear(); init(e); return *this; }
00109     /*{\Mbinop makes |\Mvar| represent the edge |e|.}*/
00110 
00111     Type get_type() const { return type; }
00112     /*{\Mop returns the type of the value contained in |\Mvar|.}*/
00113 
00114     bool is_nil()  const { return type == NIL; }
00115     /*{\Mop returns |true| iff |\Mvar| represents the value |nil|.}*/
00116 
00117     bool is_node() const { return type == NODE; }
00118     /*{\Mop returns |true| iff |\Mvar| represents a node.}*/
00119 
00120     bool is_edge() const { return type == EDGE; }
00121     /*{\Mop returns |true| iff |\Mvar| represents an edge.}*/
00122 
00123   private:
00124     void init() { type = NIL; }
00125     void init(Node n) 
00126     { type = NODE; 
00127       geninfo<Node>::create(value); 
00128       geninfo<Node>::access(value) = n; 
00129     }
00130     void init(Edge e) 
00131     { type = EDGE; 
00132       geninfo<Edge>::create(value); 
00133       geninfo<Edge>::access(value) = e; 
00134     }
00135 
00136     void clear()
00137     { 
00138       switch(type) {
00139        case NODE: geninfo<Node>::clear(value); break;
00140        case EDGE: geninfo<Edge>::clear(value); break;
00141        case NIL: break;
00142       }
00143     }
00144 
00145     void assign(const GenericLocation<Node, Edge>& L)
00146     { 
00147       type = L.type;
00148       switch(type) {
00149        case NODE: 
00150          geninfo<Node>::access(value) = geninfo<Node>::const_access(L.value); 
00151          break;
00152        case EDGE: 
00153          geninfo<Edge>::access(value) = geninfo<Edge>::const_access(L.value);
00154          break;
00155        case NIL: break;
00156       }
00157     }
00158 
00159   public:
00160     typedef GenericLocation<Node, Edge> self;
00161 
00162 
00163 private:
00164   Type   type;
00165   GenPtr value;
00166 };
00167 
00168 /*{\Mimplementation
00169   The data type |\Mtype| is implemented as a union of the types |Node| and 
00170   |Edge|. There is only constant time and space overhead.
00171 }*/
00172 template <class Node, class Edge>
00173 inline
00174 bool 
00175 operator==(const GenericLocation<Node, Edge>& L1, 
00176            const GenericLocation<Node, Edge>& L2)
00177 { 
00178   if (L1.get_type() != L2.get_type()) return false;
00179   switch (L1.get_type()) {
00180    case GenericLocation<Node, Edge>::NIL:  return true;
00181    case GenericLocation<Node, Edge>::NODE: return Node(L1) == Node(L2);
00182    case GenericLocation<Node, Edge>::EDGE: return Edge(L1) == Edge(L2);
00183   }
00184 }
00185 
00186 template <class Node, class Edge>
00187 inline
00188 bool 
00189 operator!=(const GenericLocation<Node, Edge>& L1, 
00190            const GenericLocation<Node, Edge>& L2)
00191 { return ! (L1==L2); }
00192 
00193 template <class Node, class Edge>
00194 std::ostream& operator<<(std::ostream& o, 
00195                          const GenericLocation<Node, Edge>& L)
00196 {
00197   switch (L.get_type()) {
00198    case GenericLocation<Node, Edge>::NIL:  return o<<"nil";
00199    case GenericLocation<Node, Edge>::NODE: return o<<"node("<<&*Node(L)<<')';
00200    case GenericLocation<Node, Edge>::EDGE: return o<<"edge("<<&*Edge(L)<<')';
00201   }
00202   return o;
00203 }
00204 
00205 template <class Node, class Edge>
00206 std::istream& operator>>(std::istream& i, GenericLocation<Node, Edge>&)
00207 { return i; }
00208 template <class XCoord, class PredLessThanX, class Sweepline>
00209 class GenericXStructure {
00210 public:
00211   typedef std::vector<XCoord>    Array_Coordinates;
00212   typedef std::vector<Sweepline> Array_Sweeplines;
00213   typedef typename Array_Coordinates::const_iterator Coord_iterator;
00214   typedef typename Array_Sweeplines::const_iterator  Sweepline_iterator;
00215 private:
00216   int stops;
00217   PredLessThanX     LtX;
00218   Array_Coordinates Coordinates;
00219   Array_Sweeplines  SweepLines;
00220   // SweepLines[0] is EmptyLine;
00221 public:
00222   GenericXStructure() { clear(); }
00223   GenericXStructure(int n, const PredLessThanX& cmp) { init(n, cmp); }
00224   ~GenericXStructure() { clear(); }
00225 
00226   void init(int n, const PredLessThanX& cmp)
00227   { CGAL_NEF_TRACEN("XSinit "<<n); 
00228     LtX = cmp;
00229     Coordinates = Array_Coordinates(n);
00230     SweepLines =  Array_Sweeplines(2*n+1);
00231     stops = 0;
00232   }
00233 
00234   void clear()
00235   { Coordinates.clear();
00236     SweepLines.clear();
00237     stops = 0;
00238   }
00239 
00240   void insertLines(const XCoord& X, 
00241                    const Sweepline& atX, const Sweepline& inXplus)
00242   { CGAL_NEF_TRACEN("XSinsert "<<X); 
00243     Coordinates[stops]    = X;
00244     SweepLines[2*stops+1]   = atX;
00245     SweepLines[2*stops+2] = inXplus;
00246     ++stops;
00247   }
00248 
00249   Sweepline_iterator getLineAt(const XCoord& X) const
00250   { CGAL_NEF_TRACEN("XSgetLineAt "<<X);
00251     Sweepline_iterator sit = SweepLines.begin(); // EmptyLine
00252     if ( LtX(X,*Coordinates.begin()) ) {
00253       CGAL_NEF_TRACEN("infinity first");
00254       return sit; // ]-infinity, x0[
00255     }
00256     Coord_iterator stopit = std::lower_bound (
00257         Coordinates.begin(),Coordinates.end(),X,LtX);
00258     /* determines stopit maximal such that 
00259        \forall j \in [begin,stopit) : *j < X
00260        as a consequence now: *stopit >= X */
00261     bool found_exact = false;
00262     if ( LtX(X,*stopit) ) --stopit;  // X <  *stopit
00263     else found_exact = true;         // X >= *stopit
00264       
00265     CGAL_NEF_TRACEN("stopit "<<*stopit);
00266     int offset = stopit-Coordinates.begin();
00267     return found_exact ? 
00268       SweepLines.begin() + (2*offset+1) :
00269       SweepLines.begin() + (2*offset+2);
00270   }
00271 
00272   Sweepline_iterator begin() const { return SweepLines.begin(); }
00273   Sweepline_iterator end() const { return SweepLines.end();}
00274 
00275 };
00276 /*{\Manpage {PointLocator} {PLocTraits} {Planar Point Location} {PL}}*/
00277 
00278 template <class PLocTraits>
00279 class PointLocator {
00280 /*{\Mdefinition
00281    An instance |\Mvar| of the parameterized data type |\Mtype| can be used
00282    to perform point location queries in the two-dimensional plane.
00283    Every non-empty instance |\Mvar| is associated with an embedded planar 
00284    graph |G|, which has to remain unchanged while it is referenced by |PL|.\\
00285    A location query for a point |p| returns the first object (node or edge)
00286    of |G| which is intersected by the straight ray starting in |p| and going
00287    vertically downwards/upwards.
00288    If the ray does not intersect any node or edge of |G|, then |nil| is 
00289    returned.\\
00290    The class |\Mtype| is generic, it is parameterized with a traits class 
00291    |PLocTraits| which widely controls its behaviour.
00292    The traits may even change the return type of a query and its semantics.
00293    There are predined traits classes for the LEDA graph types, which are
00294    described below in a seperate section.
00295 }*/
00296 public:
00297   // copied types from PLocTraits
00298   typedef typename PLocTraits::Point             Point;
00299   typedef typename PLocTraits::XCoord            XCoord;
00300   typedef typename PLocTraits::PredLessThanX     PredLessThanX;
00301 
00302   typedef typename PLocTraits::Graph             Graph;
00303   typedef typename PLocTraits::Node              Node;
00304   typedef typename PLocTraits::Edge              Edge;
00305   typedef typename PLocTraits::NodeIterator      NodeIterator;
00306   typedef typename PLocTraits::IncEdgeIterator   IncEdgeIterator;
00307 
00308   typedef typename PLocTraits::Curve             Curve;
00309   typedef typename PLocTraits::PredCompareCurves PredCompareCurves;
00310 
00311   typedef typename PLocTraits::QueryResult       QueryResult;
00312 
00313 /*{\Mtypes}*/
00314   // define additional types 
00315   typedef GenericLocation<Node, Edge> Location;
00316   /*{\Mtypedef usual return value for the point loaction.}*/
00317 
00318   enum Direction { downwards, upwards};
00319   /*{\Menum used to specify the direction for the point location.}*/
00320 
00321   typedef CGAL_LEDA_SCOPE::pp_dictionary<Curve, Location, PredCompareCurves>   
00322                                                               Sweepline;
00323   typedef GenericXStructure<XCoord, PredLessThanX, Sweepline> XStructure;
00324   typedef typename Sweepline::item                            SL_item;
00325   typedef typename XStructure::Sweepline_iterator Sweepline_iterator;
00326   /*{\Mcreation}*/ 
00327   PointLocator() { clear(); }
00328   /*{\Mcreate creates an empty |\Mtype|.}*/
00329 
00330   PointLocator(const Graph& G, const PLocTraits& PLT = PLocTraits()) : 
00331    traits(PLT) { init(G); }
00332   /*{\Mcreate creates a |\Mtype| for the graph |G| and the traits |PLT|.}*/
00333      
00334   /*{\Moperations}*/
00335   void clear() { X_Structure.clear(); traits.clear(); }
00336   /*{\Mop makes |\Mvar| empty.}*/
00337 
00338 
00339   void init(const Graph& G, const PLocTraits& PLT) { traits = PLT; init(G); }
00340   /*{\Mop makes |\Mvar| a |\Mtype| for the graph |G| and the traits |PLT|.}*/
00341 
00342   void init(const Graph& G);
00343   /*{\Mop makes |\Mvar| a |\Mtype| for the graph |G|.}*/
00344 
00345 
00346   QueryResult locate(const Point& p, const Direction dir) const
00347   { return dir == downwards ? locate_down(p) : locate_up(p); }
00348   /*{\Mop locates the point |p| in the direction |dir|.}*/
00349 
00350   QueryResult locate_down(const Point& p) const;
00351   /*{\Mop locates the point |p| vertically downwards.}*/
00352 
00353   QueryResult locate_up(const Point& p) const;
00354   /*{\Mop locates the point |p| vertically upwards.}*/
00355 
00356   Location location(Sweepline_iterator S, SL_item it) const
00357   { return (it == nil ? Location() : S->inf(it)); }
00358 
00359   std::string str(const Sweepline& S) const
00360   { std::ostringstream os; os << "Sweepline:\n";
00361     SL_item it;
00362     forall_items(it,S) {  os << "  " << S.key(it) << std::endl; }
00363     return os.str();
00364   }
00365 
00366 
00367 private:
00368   PLocTraits traits;
00369   XStructure X_Structure;
00370 
00371 };
00372 
00373 template <class PLocTraits>
00374 void
00375 PointLocator<PLocTraits>::init(const Graph& G)
00376 {
00377   traits.sweep_begin(G);
00378   PredLessThanX LtX = traits.getLessThanX();
00379   typedef std::map<XCoord, std::list<Node>, PredLessThanX> dictionary;
00380   typedef typename dictionary::iterator dic_iterator;
00381   dictionary stops(LtX);
00382   // Note: X_Structure, Sweepline, and stops copy compare object
00383 
00384   NodeIterator ni = traits.Nodes_begin(G), beyond = traits.Nodes_end(G);
00385   for(; ni != beyond; ++ni) {
00386     XCoord currentX = traits.getXCoord(G, ni);
00387     stops[currentX].push_front(traits.toNode(ni));
00388   }
00389 
00390   Sweepline SL(traits.getCompareCurves());
00391   X_Structure.init(stops.size(), LtX);
00392   dic_iterator stop;
00393   for(stop = stops.begin(); stop != stops.end(); ++stop) {
00394     std::list<Node>& NodesOnSL = stop->second;
00395     traits.sweep_moveto(traits.getXCoord(G, *NodesOnSL.begin()));
00396       std::list<Edge> EmergingEdges, VerticalEdges;
00397 
00398       // explore the nodes on SL
00399       typename std::list<Node>::iterator cur_node;
00400       for(cur_node = NodesOnSL.begin(); 
00401           cur_node != NodesOnSL.end(); ++cur_node) {
00402         IncEdgeIterator ei     = traits.IncEdges_begin(G, *cur_node);
00403         IncEdgeIterator beyond = traits.IncEdges_end(G, *cur_node);
00404           CGAL_NEF_TRACEN("NODE: "<<(*cur_node)->point());
00405         for(; ei != beyond; ++ei) { 
00406           switch (traits.ClassifyEdge(G, traits.toEdge(ei), *cur_node)) {
00407             case PLocTraits::StartingNonVertical: 
00408               EmergingEdges.push_front(traits.toEdge(ei)); break;
00409             case PLocTraits::StartingVertical:    
00410               VerticalEdges.push_front(traits.toEdge(ei)); break;
00411             case PLocTraits::EndingNonVertical:
00412               SL.del(traits.makeCurve(G, traits.toEdge(ei))); break;
00413             case PLocTraits::EndingVertical: break;
00414           }
00415         }
00416       }
00417 
00418       // compute SL_at_X
00419 
00420       typename std::list<Edge>::iterator cur_edge;
00421       for(cur_edge=VerticalEdges.begin(); 
00422           cur_edge!=VerticalEdges.end(); ++cur_edge) 
00423         SL.insert(traits.makeCurve(G, *cur_edge), Location(*cur_edge));
00424       for(cur_node=NodesOnSL.begin();
00425           cur_node!=NodesOnSL.end(); ++cur_node)
00426         SL.insert(traits.makeCurve(G, *cur_node), Location(*cur_node));
00427       Sweepline SL_at_X = SL;
00428 
00429       // compute SL_in_X_plus
00430 
00431       for(cur_edge=VerticalEdges.begin(); 
00432           cur_edge!=VerticalEdges.end(); ++cur_edge)
00433         SL.del(traits.makeCurve(G, *cur_edge));
00434       for(cur_node=NodesOnSL.begin();
00435           cur_node!=NodesOnSL.end(); ++cur_node)
00436         SL.del(traits.makeCurve(G, *cur_node));
00437 
00438       for(cur_edge=EmergingEdges.begin();
00439           cur_edge!=EmergingEdges.end(); ++cur_edge) 
00440         SL.insert(traits.makeCurve(G, *cur_edge), Location(*cur_edge));
00441 
00442     X_Structure.insertLines(traits.getXCoord(G, *NodesOnSL.begin()), 
00443                             SL_at_X, SL);
00444   }
00445 
00446   traits.sweep_end();
00447 }
00448 
00449 template <class PLocTraits>
00450 typename PointLocator<PLocTraits>::QueryResult
00451 PointLocator<PLocTraits>::
00452 locate_down(const typename PLocTraits::Point& p) const
00453 {
00454   Sweepline_iterator line_at_x = X_Structure.getLineAt(traits.getXCoord(p)),
00455                      line_plus = line_at_x;
00456   CGAL_NEF_TRACEN("locate_down "<<str(*line_at_x));
00457   Curve p_curve = traits.makeCurve(p);
00458   PredCompareCurves cmp = traits.getCompareCurves();
00459   SL_item it = line_at_x->locate_pred(p_curve), it_plus(0);
00460   if ( it && line_at_x->inf(it).is_node() &&
00461        cmp(p_curve, line_at_x->key(it))!=0 ) {
00462     // p hit a feature exactly
00463     line_plus = line_at_x+1;
00464     if ( line_plus != X_Structure.end() )
00465       it_plus = line_plus->locate_pred(p_curve);
00466   }
00467   return traits.PostProcess(location(line_at_x,it),
00468                             location(line_plus,it_plus),p);
00469 }
00470 
00471 template <class PLocTraits>
00472 typename PointLocator<PLocTraits>::QueryResult
00473 PointLocator<PLocTraits>::locate_up(const typename PLocTraits::Point& p) const
00474 {
00475   Sweepline_iterator line_at_x = 
00476     X_Structure.getLineAt(traits.getXCoord(p)), line_plus;
00477   Curve p_curve = traits.makeCurve(p);
00478   PredCompareCurves cmp = traits.getCompareCurves();
00479   SL_item it = line_at_x->locate_succ(p_curve), it_plus(0);
00480   if ( it && line_at_x->inf(it).is_node() &&
00481        cmp(p_curve, line_at_x->key(it))!=0 ) {
00482     // p hit a feature exactly
00483     line_plus = line_at_x+1;
00484     if ( line_plus != X_Structure.end() )
00485       it_plus = line_plus->locate_succ(p_curve);
00486   }
00487   return traits.PostProcess(location(line_at_x,it),
00488                             location(line_plus,it_plus), p);
00489 }
00490 
00491 /*{\Mimplementation
00492   The implementation of the data type |\Mtype| is based on partially 
00493   persistent binary search trees.
00494   The expected space requirement is $O(k)$ where $k$ is the sum of the number 
00495   of nodes and the number of edges in the graph $G$.
00496   The expected time needed for construction and the operation |init| is 
00497   $O(k \cdot \log k)$, for the |locate|-operations it is $O(\log k)$. The
00498   operation |clear| runs in $O(k)$.
00499 }*/
00500 /*{\Mtext
00501   \headerline{\arabic{manctr}. Predefined traits classes}
00502   \stepcounter{manctr}
00503   All predefined traits classes have in common that the return type of a query 
00504   is the type |Location|.
00505   The embedding of the given graph |G| is a straight-line embedding, so that
00506   it is totally determined by the position of the nodes of |G|.
00507   Such a position is specified by a |Point| which can be one of the LEDA point
00508   types |point| or |rat_point|. The positions can be specified implicitly by 
00509   the node attribute of a parameterized graph (e.g. |GRAPH<Point,...>|) or 
00510   explicitly by a |node_array<Point>|. In case of explicit specification a
00511   |node_array| with the positions of the nodes can be passed to the constructor
00512   of the traits class.
00513   Further, the point location processes for maps and for standard graphs differ
00514   slightly. As a map is a bidirected graph where each edge knows its reversal,
00515   the traits classes for maps can ensure the following property:
00516   If the result of a query for point |p| is an edge |e| (not containing |p|),
00517   then |e| bounds the face of |G| which contains |p|, i.e. |p| lies to the
00518   left of |e|.\\
00519   Here comes a list of the predefined traits classes:\\[-5.5ex]
00520   \begin{itemize}
00521   \item |PLocTraits<Graph>|: standard traits for implicitly specified node 
00522     positions\\
00523     |Graph| can be |GRAPH<Point,...>| (standard graph) or 
00524     |PLANAR_MAP<Point,...,...>| (map).
00525   \item |PLocTraits_NodeArray<Graph,Point>|: std. traits for explicitly 
00526     specified node positions\\
00527     |Graph| can be |graph| (standard graph) or |planar_map| (map).
00528   \item |PLocTraits_Map<Graph>| and |PLocTraits_Map_NodeArray<Graph,Point>|:\\
00529     The parameter |Graph| can be |GRAPH<Point,...>| and |graph| respectively.
00530     These traits classes assume that the given graphs are maps.
00531   \item |PLocTraits< GRAPH<Circle,Point> >|: traits class for closest-site 
00532     voronoi diagrams
00533   \end{itemize}
00534   Note that a traits class instantiated with |Graph| can also handle graph 
00535   types which are derived from |Graph|. Thus |PLocTraits< graph<Point,T> >| 
00536   can be used for graphs of type |ugraph<Point,T>| for example.
00537 }*/
00538 /*{\Mexample
00539 First we show an example where the node positions are given implicitly
00540 as node attributes:
00541 \begin{verbatim}
00542   typedef PointLocator< PLocTraits< GRAPH<Point, int> > > PLocator1;
00543   typedef PLocator1::Location Location;
00544 
00545   UGRAPH<Point, int> G;
00546   ... // construct G
00547 
00548   PLocator1 PL1(G);
00549   Point p = ...; // compute p
00550   Location L1 = PL1.locate_down(p);
00551 \end{verbatim}
00552 
00553 The second example shows how a |node_array| can be used to determine the
00554 node positions:
00555 \begin{verbatim}
00556   typedef PLocTraits_NodeArray<planar_map,Point> PLocTraits2;
00557   typedef PointLocator<PLocTraits2> PLocator2;
00558 
00559   planar_map pm;
00560   node_array<Point> na;
00561   ... // construct pm and na
00562 
00563   PLocator2 PL2(pm, PLocTraits2(na));
00564   Point q = ...; // compute q
00565   Location L2 = PL2.locate_up(q);
00566 \end{verbatim}
00567 }*/
00568 
00569 #endif // GEN_POINT_LOCATION_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines