pm_point_locator.h
来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 879 行 · 第 1/3 页
H
879 行
#ifdef CGAL_USING_PPL pPPL = 0; #endif } /*{\Moptions constref=yes}*/ PM_point_locator(const Plane_map& P, const Geometry& k = Geometry()); /*{\Mcreate constructs a point locator working on |P|.}*/ ~PM_point_locator(); /*{\Moperations 2.5 0.5}*/ const Decorator& triangulation() const { return CT; } /*{\Mop access to the constrained triangulation structure that is superimposed to |P|.}*/ /*{\Moptions constref=no}*/ Object_handle locate(const Point& p) const /*{\Mop returns a generic handle |h| to an object (vertex, halfedge, face) of |P| which contains the point |p| in its relative interior.}*/ { Object_handle h = LOCATE_IN_TRIANGULATION(p); Vertex_const_handle v_triang; if ( assign(v_triang,h) ) { return input_object(v_triang); } Halfedge_const_handle e_triang; if ( assign(e_triang,h) ) { Halfedge_const_handle e = input_halfedge(e_triang); if ( e == Halfedge_const_handle() ) // inserted during triangulation return Object_handle(input_face(e_triang)); int orientation_ = this->K.orientation(segment(e),p); if ( orientation_ == 0 ) return Object_handle(e); if ( orientation_ < 0 ) return Object_handle(face(twin(e))); if ( orientation_ > 0 ) return Object_handle(face(e)); } assert(0); return h; // compiler warning } template <typename Object_predicate> Object_handle ray_shoot(const Segment& s, const Object_predicate& M) const /*{\Mop returns an |Object_handle o| which can be converted to a |Vertex_const_handle|, |Halfedge_const_handle|, |Face_const_handle| |h| as described above. The object predicate |M| has to have function operators\\ |bool operator() (const Vertex_/ Halfedge_/Face_const_handle&) const|.\\ The object returned is intersected by the segment |s| and has minimal distance to |s.source()| and |M(h)| holds on the converted object. The operation returns the null handle |NULL| if the ray shoot along |s| does not hit any object |h| of |P| with |M(h)|.}*/ { CGAL_NEF_TRACEN("ray_shoot "<<s); CGAL_assertion( !this->K.is_degenerate(s) ); Point p = this->K.source(s), q = this->K.target(s); Direction d = this->K.construct_direction(p,q); Vertex_const_handle v; Halfedge_const_handle e; object_kind current; Object_handle h = LOCATE_IN_TRIANGULATION(p); if ( assign(v,h) ) { CGAL_NEF_TRACEN("located vertex "<<PV(v)); current = VERTEX; } if ( assign(e,h) ) { CGAL_NEF_TRACEN("located edge "<<PE(e)); int orientation_ = this->K.orientation( segment(e), p); if ( orientation_ == 0 ) { // p on segment CGAL_NEF_TRACEN("on edge "<<PE(e)); if ( d == CT.direction(e) ) { current = EDGE_COLLINEAR; } else if ( d == CT.direction(CT.twin(e)) ) { e = CT.twin(e); current = EDGE_COLLINEAR; } else { // crossing current = EDGE_CROSSING; if ( !(this->K.orientation(CT.segment(e),q)>0) ) // not left_turn e = CT.twin(e); } } else { // p not on segment, thus in triangle if ( orientation_ < 0 ) e = CT.twin(e); // now p left of e CGAL_NEF_TRACEN("in face at "<<PE(e)); if ( M(input_face(e)) ) // face mark return Object_handle(input_face(e)); Point p1 = CT.point(CT.source(e)), p2 = CT.point(CT.target(e)), p3 = CT.point(CT.target(next(e))); int or1 = this->K.orientation(p,q,p1); int or2 = this->K.orientation(p,q,p2); int or3 = this->K.orientation(p,q,p3); if ( or1 == 0 && !this->K.left_turn(p1,p2,q) ) { v = CT.source(e); current = VERTEX; } else if ( or2 == 0 && !this->K.left_turn(p2,p3,q) ) { v = CT.target(e); current = VERTEX; } else if ( or3 == 0 && !this->K.left_turn(p3,p1,q) ) { v = CT.target(CT.next(e)); current = VERTEX; } else if ( or2 > 0 && or1 < 0 && !this->K.left_turn(p1,p2,q) ) { e = CT.twin(e); current = EDGE_CROSSING; } else if ( or3 > 0 && or2 < 0 && !this->K.left_turn(p2,p3,q) ) { e = CT.twin(CT.next(e)); current = EDGE_CROSSING; } else if ( or1 > 0 && or3 < 0 && !this->K.left_turn(p3,p1,q) ) { e = CT.twin(CT.previous(e)); current = EDGE_CROSSING; } else return Object_handle(); } } while (true) switch ( current ) { case VERTEX: { CGAL_NEF_TRACEN("vertex "<<CT.point(v)); Vertex_const_handle v_org = input_vertex(v); if ( M(v_org) ) return Object_handle(v_org); if ( CT.point(v) == q ) return Object_handle(); // stop walking at q, or determine next object on s: bool collinear; Halfedge_const_handle e_out = CT.out_wedge(v,d,collinear); if (collinear) // ray shoot via e_out { e = e_out; current = EDGE_COLLINEAR; } else { // ray shoot in wedge left of e_out if ( M(input_face(e_out)) ) return Object_handle(input_face(e_out)); e = CT.twin(CT.next(e_out)); current = EDGE_CROSSING; } } break; case EDGE_CROSSING: { CGAL_NEF_TRACEN("crossing edge "<<segment(e)); if ( this->K.orientation(CT.segment(e),q) == 0 ) return Object_handle(); Halfedge_const_handle e_org = input_halfedge(e); if ( e_org != Halfedge_const_handle() ) { // not a CT edge if ( M(e_org) ) return Object_handle(e_org); if ( M(face(e_org)) ) return Object_handle(face(e_org)); } Vertex_const_handle v_cand = CT.target(CT.next(e)); CGAL_NEF_TRACEN("v_cand "<<PV(v_cand)); int orientation_ = this->K.orientation(p,q,CT.point(v_cand)); switch( orientation_ ) { case 0: v = v_cand; current = VERTEX; break; case +1: e = CT.twin(CT.next(e)); current = EDGE_CROSSING; break; case -1: e = CT.twin(CT.previous(e)); current = EDGE_CROSSING; break; } } break; case EDGE_COLLINEAR: { CGAL_NEF_TRACEN("collinear edge "<<CT.segment(e)); Halfedge_const_handle e_org = input_halfedge(e); if ( e_org == Halfedge_const_handle() ) { // a CT edge if ( M(input_face(e)) ) return Object_handle(input_face(e)); } else { // e_org is not a CT edge if ( M(e_org) ) return Object_handle(e_org); } if ( this->K.strictly_ordered_along_line( CT.point(CT.source(e)),q,CT.point(CT.target(e))) ) return Object_handle(); v = CT.target(e); current = VERTEX; } break; } // assert(0); return h; // compiler warning } Object_handle walk_in_triangulation(const Point& p) const; enum object_kind { VERTEX, EDGE_CROSSING, EDGE_COLLINEAR };}; // PM_point_locator<PM_decorator_,Geometry_>#ifdef CGAL_USING_PPLstatic const char* const pointlocationversion ="point location via pers dicts";#elsestatic const char* const pointlocationversion ="point location via seg walks";#endiftemplate <typename PMD, typename GEO>PM_point_locator<PMD,GEO>::PM_point_locator(const Plane_map& P, const Geometry& k) : Base(P,k), CT(*(new Plane_map),k){ CGAL_NEF_TRACEN("PM_point_locator construction"); CT.clone_skeleton(P,CT_link_to_original(CT,*this)); triangulate_CT(); minimize_weight_CT(); #ifdef CGAL_USING_PPL pPPL = new PMPP_locator(CT,PMPPLT(K)); #endif}template <typename PMD, typename GEO>PM_point_locator<PMD,GEO>::~PM_point_locator(){ CGAL_NEF_TRACEN("clear_static_point_locator"); Vertex_iterator vit, vend = CT.vertices_end(); for (vit = CT.vertices_begin(); vit != vend; ++vit) { geninfo<VF_pair>::clear(CT.info(vit)); } Halfedge_iterator eit, eend = CT.halfedges_end(); for (eit = CT.halfedges_begin(); eit != eend; ++eit) { geninfo<EF_pair>::clear(CT.info(eit)); } CT.clear(); delete &(CT.plane_map()); #ifdef CGAL_USING_PPL delete pPPL; pPPL=0; #endif}template <typename PMD, typename GEO>typename PM_point_locator<PMD,GEO>::Object_handle PM_point_locator<PMD,GEO>::walk_in_triangulation(const Point& q) const{ CGAL_NEF_TRACEN("walk in triangulation "<<q); Vertex_const_handle v = CT.vertices_begin(); Halfedge_const_handle e; Point p = CT.point(v); if ( p == q ) return Object_handle(v); // Segment s = this->K.construct_segment(p,q); Direction dir = this->K.construct_direction(p,q); object_kind current = VERTEX; while (true) switch ( current ) { case VERTEX: { CGAL_NEF_TRACEN("vertex "<<CT.point(v)); if ( CT.point(v) == q ) return Object_handle(v); // stop walking at q bool collinear; Halfedge_const_handle e_out = CT.out_wedge(v,dir,collinear); if (collinear) // ray shoot via e_out { e = e_out; current = EDGE_COLLINEAR; } else // ray shoot in wedge left of e_out { e = CT.twin(CT.next(e_out)); current = EDGE_CROSSING; } } break; case EDGE_CROSSING: { CGAL_NEF_TRACEN("crossing edge "<<CT.segment(e)); if ( !(this->K.orientation(CT.segment(e),q) > 0) ) // q not left of e return Object_handle(e); Vertex_const_handle v_cand = CT.target(CT.next(e)); int orientation_ = this->K.orientation(p,q,CT.point(v_cand)); switch( orientation_ ) { case 0: // collinear if ( this->K.strictly_ordered_along_line(p,q,CT.point(v_cand)) ) return Object_handle(e); v = v_cand; current = VERTEX; break; case +1: // left_turn e = twin(next(e)); current = EDGE_CROSSING; break; case -1: e = twin(previous(e)); current = EDGE_CROSSING; break; } } break; case EDGE_COLLINEAR: { CGAL_NEF_TRACEN("collinear edge "<<CT.segment(e)); if ( this->K.strictly_ordered_along_line( CT.point(CT.source(e)),q,CT.point(CT.target(e))) ) return Object_handle(e); v = CT.target(e); current = VERTEX; } break; }#if !defined(__BORLANDC__) return Object_handle(); // never reached warning acceptable#endif}CGAL_END_NAMESPACE#endif // CGAL_PM_POINT_LOCATOR_H
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?