BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_2/PM_point_locator.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/PM_point_locator.h $
00015 // $Id: PM_point_locator.h 45448 2008-09-09 16:03:25Z spion $
00016 //
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
00019 #ifndef CGAL_PM_POINT_LOCATOR_H
00020 #define CGAL_PM_POINT_LOCATOR_H
00021 
00022 #include <CGAL/basic.h>
00023 #include <CGAL/Unique_hash_map.h>
00024 #include <CGAL/Nef_2/Constrained_triang_traits.h>
00025 #include <CGAL/Nef_2/Object_handle.h>
00026 #include <CGAL/Circulator_project.h>
00027 #include <CGAL/Polygon_2_algorithms.h>
00028 #undef CGAL_NEF_DEBUG
00029 #define CGAL_NEF_DEBUG 17
00030 #include <CGAL/Nef_2/debug.h>
00031 #include <CGAL/Nef_2/geninfo.h>
00032 
00033 #ifdef CGAL_USE_LEDA
00034 #include <CGAL/LEDA_basic.h>
00035 # if __LEDA__ > 410 && __LEDA__ < 441
00036 #  define CGAL_USING_PPL
00037 #  include <CGAL/Nef_2/PM_persistent_PL.h>
00038 # endif
00039 #endif
00040 
00041 CGAL_BEGIN_NAMESPACE
00042 
00043 enum object_kind { VERTEX, EDGE_CROSSING, EDGE_COLLINEAR };
00044 
00045 template < class Node, class Object>
00046 struct Project_halfedge_point {
00047   typedef Node         argument_type;
00048   typedef Object       result_type;
00049   Object& operator()( Node& x) const   {
00050     return x.vertex()->point();
00051   }
00052   const Object& operator()( const Node& x) const   {
00053     return x.vertex()->point();
00054   }
00055 };
00056 
00057 /*{\Moptions print_title=yes }*/
00058 /*{\Msubst
00059 PM_decorator_#PMD
00060 Geometry_#GEO
00061 }*/
00062 /*{\Manpage {PM_naive_point_locator}{PMD,GEO}
00063 {Naive point location in plane maps}{PL}}*/
00064 /*{\Mdefinition An instance |\Mvar| of data type |\Mname|
00065 encapsulates naive point location queries within a plane map |P|.  The
00066 two template parameters are specified via concepts. |PM_decorator_|
00067 must be a model of the concept |PMDecorator| as described in the
00068 appendix.  |Geometry_| must be a model of the concept
00069 |AffineGeometryTraits_2| as described in the appendix. For a
00070 specification of plane maps see also the concept of
00071 |PMConstDecorator|.}*/
00072 
00073 /*{\Mgeneralization PMD}*/
00074 
00075 template <typename PM_decorator_, typename Geometry_>
00076 class PM_naive_point_locator : public PM_decorator_ {
00077 protected:
00078   typedef PM_decorator_ Base;
00079   typedef PM_naive_point_locator<PM_decorator_,Geometry_> Self;
00080 
00081   const Geometry_& K;
00082 public:
00083   /*{\Mtypes 5}*/
00084   typedef PM_decorator_                 Decorator;
00085   /*{\Mtypemember equals |PM_decorator_|.}*/
00086   typedef typename Decorator::Plane_map Plane_map;
00087   /*{\Mtypemember the plane map type decorated by |Decorator|.}*/
00088   typedef typename Decorator::Mark      Mark;
00089   /*{\Mtypemember the attribute of all objects (vertices, edges,
00090   faces).}*/
00091 
00092   typedef Geometry_                       Geometry;
00093   /*{\Mtypemember equals |Geometry_|.}*/
00094   typedef typename Geometry_::Point_2     Point;
00095   /*{\Mtypemember the point type of the geometry kernel.\\
00096   \require |Geometry::Point_2| equals |Plane_map::Point|.}*/
00097   typedef typename Geometry_::Segment_2   Segment;
00098   /*{\Mtypemember the segment type of the geometry kernel.}*/
00099   typedef typename Geometry_::Direction_2 Direction;
00100 
00101   /*{\Mtext Local types are handles, iterators and circulators of the
00102   following kind: |Vertex_const_handle|, |Vertex_const_iterator|,
00103   |Halfedge_const_handle|, |Halfedge_const_iterator|, |Face_const_handle|,
00104   |Face_const_iterator|.}*/
00105 
00106   typedef CGAL::Object_handle Object_handle;
00107   /*{\Mtypemember a generic handle to an object of the underlying plane
00108   map. The kind of the object |(vertex, halfedge,face)| can be determined and
00109   the object assigned by the three functions:\\
00110   |bool assign(Vertex_const_handle& h, Object_handle o)|\\
00111   |bool assign(Halfedge_const_handle& h, Object_handle o)|\\
00112   |bool assign(Face_const_handle& h, Object_handle o)|\\ where each
00113   function returns |true| iff the assignment of |o| to |h| was valid.}*/
00114 
00115    typedef typename PM_decorator_::Vertex_handle Vertex_handle;
00116    typedef typename PM_decorator_::Halfedge_handle Halfedge_handle;
00117    typedef typename PM_decorator_::Face_handle Face_handle;
00118    typedef typename PM_decorator_::Vertex_const_handle Vertex_const_handle;
00119    typedef typename PM_decorator_::Halfedge_const_handle Halfedge_const_handle;
00120    typedef typename PM_decorator_::Face_const_handle Face_const_handle;
00121    typedef typename PM_decorator_::Vertex_iterator Vertex_iterator;
00122    typedef typename PM_decorator_::Halfedge_iterator Halfedge_iterator;
00123    typedef typename PM_decorator_::Face_iterator Face_iterator;
00124    typedef typename PM_decorator_::Vertex_const_iterator Vertex_const_iterator;
00125    typedef typename PM_decorator_::Halfedge_const_iterator Halfedge_const_iterator;
00126    typedef typename PM_decorator_::Face_const_iterator Face_const_iterator;
00127    typedef typename PM_decorator_::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
00128    typedef typename PM_decorator_::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator;
00129    typedef typename PM_decorator_::Halfedge_around_face_circulator Halfedge_around_face_circulator;
00130    typedef typename PM_decorator_::Halfedge_around_face_const_circulator Halfedge_around_face_const_circulator;
00131 
00132   using Base::clear;
00133   using Base::vertices_begin;
00134   using Base::vertices_end;
00135   using Base::halfedges_begin;
00136   using Base::halfedges_end;
00137   using Base::faces_begin;
00138   using Base::faces_end;
00139   using Base::number_of_vertices;
00140   using Base::number_of_halfedges;
00141   using Base::number_of_faces;
00142 
00143   Halfedge_const_handle out_wedge(Vertex_const_handle v,
00144     const Direction& d, bool& collinear) const
00145   /*{\Xop returns a halfedge |e| bounding a wedge in between two
00146   neighbored edges in the adjacency list of |v| which contains |d|.
00147   If |d| extends along a edge then |e| is this edge. If |d| extends
00148   into the interior of such a wedge then |e| is the first edge hit
00149   when |d| is rotated clockwise. \precond |v| is not isolated.}*/
00150   { CGAL_NEF_TRACEN("out_wedge "<<PV(v));
00151     CGAL_assertion(!is_isolated(v));
00152     collinear=false;
00153     Point p = point(v);
00154     Halfedge_const_handle e_res = first_out_edge(v);
00155     Direction d_res = direction(e_res);
00156     Halfedge_around_vertex_const_circulator el(e_res),ee(el);
00157     CGAL_For_all(el,ee) {
00158       if ( K.strictly_ordered_ccw(d_res, direction(el), d) )
00159         e_res = el; d_res = direction(e_res);
00160     }
00161     CGAL_NEF_TRACEN("  determined "<<PE(e_res)<<" "<<d_res);
00162     if ( direction(cyclic_adj_succ(e_res)) == d ) {
00163       e_res = cyclic_adj_succ(e_res);
00164       collinear=true;
00165     }
00166     CGAL_NEF_TRACEN("  wedge = "<<PE(e_res)<<" "<<collinear);
00167     return e_res;
00168   }
00169 
00170   Segment segment(Halfedge_const_handle e) const
00171   { return K.construct_segment(point(source(e)), point(target(e))); }
00172 
00173   Direction direction(Halfedge_const_handle e) const
00174   { return K.construct_direction(point(source(e)),point(target(e))); }
00175 
00176   /*{\Mcreation 3}*/
00177 
00178   PM_naive_point_locator() : Base() {}
00179 
00180   /*{\Moptions constref=yes}*/
00181   PM_naive_point_locator(const Plane_map& P, const Geometry& k = Geometry()) :
00182     Base(const_cast<Plane_map&>(P)), K(k) {}
00183   /*{\Mcreate constructs a point locator working on |P|.}*/
00184   /*{\Moptions constref=no}*/
00185   /*{\Moperations 2.5 0.5}*/
00186 
00187   const Mark& mark(Object_handle h) const
00188   /*{\Mop returns the mark associated to the object |h|.}*/
00189   { Vertex_const_handle v;
00190     Halfedge_const_handle e;
00191     Face_const_handle f;
00192     if ( assign(v,h) ) return mark(v);
00193     if ( assign(e,h) ) return mark(e);
00194     if ( assign(f,h) ) return mark(f);
00195     CGAL_error_msg("PM_point_locator::mark: Object_handle holds no object.");
00196     return mark(v); // never reached
00197   }
00198 
00199 
00200   Object_handle locate(const Segment& s) const
00201   /*{\Mop returns a generic handle |h| to an object (vertex, halfedge,
00202   face) of the underlying plane map |P| which contains the point |p =
00203   s.source()| in its relative interior. |s.target()| must be a point
00204   such that |s| intersects the $1$-skeleton of |P|.}*/
00205   { CGAL_NEF_TRACEN("locate naivly "<<s);
00206     if (this->number_of_vertices() == 0)
00207       CGAL_error_msg("PM_naive_point_locator: plane map is empty.");
00208     Point p = K.source(s);
00209     Vertex_const_iterator vit;
00210     for(vit = this->vertices_begin(); vit != this->vertices_end(); ++vit) {
00211       if ( p == point(vit) ) return make_object(vit);
00212     }
00213     Halfedge_const_iterator eit;
00214     for(eit = this->halfedges_begin(); eit != this->halfedges_end(); ++(++eit)) {
00215       // we only have to check each second halfedge
00216       if ( K.contains(segment(eit),p) )
00217         return make_object(eit);
00218     }
00219     Vertex_const_handle v_res;
00220     Halfedge_const_handle e_res;
00221     Segment ss = s; // we shorten the segment iteratively
00222     Direction dso = K.construct_direction(K.target(s),p), d_res;
00223     CGAL::Unique_hash_map<Halfedge_const_handle,bool> visited(false);
00224     for(vit = this->vertices_begin(); vit != this->vertices_end(); ++vit) {
00225       Point p_res, vp = point(vit);
00226       if ( K.contains(ss,vp) ) {
00227         CGAL_NEF_TRACEN(" location via vertex at "<<vp);
00228         ss = K.construct_segment(p,vp); // we shrink the segment
00229         if ( is_isolated(vit) ) {
00230           v_res = vit; e_res = Halfedge_const_handle();
00231         } else { // not isolated
00232           bool dummy;
00233           e_res = out_wedge(vit,dso,dummy);
00234           Halfedge_around_vertex_const_circulator el(e_res),ee(el);
00235           CGAL_For_all(el,ee)
00236             visited[el] = visited[twin(el)] = true;
00237           /* e_res is now the counterclockwise maximal halfedge out
00238              of v just before s */
00239           if ( K.orientation(p,vp,point(target(e_res))) < 0 ) // right turn
00240             e_res = previous(e_res);
00241           // correction to make e_res visible from p
00242           CGAL_NEF_TRACEN("  determined "<<PE(e_res));
00243         }
00244       }
00245     }
00246 
00247     for (eit = this->halfedges_begin(); eit != this->halfedges_end(); ++eit) {
00248       if ( visited[eit] ) continue;
00249       Point se = point(source(eit)),
00250             te = point(target(eit));
00251       int o1 = K.orientation(ss,se);
00252       int o2 = K.orientation(ss,te);
00253       if ( o1 == -o2 && // internal intersection
00254            K.orientation(se,te,K.source(ss)) !=
00255            K.orientation(se,te,K.target(ss)) ) {
00256           CGAL_NEF_TRACEN(" location via halfedge "<<segment(eit));
00257         Point p_res = K.intersection(s,segment(eit));
00258         ss = K.construct_segment(p,p_res);
00259         e_res = (o2 > 0 ? eit : twin(eit));
00260         // o2>0 => te left of s and se right of s => p left of e
00261         visited[eit] = visited[twin(eit)] = true;
00262         CGAL_NEF_TRACEN("  determined "<<PE(e_res)<<" "<<mark(e_res));
00263         CGAL_NEF_TRACEN("             "<<mark(face(e_res)));
00264       }
00265     }
00266 
00267     if ( e_res != Halfedge_const_handle() )
00268       return make_object((Face_const_handle)(face(e_res)));
00269     else
00270       return make_object((Face_const_handle)(face(v_res)));
00271   }
00272 
00273 
00274   template <typename Object_predicate>
00275   Object_handle ray_shoot(const Segment& s, const Object_predicate& M) const
00276   /*{\Mop returns an |Object_handle o| which can be converted to a
00277   |Vertex_const_handle|, |Halfedge_const_handle|, |Face_const_handle|
00278   |h| as described above.  The object predicate |M| has to have function
00279   operators \\
00280   |bool operator() (const Vertex_/Halfedge_/Face_const_handle&)|.\\
00281   The object returned is intersected by the segment |s| and has
00282   minimal distance to |s.source()| and |M(h)| holds on the converted
00283   object. The operation returns the null handle |NULL| if the ray shoot
00284   along |s| does not hit any object |h| of |P| with |M(h)|.}*/
00285   { CGAL_NEF_TRACEN("naive ray_shoot "<<s);
00286     CGAL_assertion( !K.is_degenerate(s) );
00287     Point p = K.source(s);
00288     Segment ss(s);
00289     Direction d = K.construct_direction(K.source(s),K.target(s));
00290     Object_handle h = locate(s);
00291     Vertex_const_handle v;
00292     Halfedge_const_handle e;
00293     Face_const_handle f;
00294     if ( assign(v,h) && M(v) ||
00295          assign(e,h) && M(e) ||
00296          assign(f,h) && M(f) ) return h;
00297     h = Object_handle();
00298     CGAL_NEF_TRACEN("not contained");
00299     for (v = this->vertices_begin(); v != this->vertices_end(); ++v) {
00300       Point pv = point(v);
00301       if ( !K.contains(ss,pv) ) continue;
00302       CGAL_NEF_TRACEN("candidate "<<pv);
00303       if ( M(v) ) {
00304         h = make_object(v);     // store vertex
00305         ss = K.construct_segment(p,pv); // shorten
00306         continue;
00307       }
00308       // now we know that v is not marked but on s
00309       bool collinear;
00310       Halfedge_const_handle e = out_wedge(v,d,collinear);
00311       if ( collinear ) {
00312         if ( M(e) ) {
00313           h = make_object(e);
00314           ss = K.construct_segment(p,pv);
00315         }
00316         continue;
00317       }
00318       if ( M(face(e)) ) {
00319         h = make_object(face(e));
00320         ss = K.construct_segment(p,pv);
00321       }
00322     } // all vertices
00323 
00324     Halfedge_const_iterator e_res;
00325     for(e = this->halfedges_begin(); e != this->halfedges_end(); ++(++e)) {
00326       Segment es = segment(e);
00327       int o1 = K.orientation(ss,K.source(es));
00328       int o2 = K.orientation(ss,K.target(es));
00329       if ( o1 == -o2 && o1 != 0 &&
00330            K.orientation(es, K.source(ss)) ==
00331            - K.orientation(es, K.target(ss)) ) {
00332         // internal intersection
00333         CGAL_NEF_TRACEN("candidate "<<es);
00334         Point p_res = K.intersection(s,es);
00335         e_res = (o2 > 0 ? e : twin(e));
00336         // o2 > 0 => te left of s and se right of s => p left of e
00337         if ( M(e_res) ) {
00338           h = make_object(e_res);
00339           ss = K.construct_segment(p,p_res);
00340         } else if ( M(face(twin(e_res))) ) {
00341           h = make_object(face(twin(e_res)));
00342           ss = K.construct_segment(p,p_res);
00343         }
00344       }
00345     }
00346 
00347     return h;
00348   }
00349 
00350 
00351   // C++ is really friendly:
00352   #define USECMARK(t) const Mark& mark(t h) const { return Base::mark(h); }
00353   #define USEMARK(t)  Mark& mark(t h) const { return Base::mark(h); }
00354   USEMARK(Vertex_handle)
00355   USEMARK(Halfedge_handle)
00356   USEMARK(Face_handle)
00357   USECMARK(Vertex_const_handle)
00358   USECMARK(Halfedge_const_handle)
00359   USECMARK(Face_const_handle)
00360   #undef USEMARK
00361   #undef USECMARK
00362   /*{\Mimplementation Naive query operations are realized by checking
00363   the intersection points of the $1$-skeleton of the plane map |P| with
00364   the query segments $s$. This method takes time linear in the size $n$
00365   of the underlying plane map without any preprocessing.}*/
00366 }; // PM_naive_point_locator<PM_decorator_,Geometry_>
00367 
00368 
00369 /*{\Moptions print_title=yes }*/
00370 /*{\Msubst
00371 PM_decorator_#PMD
00372 Geometry_#GEO
00373 }*/
00374 /*{\Manpage {PM_point_locator}{PMD,GEO}
00375 {Point location in plane maps via LMWT}{PL}}*/
00376 /*{\Mdefinition An instance |\Mvar| of data type |\Mname|
00377 encapsulates point location queries within a plane map |P|. The two
00378 template parameters are specified via concepts. |PMD| must be a model
00379 of the concept |PMDecorator| as described in the appendix.  |GEO| must
00380 be a model of the concept |AffineGeometryTraits_2| as described in the
00381 appendix. For a specification of plane maps see also the concept of
00382 |PMConstDecorator|.}*/
00383 
00384 /*{\Mgeneralization PMD^#PM_naive_point_locator<PMD,GEO>}*/
00385 
00386 template <typename PM_decorator_, typename Geometry_>
00387 class PM_point_locator : public
00388   PM_naive_point_locator<PM_decorator_,Geometry_> {
00389 protected:
00390   typedef PM_naive_point_locator<PM_decorator_,Geometry_> Base;
00391   typedef PM_point_locator<PM_decorator_,Geometry_> Self;
00392   Base CT;
00393   #ifdef CGAL_USING_PPL
00394   typedef PM_persistent_PL_traits<Base>  PMPPLT;
00395   typedef PointLocator<PMPPLT>           PMPP_locator;
00396   PMPP_locator* pPPL;
00397   #define LOCATE_IN_TRIANGULATION pPPL->locate_down
00398   #else
00399   #define LOCATE_IN_TRIANGULATION walk_in_triangulation
00400   #endif
00401 
00402 public:
00403 
00404   typedef typename Base::Decorator Decorator;
00405   typedef typename Base::Plane_map Plane_map;
00406   typedef typename Base::Mark Mark;
00407   typedef typename Base::Geometry Geometry;
00408   typedef typename Base::Point Point;
00409   typedef typename Base::Segment Segment;
00410   typedef typename Base::Direction Direction;
00411   typedef typename Base::Object_handle Object_handle;
00412   typedef typename Base::Vertex_handle Vertex_handle;
00413   typedef typename Base::Halfedge_handle Halfedge_handle;
00414   typedef typename Base::Face_handle Face_handle;
00415   typedef typename Base::Vertex_const_handle Vertex_const_handle;
00416   typedef typename Base::Halfedge_const_handle Halfedge_const_handle;
00417   typedef typename Base::Face_const_handle Face_const_handle;
00418   typedef typename Base::Vertex_iterator Vertex_iterator;
00419   typedef typename Base::Halfedge_iterator Halfedge_iterator;
00420   typedef typename Base::Face_iterator Face_iterator;
00421   typedef typename Base::Vertex_const_iterator Vertex_const_iterator;
00422   typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator;
00423   typedef typename Base::Face_const_iterator Face_const_iterator;
00424   typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
00425   typedef typename Base::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator;
00426   typedef typename Base::Halfedge_around_face_circulator Halfedge_around_face_circulator;
00427   typedef typename Base::Halfedge_around_face_const_circulator Halfedge_around_face_const_circulator;
00428 
00429   using Base::K;
00430   using Base::number_of_vertices;
00431   using Base::faces_begin;
00432 
00433   /*{\Mtypes 2}*/
00434   /*{\Mtext All local types of |PM_naive_point_locator| are inherited.}*/
00435   typedef std::pair<Vertex_const_handle,Face_const_handle>   VF_pair;
00436   typedef std::pair<Halfedge_const_handle,Face_const_handle> EF_pair;
00437 
00438   struct CT_link_to_original : Decorator { // CT decorator
00439     const Decorator& Po;
00440     CT_link_to_original(const Decorator& P, const Decorator& Poi)
00441       : Decorator(P), Po(Poi) {}
00442     void operator()(Vertex_handle vn, Vertex_const_handle vo) const
00443     { Face_const_handle f;
00444       if ( Po.is_isolated(vo) ) f = Po.face(vo);
00445       geninfo<VF_pair>::create(info(vn));
00446       geninfo<VF_pair>::access(info(vn)) = VF_pair(vo,f);
00447       CGAL_NEF_TRACEN("linking to org "<<PV(vn));
00448     }
00449     void operator()(Halfedge_handle hn, Halfedge_const_handle ho) const
00450     { geninfo<EF_pair>::create(info(hn));
00451       geninfo<EF_pair>::access(info(hn)) = EF_pair(ho,Po.face(ho));
00452       CGAL_NEF_TRACEN("linking to org "<<PE(hn));
00453     }
00454   };
00455 
00456 protected:
00457   Vertex_const_handle input_vertex(Vertex_const_handle v) const
00458   { return geninfo<VF_pair>::const_access(CT.info(v)).first; }
00459 
00460   Halfedge_const_handle input_halfedge(Halfedge_const_handle e) const
00461   { return geninfo<EF_pair>::const_access(CT.info(e)).first; }
00462 
00463   Face_const_handle input_face(Halfedge_const_handle e) const
00464   { return geninfo<EF_pair>::const_access(CT.info(e)).second; }
00465 
00466 
00467   Object_handle input_object(Vertex_const_handle v) const
00468   { return make_object(input_vertex(v)); }
00469 
00470   Object_handle input_object(Halfedge_const_handle e) const
00471   { Halfedge_const_handle e_org = input_halfedge(e);
00472     if ( e_org != Halfedge_const_handle() )
00473       return make_object( e_org );
00474     // now e_org is not existing
00475     return make_object( input_face(e) );
00476   }
00477 
00478   /*{\Mimplementation
00479   The efficiency of this point location module is mostly based on
00480   heuristics. Therefore worst case bounds are not very expressive. The
00481   query operations take up to linear time for subsequent query
00482   operations though they are better in practise. They trigger a one-time
00483   initialization which needs worst case $O(n^2)$ time though runtime
00484   tests often show subquadratic results. The necessary space for the
00485   query structure is subsumed in the storage space $O(n)$ of the input
00486   plane map. The query times are configuration dependent. If LEDA is
00487   present then point location is done via the slap method based on
00488   persistent dictionaries.  Then $T_{pl}(n) = O( \log(n) )$. If CGAL is
00489   not configured to use LEDA then point location is done via a segment
00490   walk in the underlying convex subdivision of $P$. In this case
00491   $T_{pl}(n)$ is the number of triangles crossed by a walk from the
00492   boundary of the structure to the query point. The time for the ray
00493   shooting operation $T_{rs}(n)$ is the time for the point location
00494   $T_{pl}(n)$ plus the time for the walk in the triangulation that is
00495   superimposed to the plane map. Let's consider the plane map edges as
00496   obstacles and the additional triangulation edges as non-obstacle
00497   edges. Let's call the sum of the lengths of all edges of the
00498   triangulation its weight. If the calculated triangulation
00499   approximates\footnote{The calculation of general
00500   minimum-weight-triangulations is conjectured to be NP-complete and
00501   locally-minimum-weight-triangulations that we use are considered good
00502   approximations.} the minimum weight triangulation of the obstacle set
00503   then the stepping quotient\footnote {The number of non-obstacle edges
00504   crossed until an obstacle edge is hit.} for a random direction of the
00505   ray shot is expected to be $O( \sqrt{n} )$.}*/
00506 
00507 
00508   struct CT_new_edge : Decorator {
00509     const Decorator& _DP;
00510     CT_new_edge(const Decorator& CT, const Decorator& DP) :
00511       Decorator(CT), _DP(DP) {}
00512     void operator()(Halfedge_handle& e) const
00513     { Halfedge_handle e_from = previous(e);
00514       Face_const_handle f;
00515       if ( is_closed_at_source(e) ) // source(e) was isolated before
00516         f = geninfo<VF_pair>::access(info(source(e))).second;
00517       else
00518         f = geninfo<EF_pair>::access(info(e_from)).second;
00519       mark(e) = _DP.mark(f);
00520       geninfo<EF_pair>::create(info(e));
00521       geninfo<EF_pair>::create(info(twin(e)));
00522 
00523       geninfo<EF_pair>::access(info(e)).first =
00524       geninfo<EF_pair>::access(info(twin(e))).first =
00525         Halfedge_const_handle();
00526 
00527       geninfo<EF_pair>::access(info(e)).second =
00528       geninfo<EF_pair>::access(info(twin(e))).second = f;
00529       CGAL_NEF_TRACEN("CT_new_edge "<<PE(e));
00530     }
00531   };
00532 
00533   void triangulate_CT() const
00534   {
00535     CGAL_NEF_TRACEN("triangulate_CT");
00536     typedef CGAL::Constrained_triang_traits<
00537       Decorator,Geometry,CT_new_edge> NCTT;
00538     typedef CGAL::generic_sweep<NCTT> Constrained_triang_sweep;
00539     CT_new_edge NE(CT,*this);
00540     Constrained_triang_sweep T(NE,CT.plane_map(),this->K); T.sweep();
00541   }
00542 
00543   void minimize_weight_CT() const
00544   { CGAL_NEF_TRACEN("minimize_weight_CT");
00545     if ( this->number_of_vertices() < 2 ) return;
00546     std::list<Halfedge_handle> S;
00547     /* We maintain a stack |S| of edges containing diagonals
00548        which might have to be flipped. */
00549     int flip_count = 0;
00550     Halfedge_iterator e;
00551     for (e = CT.halfedges_begin(); e != CT.halfedges_end(); ++(++e)) {
00552       Halfedge_const_handle e_org = input_halfedge(e);
00553       if ( e_org != Halfedge_const_handle() )
00554         continue;
00555       S.push_back(e);
00556     }
00557 
00558     while ( !S.empty() ) {
00559       Halfedge_handle e = S.front(); S.pop_front();
00560       Halfedge_handle r = twin(e);
00561       Halfedge_const_handle e_org = input_halfedge(e);
00562       if ( e_org != Halfedge_const_handle() )
00563         continue;
00564       Halfedge_handle e1 = next(r);
00565       Halfedge_handle e3 = next(e);
00566       // e1,e3: edges of quadrilateral with diagonal e
00567 
00568       Point a = point(source(e1));
00569       Point b = point(target(e1));
00570       Point c = point(source(e3));
00571       Point d = point(target(e3));
00572 
00573       if (! (this->K.orientation(b,d,a) > 0 && // left_turn
00574              this->K.orientation(b,d,c) < 0) ) // right_turn
00575         continue;
00576 
00577       if ( this->K.first_pair_closer_than_second(b,d,a,c) ) { // flip
00578         CGAL_NEF_TRACEN("flipping diagonal of quadilateral"<<a<<b<<c<<d);
00579         Halfedge_handle e2 = next(e1);
00580         Halfedge_handle e4 = next(e3);
00581         S.push_back(e1);
00582         S.push_back(e2);
00583         S.push_back(e3);
00584         S.push_back(e4);
00585         flip_diagonal(e);
00586         flip_count++;
00587       }
00588 
00589 
00590     }
00591     CGAL_NEF_TRACEN("  flipped "<<flip_count);
00592   }
00593 
00594 public:
00595   /*{\Mcreation 3}*/
00596 
00597   PM_point_locator() {
00598     #ifdef CGAL_USING_PPL
00599     pPPL = 0;
00600     #endif
00601 
00602   }
00603 
00604   /*{\Moptions constref=yes}*/
00605   PM_point_locator(const Plane_map& P, const Geometry& k = Geometry());
00606   /*{\Mcreate constructs a point locator working on |P|.}*/
00607 
00608   ~PM_point_locator();
00609 
00610   /*{\Moperations 2.5 0.5}*/
00611 
00612   const Decorator& triangulation() const { return CT; }
00613   /*{\Mop access to the constrained triangulation structure that
00614   is superimposed to |P|.}*/
00615   /*{\Moptions constref=no}*/
00616 
00617 
00618   Object_handle locate(const Point& p) const
00619   /*{\Mop returns a generic handle |h| to an object (vertex, halfedge,
00620   face) of |P| which contains the point |p| in its relative
00621   interior.}*/
00622   {
00623     Object_handle h = LOCATE_IN_TRIANGULATION(p);
00624     Vertex_const_handle v_triang;
00625     if ( assign(v_triang,h) ) {
00626       return input_object(v_triang);
00627     }
00628     Halfedge_const_handle e_triang;
00629     if ( assign(e_triang,h) ) {
00630       Halfedge_const_handle e = input_halfedge(e_triang);
00631       if ( e == Halfedge_const_handle() ) // inserted during triangulation
00632         return make_object(input_face(e_triang));
00633       int orientation_ = this->K.orientation(segment(e),p);
00634       if ( orientation_ == 0 ) return make_object(e);
00635       if ( orientation_ < 0 )  return make_object(face(twin(e)));
00636       if ( orientation_ > 0 )  return make_object(face(e));
00637     }
00638     CGAL_assertion(!check_tag(typename Is_extended_kernel<Geometry>::value_type()));
00639     return make_object(Face_const_handle(faces_begin()));
00640     //    CGAL_error(); return h; // compiler warning
00641   }
00642 
00643   bool ray_shoot_from_outer_facet(Segment& , object_kind& ,
00644                                   Vertex_const_handle &,
00645                                   Halfedge_const_handle& ,
00646                                   const Tag_true& ) const {
00647     return false;
00648   }
00649 
00650   bool ray_shoot_from_outer_facet(Segment& s, object_kind& current,
00651                                   Vertex_const_handle &v,
00652                                   Halfedge_const_handle& e,
00653                                   const Tag_false& ) const {
00654     CGAL_NEF_TRACEN("target on outer facet");
00655     Point p = this->K.source(s);
00656     Vertex_const_handle v1 = CT.vertices_begin();
00657     Halfedge_const_handle e1 = CT.twin(CT.first_out_edge(v1));
00658     Halfedge_around_face_const_circulator circ(e1), end(circ);
00659     Point i;
00660     Segment seg;
00661     bool found = false;
00662     CGAL_For_all(circ, end) {
00663       //        std::cerr << s << std::endl;
00664       //        std::cerr << point(source(circ)) << "->" << point(target(circ)) << std::endl;
00665       Object o = intersection(s, Segment(point(source(circ)),
00666                                          point(target(circ))));
00667 
00668       if(assign(i,o)) {
00669         CGAL_NEF_TRACEN("intersection in point " << i);
00670         found = true;
00671         s = Segment(p,i);
00672         if(i == point(source(circ))) {
00673           current = VERTEX;
00674           v = source(circ);
00675         } else if(i == point(target(circ))) {
00676           current = VERTEX;
00677           v = target(circ);
00678         } else {
00679           current = EDGE_CROSSING;
00680           e = circ;
00681         }
00682       } else if(assign(seg,o)) {
00683         found = true;
00684         CGAL_NEF_TRACEN("overlap of segments");
00685         current = EDGE_COLLINEAR;
00686         e = circ;
00687       }
00688     }
00689     return found;
00690   }
00691 
00692   template <typename Object_predicate>
00693   Object_handle ray_shoot(const Segment& ss, const Object_predicate& M) const
00694   /*{\Mop returns an |Object_handle o| which can be converted to a
00695   |Vertex_const_handle|, |Halfedge_const_handle|, |Face_const_handle|
00696   |h| as described above.  The object predicate |M| has to have
00697   function operators\\
00698   |bool operator() (const Vertex_/ Halfedge_/Face_const_handle&) const|.\\
00699   The object returned is intersected by the segment |s| and has minimal
00700   distance to |s.source()| and |M(h)| holds on the converted object. The
00701   operation returns the null handle |NULL| if the ray shoot along |s|
00702   does not hit any object |h| of |P| with |M(h)|.}*/
00703   { Segment s(ss);
00704     CGAL_NEF_TRACEN("ray_shoot "<<s);
00705     CGAL_assertion( !this->K.is_degenerate(s) );
00706     Point p = this->K.source(s);
00707     Direction d = this->K.construct_direction(p,s.target());
00708     Vertex_const_handle v;
00709     Halfedge_const_handle e;
00710     object_kind current;
00711     Object_handle h = LOCATE_IN_TRIANGULATION(p);
00712     if ( assign(v,h) ) {
00713       CGAL_NEF_TRACEN("located vertex "<<PV(v));
00714       current = VERTEX;
00715     } else if ( assign(e,h) ) {
00716       CGAL_NEF_TRACEN("located edge "<<PE(e));
00717       int orientation_ = this->K.orientation( segment(e), p);
00718       if ( orientation_ == 0 ) { // p on segment
00719         CGAL_NEF_TRACEN("on edge "<<PE(e));
00720         if ( d == CT.direction(e) )
00721         { current = EDGE_COLLINEAR; }
00722         else if ( d == CT.direction(CT.twin(e)) )
00723         { e = CT.twin(e); current = EDGE_COLLINEAR; }
00724         else { // crossing
00725           current = EDGE_CROSSING;
00726           if ( !(this->K.orientation(CT.segment(e),s.target())>0) ) // not left_turn
00727             e = CT.twin(e);
00728         }
00729 
00730       } else { // p not on segment, thus in triangle
00731         if ( orientation_ < 0  ) e = CT.twin(e);
00732         // now p left of e
00733         CGAL_NEF_TRACEN("in face at "<<PE(e));
00734         if ( M(input_face(e)) ) // face mark
00735           return make_object(input_face(e));
00736 
00737         Point p1 = CT.point(CT.source(e)),
00738               p2 = CT.point(CT.target(e)),
00739               p3 = CT.point(CT.target(next(e)));
00740         int or1 = this->K.orientation(p,s.target(),p1);
00741         int or2 = this->K.orientation(p,s.target(),p2);
00742         int or3 = this->K.orientation(p,s.target(),p3);
00743         if ( or1 == 0 && !this->K.left_turn(p1,p2,s.target()) )
00744         { v = CT.source(e); current = VERTEX; }
00745         else if ( or2 == 0 && !this->K.left_turn(p2,p3,s.target()) )
00746         { v = CT.target(e); current = VERTEX; }
00747         else if ( or3 == 0 && !this->K.left_turn(p3,p1,s.target()) )
00748         { v = CT.target(CT.next(e)); current = VERTEX; }
00749         else if ( or2 > 0 && or1 < 0 && !this->K.left_turn(p1,p2,s.target()) )
00750         { e = CT.twin(e); current = EDGE_CROSSING; }
00751         else if ( or3 > 0 && or2 < 0 && !this->K.left_turn(p2,p3,s.target()) )
00752         { e = CT.twin(CT.next(e)); current = EDGE_CROSSING; }
00753         else if ( or1 > 0 && or3 < 0 && !this->K.left_turn(p3,p1,s.target()) )
00754         { e = CT.twin(CT.previous(e)); current = EDGE_CROSSING; }
00755         else return Object_handle();
00756 
00757       }
00758     } else {
00759 
00760       if(check_tag(typename Is_extended_kernel<Geometry>::value_type())) {
00761         CGAL_error_msg( "code is only for Bounded_kernel");
00762       }
00763       if(!ray_shoot_from_outer_facet(s,current,v,e,typename Is_extended_kernel<Geometry>::value_type()))
00764         return Object_handle();
00765     }
00766 
00767     CGAL_NEF_TRACEN("current = " << current);
00768     if(current == VERTEX)
00769       CGAL_NEF_TRACEN(point(v));
00770 
00771     while (true) switch ( current ) {
00772       case VERTEX:
00773         { CGAL_NEF_TRACEN("vertex "<<CT.point(v));
00774           Vertex_const_handle v_org = input_vertex(v);
00775           if ( M(v_org) ) return make_object(v_org);
00776           if ( CT.point(v) == s.target() ) return Object_handle();
00777           // stop walking at s.target(), or determine next object on s:
00778           bool collinear;
00779           Halfedge_const_handle e_out = CT.out_wedge(v,d,collinear);
00780           if (collinear) // ray shoot via e_out
00781           { e = e_out; current = EDGE_COLLINEAR; }
00782           else { // ray shoot in wedge left of e_out
00783             if ( M(input_face(e_out)) )
00784               return make_object(input_face(e_out));
00785             e = CT.twin(CT.next(e_out)); current = EDGE_CROSSING;
00786           }
00787         }
00788 
00789         break;
00790       case EDGE_CROSSING:
00791         { CGAL_NEF_TRACEN("crossing edge "<<segment(e));
00792           if ( this->K.orientation(CT.segment(e),s.target()) == 0 )
00793             return Object_handle();
00794           Halfedge_const_handle e_org = input_halfedge(e);
00795           if ( e_org != Halfedge_const_handle() ) { // not a CT edge
00796             if ( M(e_org) ) return make_object(e_org);
00797             if ( M(face(e_org)) ) return make_object(face(e_org));
00798           }
00799           Vertex_const_handle v_cand = CT.target(CT.next(e));
00800           CGAL_NEF_TRACEN("v_cand "<<PV(v_cand));
00801           int orientation_ = this->K.orientation(p,s.target(),CT.point(v_cand));
00802           switch( orientation_ ) {
00803             case 0:
00804               v = v_cand; current = VERTEX; break;
00805             case +1:
00806               e = CT.twin(CT.next(e)); current = EDGE_CROSSING; break;
00807             case -1:
00808               e = CT.twin(CT.previous(e)); current = EDGE_CROSSING; break;
00809           }
00810         }
00811 
00812         break;
00813       case EDGE_COLLINEAR:
00814         { CGAL_NEF_TRACEN("collinear edge "<<CT.segment(e));
00815           Halfedge_const_handle e_org = input_halfedge(e);
00816           if ( e_org == Halfedge_const_handle() ) { // a CT edge
00817             if ( M(input_face(e)) )
00818               return make_object(input_face(e));
00819           } else { // e_org is not a CT edge
00820             if ( M(e_org) )
00821               return make_object(e_org);
00822           }
00823           if ( this->K.strictly_ordered_along_line(
00824                  CT.point(CT.source(e)),s.target(),CT.point(CT.target(e))) )
00825             return Object_handle();
00826           v = CT.target(e); current = VERTEX;
00827         }
00828 
00829         break;
00830     }
00831     // CGAL_error(); return h; // compiler warning
00832   }
00833 
00834   bool within_outer_cycle(Vertex_const_handle ,
00835                           const Point& , const Tag_true& ) const {
00836     return true;
00837   }
00838 
00839   bool within_outer_cycle(Vertex_const_handle v,
00840                           const Point& q, const Tag_false& ) const {
00841     typedef Project_halfedge_point<typename Decorator::Halfedge, Point> Project;
00842     typedef Circulator_project<Halfedge_around_face_const_circulator,
00843       Project, const Point&, const Point*> Circulator;
00844     typedef Container_from_circulator<Circulator> Container;
00845 
00846     Halfedge_const_handle e_min = CT.twin(CT.first_out_edge(v));
00847     Halfedge_around_face_const_circulator circ(e_min);
00848     Circulator c(circ);
00849     Container ct(c);
00850     if(is_empty_range(ct.begin(), ct.end()) ||
00851        bounded_side_2(ct.begin(), ct.end(),q) == CGAL::ON_UNBOUNDED_SIDE)
00852       return false;
00853 
00854     return true;
00855   }
00856 
00857   Object_handle walk_in_triangulation(const Point& p) const;
00858 
00859 }; // PM_point_locator<PM_decorator_,Geometry_>
00860 
00861 
00862 #ifdef CGAL_USING_PPL
00863 static const char* const pointlocationversion ="point location via pers dicts";
00864 #else
00865 static const char* const pointlocationversion ="point location via seg walks";
00866 #endif
00867 
00868 template <typename PMD, typename GEO>
00869 PM_point_locator<PMD,GEO>::
00870 PM_point_locator(const Plane_map& P, const Geometry& k) :
00871   Base(P,k), CT(*(new Plane_map),k)
00872 
00873 { CGAL_NEF_TRACEN("PM_point_locator construction");
00874   CT.clone_skeleton(P,CT_link_to_original(CT,*this));
00875   triangulate_CT();
00876   minimize_weight_CT();
00877   #ifdef CGAL_USING_PPL
00878   pPPL = new PMPP_locator(CT,PMPPLT(K));
00879   #endif
00880 
00881 }
00882 
00883 template <typename PMD, typename GEO>
00884 PM_point_locator<PMD,GEO>::
00885 ~PM_point_locator()
00886 { CGAL_NEF_TRACEN("clear_static_point_locator");
00887   Vertex_iterator vit, vend = CT.vertices_end();
00888   for (vit = CT.vertices_begin(); vit != vend; ++vit) {
00889     geninfo<VF_pair>::clear(CT.info(vit));
00890   }
00891   Halfedge_iterator eit, eend = CT.halfedges_end();
00892   for (eit = CT.halfedges_begin(); eit != eend; ++eit) {
00893     geninfo<EF_pair>::clear(CT.info(eit));
00894   }
00895   CT.clear();
00896   delete &(CT.plane_map());
00897   #ifdef CGAL_USING_PPL
00898   delete pPPL; pPPL=0;
00899   #endif
00900 }
00901 
00902 template <typename PMD, typename GEO>
00903 typename PM_point_locator<PMD,GEO>::Object_handle
00904 PM_point_locator<PMD,GEO>::walk_in_triangulation(const Point& q) const
00905 {
00906   CGAL_NEF_TRACEN("walk in triangulation "<<q);
00907 
00908   Vertex_const_handle v = CT.vertices_begin();
00909 
00910   if(!check_tag(typename Is_extended_kernel<GEO>::value_type()))
00911     if(!within_outer_cycle(v,q,typename Is_extended_kernel<Geometry>::value_type()))
00912       return Object_handle();
00913 
00914   Halfedge_const_handle e;
00915   Point p = CT.point(v);
00916   if ( p == q ) return make_object(v);
00917   //  Segment s = this->K.construct_segment(p,q);
00918   Direction dir = this->K.construct_direction(p,q);
00919   object_kind current = VERTEX;
00920   while (true) switch ( current ) {
00921     case VERTEX:
00922       {
00923         CGAL_NEF_TRACEN("vertex "<<CT.point(v));
00924         if ( CT.point(v) == q )
00925           return make_object(v); // stop walking at q
00926         bool collinear;
00927         Halfedge_const_handle e_out = CT.out_wedge(v,dir,collinear);
00928         if (collinear) // ray shoot via e_out
00929         { e = e_out; current = EDGE_COLLINEAR; }
00930         else  // ray shoot in wedge left of e_out
00931         { e = CT.twin(CT.next(e_out)); current = EDGE_CROSSING; }
00932       }
00933 
00934       break;
00935     case EDGE_CROSSING:
00936       { CGAL_NEF_TRACEN("crossing edge "<<CT.segment(e));
00937         if ( !(this->K.orientation(CT.segment(e),q) > 0) ) // q not left of e
00938           return make_object(e);
00939         Vertex_const_handle v_cand = CT.target(CT.next(e));
00940         int orientation_ = this->K.orientation(p,q,CT.point(v_cand));
00941         switch( orientation_ ) {
00942           case 0:  // collinear
00943             if ( this->K.strictly_ordered_along_line(p,q,CT.point(v_cand)) )
00944               return make_object(e);
00945             v = v_cand; current = VERTEX; break;
00946           case +1: // left_turn
00947             e = twin(next(e)); current = EDGE_CROSSING; break;
00948           case -1:
00949             e = twin(previous(e)); current = EDGE_CROSSING; break;
00950         }
00951       }
00952 
00953       break;
00954     case EDGE_COLLINEAR:
00955       { CGAL_NEF_TRACEN("collinear edge "<<CT.segment(e));
00956         if ( this->K.strictly_ordered_along_line(
00957                CT.point(CT.source(e)),q,CT.point(CT.target(e))) )
00958           return make_object(e);
00959         v = CT.target(e); current = VERTEX;
00960       }
00961 
00962       break;
00963   }
00964   return Object_handle(); // never reached warning acceptable
00965 }
00966 
00967 CGAL_END_NAMESPACE
00968 
00969 #endif // CGAL_PM_POINT_LOCATOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines