sm_point_locator.h

来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 545 行 · 第 1/2 页

H
545
字号
// Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (Germany).// All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $Source: /CVSROOT/CGAL/Packages/Nef_S2/include/CGAL/Nef_S2/SM_point_locator.h,v $// $Revision: 1.15.2.1 $ $Date: 2004/12/08 20:10:13 $// $Name:  $//// Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>#ifndef CGAL_SM_POINT_LOCATOR_H#define CGAL_SM_POINT_LOCATOR_H#include <vector>#include <CGAL/basic.h>#include <CGAL/Unique_hash_map.h>#include <CGAL/Nef_2/geninfo.h>#include <CGAL/Nef_2/Object_handle.h>#include <CGAL/Nef_S2/SM_decorator_traits.h>#undef CGAL_NEF_DEBUG#define CGAL_NEF_DEBUG 47#include <CGAL/Nef_2/debug.h>CGAL_BEGIN_NAMESPACE/*{\Moptions print_title=yes }*/ /*{\Manpage {SM_point_locator}{Decorator}{Naive point location in plane maps}{PL}}*//*{\Mdefinition An instance |\Mvar| of data type |\Mname|encapsulates naive point location queries within a sphere map |M|.  Thetwo template parameters are specified via concepts. |SM_decorator_|must be a model of the concept |SMDecorator| as described in theappendix.  |Geometry_| must be a model of the concept|AffineGeometryTraits_2| as described in the appendix. For aspecification of plane maps see also the concept of|SMConstDecorator|.}*//*{\Mgeneralization Decorator}*/template <class SM_decorator>class SM_point_locator : public SM_decorator {protected:  typedef SM_decorator                                  Base;  typedef SM_point_locator<SM_decorator>                Self;  typedef typename SM_decorator::Sphere_map             Sphere_map;public:  /*{\Mtypes 5}*/  typedef typename SM_decorator::Decorator_traits  Decorator_traits;  typedef typename Base::Mark      Mark;  /*{\Mtypemember the attribute of all objects (vertices, edges, loops,  faces).}*/  typedef typename SM_decorator::Sphere_kernel Sphere_kernel;  /*{\Mtypemember the sphere kernel.}*/  typedef typename Sphere_kernel::Sphere_point Sphere_point;  /*{\Mtypemember points.}*/  typedef typename Sphere_kernel::Sphere_segment Sphere_segment;  /*{\Mtypemember segments.}*/  typedef typename Sphere_kernel::Sphere_circle Sphere_circle;  /*{\Mtypemember circles.}*/  typedef typename Sphere_kernel::Sphere_direction Sphere_direction;  /*{\Mtypemember directions.}*/  /*{\Mtext Local types are handles, iterators and circulators of the   following kind: |SVertex_const_handle|, |SVertex_const_iterator|,   |SHalfedge_const_handle|, |SHalfedge_const_iterator|,   |SHalfloop_const_handle|, |SHalfloop_const_iterator|,   |SFace_const_handle|, |SFace_const_iterator|.}*/  typedef CGAL::Object_handle Object_handle;  /*{\Mtypemember a generic handle to an object of the underlying plane  map. The kind of the object |(vertex, halfedge,face)| can be determined and  the object assigned by the three functions:\\   |bool assign(SVertex_const_handle& h, Object_handle o)|\\   |bool assign(SHalfedge_const_handle& h, Object_handle o)|\\   |bool assign(SFace_const_handle& h, Object_handle o)|\\ where each   function returns |true| iff the assignment of |o| to |h| was valid.}*/  typedef typename Decorator_traits::SVertex_handle       SVertex_handle;     typedef typename Decorator_traits::SHalfedge_handle     SHalfedge_handle;     typedef typename Decorator_traits::SHalfloop_handle     SHalfloop_handle;     typedef typename Decorator_traits::SFace_handle         SFace_handle;       typedef typename Decorator_traits::SVertex_iterator     SVertex_iterator;  typedef typename Decorator_traits::SHalfedge_iterator   SHalfedge_iterator;  typedef typename Decorator_traits::SHalfloop_iterator   SHalfloop_iterator;  typedef typename Decorator_traits::SFace_iterator       SFace_iterator;  typedef typename Decorator_traits::SHalfedge_around_svertex_circulator                                     SHalfedge_around_svertex_circulator;  typedef typename Decorator_traits::SHalfedge_around_sface_circulator                                     SHalfedge_around_sface_circulator;  Sphere_segment segment(SHalfedge_handle e) const  { return Sphere_segment(point(source(e)), point(target(e)), circle(e)); }  Sphere_direction direction(SHalfedge_handle e) const  { return Sphere_direction(circle(e)); }  SHalfedge_handle out_wedge(SVertex_handle v, const Sphere_direction& d, 			     bool& collinear) const  /*{\Xop returns a halfedge |e| bounding a wedge in between two  neighbored edges in the adjacency list of |v| which contains |d|.  If |d| extends along a edge then |e| is this edge. If |d| extends  into the interior of such a wedge then |e| is the first edge hit  when |d| is rotated clockwise. \precond |v| is not isolated.}*/  { CGAL_NEF_TRACEN("out_wedge "<<PH(v));    CGAL_assertion(!is_isolated(v));    collinear=false;    Sphere_point p = point(v);    SHalfedge_handle e_res = first_out_edge(v);    Sphere_direction d_res = direction(e_res);    SHalfedge_around_svertex_circulator el(e_res),ee(el);    if(direction(el) == d) {      collinear = true;      CGAL_NEF_TRACEN("  determined "<<PH(el) << circle(el));      return el;    }    CGAL_For_all(el,ee) {      if(direction(cyclic_adj_succ(el)) == d) {	collinear = true;	CGAL_NEF_TRACEN("  equal "<<PH(cyclic_adj_succ(el)) << circle(cyclic_adj_succ(el)));	return cyclic_adj_succ(el);      }      else {	CGAL_NEF_TRACEN("strictly_ordered_ccw " << direction(el) << " ? " << d << " ? " << direction(cyclic_adj_succ(el)));	//	if ( strictly_ordered_ccw_at(p,d_res, direction(el), d) ) {	if ( strictly_ordered_ccw_at(p,direction(el), d, direction(cyclic_adj_succ(el))) ) {	  CGAL_NEF_TRACEN("strictly_ordered_ccw " << direction(el) << " - " << d << " - " << direction(cyclic_adj_succ(el)));	  e_res = el; d_res = direction(e_res); break;	}      }    }    CGAL_NEF_TRACEN("  finally determined "<<PH(e_res) << circle(e_res));    /*    Sphere_direction d2 = direction(cyclic_adj_succ(e_res));    d2 = normalized(d2);    CGAL_NEF_TRACEN(d2 << " =?= " << d);    if (d2 == d ) {      e_res = cyclic_adj_succ(e_res);      collinear=true;    }    CGAL_NEF_TRACEN("  wedge = "<<PH(e_res)<<" "<<collinear);    */    return e_res;  }  /*{\Mcreation 3}*/  SM_point_locator() : Base() {}  /*{\Moptions constref=yes}*/  SM_point_locator(Sphere_map* cp) : Base(cp) {}  /*{\Mcreate constructs a point locator working on |P|.}*/  /*{\Moptions constref=no}*/  /*{\Moperations 2.5 0.5}*/  const Mark& mark(Object_handle h) const  /*{\Mop returns the mark associated to the object |h|.}*/  { SVertex_handle v;     SHalfedge_handle e;     SHalfloop_handle l;    SFace_handle f;    if ( CGAL::assign(v,h) ) return Base::mark(v);    if ( CGAL::assign(e,h) ) return Base::mark(e);    if ( CGAL::assign(l,h) ) return Base::mark(l);    CGAL_assertion_msg(CGAL::assign(f,h),	 "PM_point_locator::mark: Object_handle holds no object.");    CGAL::assign(f,h);    return Base::mark(f);  }  enum SOLUTION { is_vertex_, is_edge_, is_loop_ };  // enumeration for internal use  Object_handle locate(const Sphere_point& p) const  /*{\Mop returns a generic handle |h| to an object (vertex, halfedge,  face) of the underlying plane map |P| which contains the point |p =  s.source()| in its relative interior. |s.target()| must be a point  such that |s| intersects the $1$-skeleton of |P|.}*/  { CGAL_NEF_TRACEN("locate naivly "<<p);    SVertex_iterator v;    CGAL_forall_svertices(v,*this) {      if ( p == point(v) ) {	CGAL_NEF_TRACEN( "  on point"); 	return Object_handle(v);      }    }    SHalfedge_iterator e;    CGAL_forall_sedges(e,*this) {      if ( segment(e).has_on(p) ) {	CGAL_NEF_TRACEN( "  on segment " << segment(e));	return Object_handle(e);      }    }    if ( this->has_shalfloop() && circle(this->shalfloop()).has_on(p) ) {      CGAL_NEF_TRACEN( "  on loop");      return Object_handle(SHalfloop_handle(this->shalfloop()));    }    // now in face:    if(this->number_of_sfaces() == 1) {      CGAL_NEF_TRACEN("  on unique face");      SFace_handle f = this->sfaces_begin();      return Object_handle(f);    }    SVertex_handle v_res;    SHalfedge_handle e_res;    SHalfloop_handle l_res(this->shalfloop());    SOLUTION solution;    CGAL_NEF_TRACEN("  on face...");    Sphere_segment s; // we shorten the segment iteratively    if ( this->has_shalfloop() ) {      Sphere_circle c(circle(this->shalfloop()),p); // orthogonal through p      s = Sphere_segment(p,intersection(c,circle(this->shalfloop())));      l_res = circle(this->shalfloop()).has_on_positive_side(p) ? 	this->shalfloop() : twin(this->shalfloop());      solution = is_loop_;      CGAL_NEF_TRACEN("has loop, initial ray "<<s);      CGAL_NEF_TRACEN(circle(l_res));    } else { // has vertices !      CGAL_assertion( this->number_of_svertices()!=0 );      SVertex_iterator vi = this->svertices_begin();      if( p == point(vi).antipode()) {	++vi;	CGAL_assertion( vi != this->svertices_end());      }      CGAL_NEF_TRACEN("initial segment: "<<p<<","<<point(vi));      CGAL_assertion( p != point(vi).antipode());      s = Sphere_segment( p, point(vi));      v_res = vi;      solution = is_vertex_;      CGAL_NEF_TRACEN("has vertices, initial ray "<<s);    }    // s now initialized        Sphere_direction dso(s.sphere_circle().opposite());    Unique_hash_map<SHalfedge_handle,bool> visited(false);    CGAL_forall_svertices(v,*this) {      Sphere_point vp = point(v);      if ( s.has_on(vp) ) {        CGAL_NEF_TRACEN(" location via vertex at "<<vp);        s = Sphere_segment(p,vp,s.sphere_circle()); // we shrink the segment        if ( is_isolated(v) ) {          CGAL_NEF_TRACEN("is_vertex_");          v_res = v; solution = is_vertex_;        } else { // not isolated          bool dummy;          e_res = out_wedge(v,dso,dummy);          SHalfedge_around_svertex_circulator el(e_res),ee(el);          CGAL_For_all(el,ee)             visited[el] = visited[twin(el)] = true;          /* e_res is now the counterclockwise maximal halfedge out             of v just before s */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?