BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Constrained_triangulation_2.h
Go to the documentation of this file.
00001 // Copyright (c) 1997  INRIA Sophia-Antipolis (France).
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/Triangulation_2/include/CGAL/Constrained_triangulation_2.h $
00015 // $Id: Constrained_triangulation_2.h 48844 2009-04-21 18:28:04Z spion $
00016 // 
00017 //
00018 // Author(s)     : Mariette Yvinec, Jean-Daniel Boissonnat
00019 
00020 
00021 #ifndef CGAL_CONSTRAINED_TRIANGULATION_2_H
00022 #define CGAL_CONSTRAINED_TRIANGULATION_2_H
00023 
00024 #include <set>
00025 
00026 #include <CGAL/triangulation_assertions.h>
00027 #include <CGAL/Triangulation_2.h> 
00028 #include <CGAL/Constrained_triangulation_face_base_2.h>
00029 #include <CGAL/iterator.h>
00030 
00031 #include <CGAL/intersections.h>
00032 #include <CGAL/squared_distance_2.h>
00033 
00034 CGAL_BEGIN_NAMESPACE
00035 
00036 struct No_intersection_tag{};
00037 struct Exact_intersections_tag{}; // to be used with an exact number type
00038 struct Exact_predicates_tag{}; // to be used with filtered exact number
00039 
00040 
00041 template < class Gt, 
00042            class Tds = Triangulation_data_structure_2 <
00043                        Triangulation_vertex_base_2<Gt>,
00044                        Constrained_triangulation_face_base_2<Gt> >, 
00045            class Itag = No_intersection_tag >
00046 class Constrained_triangulation_2  : public Triangulation_2<Gt,Tds>
00047 {
00048 
00049 public:
00050   typedef Triangulation_2<Gt,Tds> Triangulation;
00051   typedef Constrained_triangulation_2<Gt,Tds,Itag>  Constrained_triangulation;
00052   
00053   typedef typename Triangulation::Edge Edge;
00054   typedef typename Triangulation::Vertex Vertex;
00055   typedef typename Triangulation::Vertex_handle Vertex_handle;
00056   typedef typename Triangulation::Face_handle Face_handle;
00057   typedef typename Triangulation::Locate_type Locate_type;
00058   typedef typename Triangulation::All_faces_iterator All_faces_iterator;
00059   typedef typename Triangulation::Face_circulator Face_circulator;
00060   typedef typename Triangulation::Edge_circulator Edge_circulator;
00061   typedef typename Triangulation::Vertex_circulator Vertex_circulator;
00062   typedef typename Triangulation::Line_face_circulator Line_face_circulator;
00063 
00064 #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
00065   using Triangulation::number_of_vertices;
00066   using Triangulation::cw;
00067   using Triangulation::ccw;
00068   using Triangulation::dimension;
00069   using Triangulation::geom_traits;
00070   using Triangulation::all_faces_begin;
00071   using Triangulation::all_faces_end;
00072   using Triangulation::side_of_oriented_circle;
00073 #endif
00074 
00075   typedef Gt                                 Geom_traits;
00076   typedef Itag                               Intersection_tag;
00077   typedef typename Geom_traits::Point_2      Point;
00078   typedef typename Geom_traits::Segment_2    Segment;
00079   typedef std::pair<Point,Point>             Constraint;
00080   typedef std::list<Edge>                    List_edges;
00081   typedef std::list<Face_handle>             List_faces;
00082   typedef std::list<Vertex_handle>           List_vertices;
00083   typedef std::list<Constraint>              List_constraints;
00084 
00085   // Tag to mark the presence of a hierarchy of constraints
00086  typedef Tag_false                           Constraint_hierarchy_tag;
00087    
00088 
00089   class Less_edge;
00090   typedef std::set<Edge,Less_edge> Edge_set;
00091 
00092 
00093   Constrained_triangulation_2(const Gt& gt = Gt()) : Triangulation(gt) { }
00094 
00095   Constrained_triangulation_2(const Constrained_triangulation_2& ct)
00096     : Triangulation(ct) {}
00097 
00098   Constrained_triangulation_2(std::list<Constraint>& lc, const Gt& gt=Gt())
00099       : Triangulation_2<Gt,Tds>(gt)
00100   {
00101     typename List_constraints::iterator lcit=lc.begin();
00102     for( ;lcit != lc.end(); lcit++) {
00103       insert( (*lcit).first, (*lcit).second);
00104     }
00105      CGAL_triangulation_postcondition( this->is_valid() );
00106   }
00107 
00108   template<class InputIterator>
00109   Constrained_triangulation_2(InputIterator it,
00110                               InputIterator last,
00111                               const Gt& gt=Gt() )
00112      : Triangulation_2<Gt,Tds>(gt)
00113   {
00114     for ( ; it != last; it++) {
00115         insert_constraint((*it).first, (*it).second);
00116       }
00117       CGAL_triangulation_postcondition( this->is_valid() );
00118   }
00119 
00120   //TODO Is that destructor correct ?
00121   virtual ~Constrained_triangulation_2() {}
00122 
00123   // INSERTION
00124   Vertex_handle insert(const Point& p, 
00125                                Face_handle start = Face_handle() );
00126   Vertex_handle insert(const Point& p,
00127                        Locate_type lt,
00128                        Face_handle loc, 
00129                        int li );
00130   Vertex_handle push_back(const Point& a);
00131 //   template < class InputIterator >
00132 //   int insert(InputIterator first, InputIterator last);
00133  
00134   void insert_constraint(const Point& a, const Point& b);
00135   void insert_constraint(Vertex_handle va, Vertex_handle  vb);
00136   void push_back(const Constraint& c);
00137 
00138   void remove(Vertex_handle  v);
00139   void remove_constrained_edge(Face_handle f, int i);
00140   void remove_incident_constraints(Vertex_handle  v);
00141   // to be used by Constrained_triangulation_plus_2
00142  template <class OutputItFaces>
00143  OutputItFaces 
00144  remove_constrained_edge(Face_handle f, int i, OutputItFaces out) 
00145  {
00146    remove_constrained_edge(f, i);
00147    return out;
00148  }
00149 
00150   //for backward compatibility
00151   void remove_constraint(Face_handle f, int i) {remove_constrained_edge(f,i);}
00152   void insert(Point a, Point b) { insert_constraint(a, b);}
00153   void insert(Vertex_handle va, Vertex_handle  vb) {insert_constraint(va,vb);}
00154 
00155   // QUERY
00156   bool is_constrained(Edge e) const;
00157   bool are_there_incident_constraints(Vertex_handle v) const;
00158   bool is_valid(bool verbose = false, int level = 0) const;
00159   // template<class OutputItEdges>
00160   // OutputItEdges incident_constraints(Vertex_handle v, 
00161   //                                     OutputItEdges out) const;
00162   
00163 
00164   class Less_edge 
00165     :  public std::binary_function<Edge, Edge, bool>
00166   {
00167   public:
00168     Less_edge() {}
00169     bool operator() (const Edge& e1, const Edge& e2) const
00170       {
00171         int ind1=e1.second, ind2=e2.second;
00172         return( (&(*e1.first) < &(*e2.first))
00173                 || ( (&(*e1.first) == &(*e2.first)) && (ind1 < ind2)));
00174       } 
00175   };
00176 
00177 
00178   void file_output(std::ostream& os) const;
00179 
00180 protected:
00181   virtual Vertex_handle virtual_insert(const Point& a, 
00182                                        Face_handle start = Face_handle());
00183   virtual Vertex_handle virtual_insert(const Point& a,
00184                                        Locate_type lt,
00185                                        Face_handle loc, 
00186                                        int li );
00187 //Vertex_handle special_insert_in_edge(const Point & a, Face_handle f, int i);
00188   void update_constraints_incident(Vertex_handle va, 
00189                                    Vertex_handle c1,
00190                                    Vertex_handle c2);
00191   void clear_constraints_incident(Vertex_handle va);
00192   void update_constraints_opposite(Vertex_handle va);
00193   void update_constraints(const List_edges &hole);
00194 
00195   void mark_constraint(Face_handle fr, int i);
00196 
00197   virtual Vertex_handle intersect(Face_handle f, int i, 
00198                           Vertex_handle vaa,
00199                           Vertex_handle vbb);
00200   Vertex_handle intersect(Face_handle f, int i, 
00201                           Vertex_handle vaa,
00202                           Vertex_handle vbb,
00203                           No_intersection_tag);
00204   Vertex_handle intersect(Face_handle f, int i, 
00205                           Vertex_handle vaa,
00206                           Vertex_handle vbb,
00207                            Exact_intersections_tag);
00208   Vertex_handle intersect(Face_handle f, int i, 
00209                           Vertex_handle vaa,
00210                           Vertex_handle vbb,
00211                           Exact_predicates_tag);
00212 public:
00213 // made public for Laurent  to find out deleted faces
00214 // when inserting a constraint with most probably 
00215 // no intersection
00216   bool find_intersected_faces(Vertex_handle va, 
00217                               Vertex_handle vb,
00218                               List_faces & intersected_faces,
00219                               List_edges & list_ab, 
00220                               List_edges & list_ba,
00221                               Vertex_handle& vi);
00222 protected:
00223   virtual void triangulate_hole(List_faces& intersected_faces,
00224                                 List_edges& conflict_boundary_ab,
00225                                 List_edges& conflict_boundary_ba);
00226   
00227   void triangulate_hole(List_faces& intersected_faces,
00228                         List_edges& conflict_boundary_ab,
00229                         List_edges& conflict_boundary_ba,
00230                         List_edges& new_edges);
00231   
00232   void triangulate_half_hole(List_edges & list_edges, 
00233                              List_edges & new_edges);
00234 
00235   void remove_1D(Vertex_handle v);
00236   void remove_2D(Vertex_handle v);
00237 
00238   //templated member function
00239 public:
00240   // the int parameter is a work around for VC7 to compile
00241   template < class InputIterator >
00242 #if defined(_MSC_VER)
00243    int insert(InputIterator first, InputIterator last, int i = 0)
00244 #else
00245    int insert(InputIterator first, InputIterator last) 
00246 #endif
00247     {
00248       int n = number_of_vertices(); 
00249 
00250       std::vector<Point> points (first, last);
00251       std::random_shuffle (points.begin(), points.end());
00252       CGAL::spatial_sort (points.begin(), points.end(), geom_traits());
00253 
00254       Face_handle hint;
00255       for (typename std::vector<Point>::const_iterator p = points.begin(), end = points.end();
00256               p != end; ++p)
00257           hint = insert (*p, hint)->face();
00258 
00259       return number_of_vertices() - n;
00260     }
00261 
00262   //deprecated
00263  template<class OutputIterator>
00264   bool are_there_incident_constraints(Vertex_handle v, 
00265                                       OutputIterator out) const
00266     {
00267       Edge_circulator ec=incident_edges(v), done(ec);
00268       bool are_there = false;
00269       if (ec == 0) return are_there;
00270       do {
00271         if(is_constrained(*ec)) {
00272           *out++ = *ec;
00273           are_there = true;
00274         }
00275         ec++;
00276       } while (ec != done);
00277       return are_there;
00278     }
00279 
00280   
00281  template<class OutputItEdges>
00282  OutputItEdges  incident_constraints(Vertex_handle v, 
00283                                       OutputItEdges out) const {
00284    Edge_circulator ec=incident_edges(v), done(ec);
00285    if (ec == 0) return  out;
00286    do {
00287      if(is_constrained(*ec))    *out++ = *ec;
00288      ec++;
00289    } while (ec != done);
00290    return out;
00291  }
00292  
00293   // the following fonctions are overloaded 
00294   // to take care of constraint marks 
00295   template<class EdgeIt>
00296   Vertex_handle star_hole( const Point& p, 
00297                            EdgeIt edge_begin,  
00298                            EdgeIt edge_end) {
00299     std::list<Face_handle> empty_list;
00300     return star_hole(p, 
00301                      edge_begin, 
00302                      edge_end, 
00303                      empty_list.begin(),
00304                      empty_list.end());
00305   }
00306 
00307   template<class EdgeIt, class FaceIt>
00308   Vertex_handle star_hole( const Point& p, 
00309                            EdgeIt edge_begin,
00310                            EdgeIt edge_end,
00311                            FaceIt face_begin,
00312                            FaceIt face_end)
00313 {
00314     Vertex_handle v =  Triangulation::star_hole(p, 
00315                                                 edge_begin, 
00316                                                 edge_end, 
00317                                                 face_begin,
00318                                                 face_end);
00319     // restore constraint status for new faces.
00320     int vindex;
00321     Face_handle fh;
00322     int ih;
00323     Face_circulator fc = incident_faces(v), done(fc);
00324     do {
00325       vindex = fc->index(v);
00326       fc->set_constraint(cw(vindex), false);
00327       fc->set_constraint(ccw(vindex), false);
00328       fh = fc->neighbor(vindex);
00329       ih = this->mirror_index(fc,vindex);
00330       fc->set_constraint(vindex, fh->is_constrained(ih));
00331     } while (++fc != done);
00332     return v;
00333 }
00334  
00335 };
00336 
00337 template < class Gt, class Tds, class Itag >
00338 inline
00339 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle
00340 Constrained_triangulation_2<Gt,Tds,Itag>::
00341 virtual_insert(const Point& a, Face_handle start)
00342 // virtual version of insert
00343 {
00344   return insert(a,start);
00345 }
00346 
00347 template < class Gt, class Tds, class Itag >
00348 inline
00349 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle
00350 Constrained_triangulation_2<Gt,Tds,Itag>::
00351 virtual_insert(const Point& a,
00352                Locate_type lt,
00353                Face_handle loc, 
00354                int li )
00355 // virtual version of insert
00356 {
00357   return insert(a,lt,loc,li);
00358 }
00359     
00360 template < class Gt, class Tds, class Itag >
00361 inline
00362 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle
00363 Constrained_triangulation_2<Gt,Tds,Itag>::
00364 insert(const Point& a, Face_handle start)
00365 // inserts point a 
00366 // in addition to what is done for non constrained triangulations
00367 // constrained edges are updated
00368 {
00369   Face_handle loc;
00370   int li;
00371   Locate_type lt;
00372   loc = locate(a, lt, li, start);
00373   return Constrained_triangulation::insert(a,lt,loc,li);
00374 }
00375 
00376 template < class Gt, class Tds, class Itag >
00377 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle
00378 Constrained_triangulation_2<Gt,Tds,Itag>::
00379 insert(const Point& a, Locate_type lt, Face_handle loc, int li)
00380 // insert a point p, whose localisation is known (lt, f, i)
00381 // in addition to what is done for non constrained triangulations
00382 // constrained edges are updated
00383 {
00384   Vertex_handle va;
00385   Vertex_handle v1, v2;
00386   bool insert_in_constrained_edge = false;
00387 
00388   if ( lt == Triangulation::EDGE && loc->is_constrained(li) ){
00389     insert_in_constrained_edge = true;
00390     v1=loc->vertex(ccw(li)); //endpoint of the constraint
00391     v2=loc->vertex(cw(li)); // endpoint of the constraint
00392   }
00393 
00394   va = Triangulation::insert(a,lt,loc,li);
00395   if (insert_in_constrained_edge) update_constraints_incident(va, v1,v2);
00396   else if(lt != Triangulation::VERTEX) clear_constraints_incident(va);
00397   if (dimension() == 2) update_constraints_opposite(va);
00398   return va;
00399 }
00400 
00401 // template < class Gt, class Tds, class Itag >  
00402 // typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle 
00403 // Constrained_triangulation_2<Gt, Tds, Itag>::
00404 // special_insert_in_edge(const Point & a, Face_handle f, int i)
00405 //   // insert  point p in edge(f,i)
00406 //   // bypass the precondition for point a to be in edge(f,i)
00407 //   // update constrained status
00408 // {
00409 //   Vertex_handle va;
00410 //   Vertex_handle c1,c2;
00411 //   c1 = f->vertex(cw(i));  //endpoint of edge
00412 //   c2 = f->vertex(ccw(i)); //endpoint of edge
00413 //   bool insert_in_constrained_edge = f->is_constrained(i);
00414  
00415 //   va = this->_tds.insert_in_edge(f, i);
00416 //   va->set_point(a);
00417 
00418 //   if (insert_in_constrained_edge) update_constraints_incident(va, c1,c2);
00419 //   else clear_constraints_incident(va);
00420 //   if (dimension() == 2) update_constraints_opposite(va);
00421 //   return va;
00422 // }
00423 
00424 
00425 template < class Gt, class Tds, class Itag >
00426 inline void
00427 Constrained_triangulation_2<Gt,Tds,Itag>::
00428 insert_constraint(const Point& a, const Point& b)
00429 // the algorithm first inserts a and b, 
00430 // and then forces the constraint [va,vb]
00431 {
00432   Vertex_handle va= virtual_insert(a);
00433   Vertex_handle vb= virtual_insert(b);
00434   if ( va != vb)   insert_constraint(va,vb);
00435 }
00436 
00437 
00438 
00439 template <class Gt, class Tds, class Itag >
00440 inline void
00441 Constrained_triangulation_2<Gt,Tds,Itag>::
00442 insert_constraint(Vertex_handle  vaa, Vertex_handle vbb)
00443 // forces the constrained [va,vb]
00444 // [va,vb] will eventually be splitted into several edges
00445 // if a vertex vc of t lies on segment ab
00446 // of if ab intersect some constrained edges
00447 {
00448   CGAL_triangulation_precondition( vaa != vbb);
00449   Vertex_handle vi;
00450 
00451   Face_handle fr;
00452   int i;
00453   if(includes_edge(vaa,vbb,vi,fr,i)) {
00454     mark_constraint(fr,i);
00455     if (vi != vbb)  {
00456       insert_constraint(vi,vbb);
00457     }
00458     return;
00459   }
00460 
00461   List_faces intersected_faces;
00462   List_edges conflict_boundary_ab, conflict_boundary_ba;
00463   bool intersection  = find_intersected_faces( vaa, vbb,
00464                                                intersected_faces,
00465                                                conflict_boundary_ab,
00466                                                conflict_boundary_ba,
00467                                                vi);
00468   if ( intersection) {
00469     if (vi != vaa && vi != vbb) {
00470       insert_constraint(vaa,vi); 
00471       insert_constraint(vi,vbb); 
00472      }
00473     else insert_constraint(vaa,vbb);
00474     return;
00475   }
00476 
00477   triangulate_hole(intersected_faces,
00478                    conflict_boundary_ab,
00479                    conflict_boundary_ba);
00480 
00481   if (vi != vbb) {
00482     insert_constraint(vi,vbb); 
00483   }
00484   return;
00485 
00486 }
00487 
00488 template <class Gt, class Tds, class Itag >
00489 bool
00490 Constrained_triangulation_2<Gt,Tds,Itag>::
00491 find_intersected_faces(Vertex_handle vaa,
00492                        Vertex_handle vbb,
00493                        List_faces & intersected_faces,
00494                        List_edges & list_ab, 
00495                        List_edges & list_ba,
00496                        Vertex_handle & vi) 
00497   // vi is set to the first vertex of the triangulation on [vaa,vbb].
00498   // Return true if an intersection with a constrained edge is
00499   // encountered, false otherwise
00500   // When false : 
00501   // intersected_faces contains the list if faces intersected by [va,vi]
00502   // list_ab and list_ba represents the boundary of the union
00503   // of the intersected faces oriented cw
00504   // list_ab consists of the edges from vaa to vi (i.e. on the left of a->b)
00505   // list_ba    "         "        from vi to vaa (i.e. on the right of a->b)
00506 {
00507   const Point& aa = vaa->point();
00508   const Point& bb = vbb->point();
00509   Line_face_circulator current_face=Line_face_circulator(vaa, this, bb);
00510   int ind=current_face->index(vaa);
00511       
00512   // to deal with the case where the first crossed edge
00513   // is constrained
00514   if(current_face->is_constrained(ind)) {
00515     vi=intersect(current_face, ind, vaa, vbb);
00516     return true;
00517   }
00518 
00519   Face_handle lf= current_face->neighbor(ccw(ind)); 
00520   Face_handle rf= current_face->neighbor(cw(ind));
00521   Orientation orient;
00522   Face_handle previous_face;
00523   Vertex_handle current_vertex; 
00524 
00525   list_ab.push_back(Edge(lf, lf->index(current_face)));
00526   list_ba.push_front(Edge(rf, rf->index(current_face)));
00527   intersected_faces.push_front(current_face);
00528 
00529   // initcd
00530   previous_face=current_face; 
00531   ++current_face;
00532   ind=current_face->index(previous_face);  
00533   current_vertex=current_face->vertex(ind);  
00534 
00535   // loop over triangles intersected by ab
00536   bool done = false;
00537   while (current_vertex != vbb && !done)  { 
00538     orient = this->orientation(aa,bb,current_vertex->point());
00539     int i1, i2;
00540     switch (orient) {
00541     case COLLINEAR :  
00542       done = true; // current_vertex is the new endpoint
00543       break;
00544     case LEFT_TURN :
00545     case RIGHT_TURN :
00546       if (orient == LEFT_TURN) {
00547         i1 = ccw(ind) ; //index of second intersected edge of current_face
00548         i2 = cw(ind); //index of non intersected edge of current_face
00549       }
00550       else {
00551         i1 = cw(ind) ; //index of second intersected edge of current_face
00552         i2 = ccw(ind); //index of non intersected edge of current_face
00553       }
00554       if(current_face->is_constrained(i1)) {
00555         vi = intersect(current_face, i1, vaa,vbb);
00556         return true;
00557       }
00558       else {
00559         lf= current_face->neighbor(i2);
00560         intersected_faces.push_front(current_face);
00561         if (orient == LEFT_TURN) 
00562           list_ab.push_back(Edge(lf, lf->index(current_face)));
00563         else // orient == RIGHT_TURN
00564           list_ba.push_front(Edge(lf, lf->index(current_face)));
00565         previous_face=current_face;
00566         ++current_face;
00567         ind=current_face->index(previous_face); 
00568         current_vertex=current_face->vertex(ind);
00569       }
00570       break;
00571     }
00572   }
00573     
00574   // last triangle 
00575   vi = current_vertex;
00576   intersected_faces.push_front(current_face);
00577   lf= current_face->neighbor(cw(ind));
00578   list_ab.push_back(Edge(lf, lf->index(current_face))); 
00579   rf= current_face->neighbor(ccw(ind));
00580   list_ba.push_front(Edge(rf, rf->index(current_face)));
00581   return false;
00582 }
00583 
00584 
00585 template <class Gt, class Tds, class Itag >
00586 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle 
00587 Constrained_triangulation_2<Gt,Tds,Itag>::
00588 intersect(Face_handle f, int i, 
00589           Vertex_handle vaa,
00590           Vertex_handle vbb) 
00591 {
00592   return intersect(f, i, vaa, vbb, Itag());
00593 }
00594 
00595 template <class Gt, class Tds, class Itag >
00596 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle 
00597 Constrained_triangulation_2<Gt,Tds,Itag>::
00598 intersect(Face_handle , int , 
00599           Vertex_handle ,
00600           Vertex_handle ,
00601           No_intersection_tag)
00602 {
00603   std::cerr << " sorry, this triangulation does not deal with" 
00604             <<    std::endl
00605             << " intersecting constraints" << std::endl;
00606   CGAL_triangulation_assertion(false);
00607   return Vertex_handle() ;
00608 }
00609 
00610 template <class Gt, class Tds, class Itag >
00611 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle 
00612 Constrained_triangulation_2<Gt,Tds,Itag>::
00613 intersect(Face_handle f, int i, 
00614           Vertex_handle vaa,
00615           Vertex_handle vbb,
00616           Exact_intersections_tag)
00617 // compute the intersection of the constraint edge (f,i) 
00618 // with the subconstraint (vaa,vbb) being inserted
00619 // insert the intersection point
00620 // split constraint edge (f,i) 
00621 // and return the Vertex_handle of the new Vertex
00622 { 
00623   std::cerr << "You are using an exact number types" << std::endl;
00624   std::cerr << "using a Constrained_triangulation_plus_2 class" << std::endl;
00625   std::cerr << "would avoid cascading intersection computation" << std::endl;
00626   std::cerr << " and be much more efficient" << std::endl;
00627   const Point& pa = vaa->point();
00628   const Point& pb = vbb->point();
00629   const Point& pc = f->vertex(cw(i))->point();
00630   const Point& pd = f->vertex(ccw(i))->point();
00631   Point pi;
00632   Itag itag = Itag();
00633   CGAL_triangulation_assertion_code( bool ok = )
00634   intersection(geom_traits(), pa, pb, pc, pd, pi, itag );
00635   CGAL_triangulation_assertion(ok);
00636   Vertex_handle vi = virtual_insert(pi, Triangulation::EDGE, f, i);
00637   return vi; 
00638 }
00639 
00640 template <class Gt, class Tds, class Itag >
00641 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle 
00642 Constrained_triangulation_2<Gt,Tds,Itag>::
00643 intersect(Face_handle f, int i, 
00644           Vertex_handle vaa,
00645           Vertex_handle vbb,
00646           Exact_predicates_tag)
00647 {
00648   Vertex_handle  vcc, vdd;
00649   vcc = f->vertex(cw(i));
00650   vdd = f->vertex(ccw(i));
00651 
00652   const Point& pa = vaa->point();
00653   const Point& pb = vbb->point();
00654   const Point& pc = vcc->point();
00655   const Point& pd = vdd->point();
00656 
00657   Point pi; //creator for point is required here
00658   Itag itag = Itag();
00659   bool ok  = intersection(geom_traits(), pa, pb, pc, pd, pi, itag );
00660 
00661   Vertex_handle vi;
00662   if ( !ok) {  //intersection detected but not computed
00663     int i = limit_intersection(geom_traits(), pa, pb, pc, pd, itag);
00664     switch(i){
00665     case 0 : vi = vaa; break;
00666     case 1 : vi = vbb; break;
00667     case 2 : vi = vcc; break;
00668     case 3 : vi = vdd; break; 
00669     }
00670   }
00671   else{ //intersection computed
00672     remove_constrained_edge(f, i);
00673     vi = virtual_insert(pi, f);
00674   }
00675 
00676   // vi == vc or vi == vd may happen even if intersection==true
00677   // due to approximate construction of the intersection
00678   if (vi != vcc && vi != vdd) { 
00679     insert_constraint(vcc,vi); 
00680     insert_constraint(vi, vdd);
00681   } 
00682   else {
00683     insert_constraint(vcc,vdd);
00684   }
00685   return vi; 
00686 }
00687 
00688 template <class Gt, class Tds, class Itag >
00689 inline
00690 typename Constrained_triangulation_2<Gt,Tds,Itag>::Vertex_handle
00691 Constrained_triangulation_2<Gt,Tds,Itag>::
00692 push_back(const Point &p)
00693 {
00694   return insert(p);
00695 }
00696 
00697 
00698 template <class Gt, class Tds, class Itag >
00699 inline
00700 void
00701 Constrained_triangulation_2<Gt,Tds,Itag>::
00702 push_back(const Constraint &c)
00703 {
00704   insert(c.first, c.second);
00705 }
00706 
00707 
00708 template < class Gt, class Tds, class Itag >
00709 void
00710 Constrained_triangulation_2<Gt,Tds,Itag>::
00711 update_constraints_incident(Vertex_handle va, 
00712                             Vertex_handle c1,
00713                             Vertex_handle c2)
00714   // update status of edges incident to a 
00715   // after insertion in the  constrained edge c1c2
00716 {
00717   if (dimension() == 0) return;
00718   if (dimension()== 1) {
00719     Edge_circulator ec=this->incident_edges(va), done(ec);
00720     do {
00721       ((*ec).first)->set_constraint(2,true);
00722     }while (++ec != done);
00723   }
00724   else{
00725     //dimension() ==2
00726     int cwi, ccwi, indf;
00727     Face_circulator fc=this->incident_faces(va), done(fc);  
00728     CGAL_triangulation_assertion(fc != 0);
00729     do {
00730       indf = fc->index(va);
00731       cwi=cw(indf);
00732       ccwi=ccw(indf); 
00733       if ((fc->vertex(cwi) == c1)||(fc->vertex(cwi) == c2)) {
00734           fc->set_constraint(ccwi,true);
00735           fc->set_constraint(cwi,false);
00736         }       
00737         else {
00738           fc->set_constraint(ccwi,false);
00739           fc->set_constraint(cwi,true);
00740         }
00741         ++fc;
00742       } while (fc != done);
00743   }
00744 }
00745 
00746 template < class Gt, class Tds ,class Itag >
00747 void
00748 Constrained_triangulation_2<Gt,Tds,Itag>::
00749 clear_constraints_incident(Vertex_handle va)
00750 // make the edges incident to a newly created vertex unconstrained
00751 {
00752  Edge_circulator ec=this->incident_edges(va), done(ec);
00753  Face_handle f;
00754  int indf;
00755   if ( ec != 0){
00756     do {
00757       f = (*ec).first ;
00758       indf = (*ec).second;
00759       f->set_constraint(indf,false);
00760       if (dimension() == 2) {
00761         f->neighbor(indf)->set_constraint(this->mirror_index(f,indf),false);
00762       }
00763     } while (++ec != done);
00764   }
00765   return;
00766 }
00767 
00768 
00769 template < class Gt, class Tds, class Itag >
00770 void
00771 Constrained_triangulation_2<Gt,Tds,Itag>::  
00772 update_constraints_opposite(Vertex_handle va)
00773   // update status of edges opposite to a
00774   // after insertion of a
00775 {
00776   CGAL_triangulation_assertion(dimension()==2); 
00777   Face_handle f=va->face(), start=f;
00778   int indf;
00779   do {
00780     indf = f->index(va);
00781     if (f->neighbor(indf)->is_constrained(this->mirror_index(f,indf)) ) {
00782       f->set_constraint(indf,true);
00783     }
00784     else {
00785       f->set_constraint(indf,false);
00786     }
00787     f= f->neighbor(ccw(indf)); // turns ccw around va 
00788   } while (f != start);
00789   return;
00790 }
00791 
00792 template < class Gt, class Tds, class Itag >
00793 void
00794 Constrained_triangulation_2<Gt,Tds,Itag>:: 
00795 update_constraints( const List_edges &hole)
00796 {
00797   typename List_edges::const_iterator it = hole.begin();
00798   Face_handle f;
00799   int i;
00800   for ( ; it != hole.end(); it ++) {
00801     f =(*it).first;
00802     i = (*it).second;
00803     if ( f->is_constrained(i) ) 
00804       (f->neighbor(i))->set_constraint(this->mirror_index(f,i),true);
00805     else (f->neighbor(i))->set_constraint(this->mirror_index(f,i),false);
00806   }
00807 }
00808 
00809 
00810 template < class Gt, class Tds, class Itag >
00811 inline void
00812 Constrained_triangulation_2<Gt,Tds,Itag>::
00813 mark_constraint(Face_handle fr, int i)
00814 {
00815   if (dimension()==1) fr->set_constraint(2, true);
00816   else{
00817     fr->set_constraint(i,true);
00818     fr->neighbor(i)->set_constraint(this->mirror_index(fr,i),true);
00819   }
00820   return;
00821 }
00822 
00823 template < class Gt, class Tds, class Itag >
00824 inline void
00825 Constrained_triangulation_2<Gt,Tds,Itag>::
00826 triangulate_hole(List_faces& intersected_faces,
00827                  List_edges& conflict_boundary_ab,
00828                  List_edges& conflict_boundary_ba)
00829 {
00830   List_edges new_edges;
00831   triangulate_hole(intersected_faces,
00832                    conflict_boundary_ab,
00833                    conflict_boundary_ba,
00834                    new_edges);
00835 }
00836 
00837 
00838 
00839 template < class Gt, class Tds, class Itag >
00840 void
00841 Constrained_triangulation_2<Gt,Tds,Itag>::
00842 triangulate_hole(List_faces& intersected_faces,
00843                  List_edges& conflict_boundary_ab,
00844                  List_edges& conflict_boundary_ba,
00845                  List_edges& new_edges)
00846   // triangulate the hole limited by conflict_boundary_ab
00847   // and conflict_boundary_ba
00848   // insert the new edges in new-edges 
00849   // delete the faces of intersected_faces
00850 {
00851   if ( !conflict_boundary_ab.empty() ) {
00852     triangulate_half_hole(conflict_boundary_ab, new_edges);
00853     triangulate_half_hole(conflict_boundary_ba, new_edges);
00854         
00855     // the two faces that share edge ab are neighbors
00856     // their common edge ab is a constraint
00857     Face_handle fr,fl;
00858     fl=(*conflict_boundary_ab.begin()).first;
00859     fr=(*conflict_boundary_ba.begin()).first;
00860     fl->set_neighbor(2, fr);
00861     fr->set_neighbor(2, fl);
00862     fl->set_constraint(2, true);
00863     fr->set_constraint(2, true);
00864    
00865     // delete intersected faces
00866     while( ! intersected_faces.empty()) {
00867       fl = intersected_faces.front();
00868       intersected_faces.pop_front();
00869       delete_face(fl);
00870     }
00871   }
00872 }
00873 
00874 
00875 
00876 template < class Gt, class Tds, class Itag >
00877 void
00878 Constrained_triangulation_2<Gt,Tds,Itag>::
00879 remove(Vertex_handle  v)
00880   // remove a vertex and updates the constrained edges of the new faces
00881   // precondition : there is no incident constraints
00882 {
00883   CGAL_triangulation_precondition( v != Vertex_handle() );
00884   CGAL_triangulation_precondition( ! is_infinite(v));
00885   CGAL_triangulation_precondition( ! are_there_incident_constraints(v));
00886     
00887   if  (number_of_vertices() == 1)     remove_first(v);
00888   else if (number_of_vertices() == 2) remove_second(v);
00889   else   if ( dimension() == 1) remove_1D(v);
00890   else  remove_2D(v);
00891   return;
00892 }
00893 
00894 
00895 template < class Gt, class Tds, class Itag >
00896 void
00897 Constrained_triangulation_2<Gt,Tds,Itag>::
00898 remove_1D(Vertex_handle  v)
00899 {
00900   Edge_circulator ec = incident_edges(v), done(ec);
00901   do {
00902     (*ec).first->set_constraint(2,false);
00903   } while (++ec != done);
00904   Triangulation::remove_1D(v);
00905 }
00906 
00907 template < class Gt, class Tds, class Itag >
00908 void
00909 Constrained_triangulation_2<Gt,Tds,Itag>::
00910 remove_2D(Vertex_handle v)
00911 {
00912   if (test_dim_down(v)) { this->_tds.remove_dim_down(v);}
00913   else {
00914     List_edges hole;
00915     make_hole(v, hole);
00916     List_edges shell=hole; //save hole because it will be emptied by fill_hole
00917     fill_hole(v, hole);
00918     update_constraints(shell);
00919     delete_vertex(v);
00920   }
00921   return;       
00922 }
00923 
00924 
00925 template < class Gt, class Tds, class Itag >
00926 void
00927 Constrained_triangulation_2<Gt,Tds,Itag>::
00928 remove_constrained_edge(Face_handle f, int i)
00929 {
00930   f->set_constraint(i, false);
00931   if (dimension() == 2)
00932     (f->neighbor(i))->set_constraint(this->mirror_index(f,i), false);
00933   return;
00934 }
00935 
00936 template < class Gt, class Tds, class Itag >
00937 void
00938 Constrained_triangulation_2<Gt,Tds,Itag>::
00939 remove_incident_constraints(Vertex_handle v)
00940 {
00941    Edge_circulator ec=incident_edges(v), done(ec);
00942    if (ec == 0) return;
00943    do {
00944         if(is_constrained(*ec)) { remove_constrained_edge((*ec).first,
00945                                                    (*ec).second);}
00946         ec++;
00947    } while (ec != done);
00948    return;      
00949 }
00950 
00951 template < class Gt, class Tds, class Itag >
00952 inline  bool 
00953 Constrained_triangulation_2<Gt,Tds,Itag>::
00954 are_there_incident_constraints(Vertex_handle v) const
00955 {
00956   return are_there_incident_constraints(v, Emptyset_iterator());
00957 }
00958 
00959 template < class Gt, class Tds, class Itag >
00960 inline  bool 
00961 Constrained_triangulation_2<Gt,Tds,Itag>::
00962 is_valid(bool verbose, int level) const
00963 {
00964     bool result = Triangulation::is_valid(verbose,level);
00965     for( All_faces_iterator it = all_faces_begin(); 
00966                             it != all_faces_end() ; it++) {
00967       for(int i=0; i<3; i++) {
00968         Face_handle n = it->neighbor(i);
00969         result = result && 
00970           it->is_constrained(i) == n->is_constrained(n->index(it));
00971       }
00972     }
00973     return result;
00974 }
00975 
00976 template < class Gt, class Tds, class Itag >
00977 inline  bool 
00978 Constrained_triangulation_2<Gt,Tds,Itag>::
00979 is_constrained(Edge e) const
00980 {
00981   return (e.first)->is_constrained(e.second);
00982 }
00983     
00984 template < class Gt, class Tds, class Itag >
00985 void
00986 Constrained_triangulation_2<Gt,Tds,Itag>::
00987 triangulate_half_hole(List_edges & list_edges,  List_edges & new_edges)
00988   // triangulates the  polygon whose boundary consists of list_edges
00989   // plus the edge ab joining the two endpoints of list_edges
00990   // the orientation of the polygon (as provided by list_edges) must
00991   // be cw
00992   // the edges of list_edges are assumed to be edges of a
00993   // triangulation that will be updated by the procedure
00994   // the edges that are created are put in list new_edges
00995   // takes linear time
00996 {
00997   Vertex_handle va,vb; // first and last vertices of list_edges 
00998   Face_handle newlf;
00999   Face_handle n1,n2,n;
01000   int ind1, ind2,ind;
01001   Orientation orient;
01002     
01003   typename List_edges::iterator current, next, tempo;
01004   current=list_edges.begin();
01005   tempo=list_edges.end(); 
01006   --tempo; 
01007 
01008   va=((*current).first)->vertex(ccw((*current).second));
01009   vb=((*tempo).first)->vertex(cw((*tempo).second));
01010   next=current; 
01011   ++next;
01012 
01013   do
01014     {
01015       n1=(*current).first;
01016       ind1=(*current).second;
01017       // in case n1 is no longer a triangle of the new triangulation
01018       if ( n1->neighbor(ind1) != Face_handle() ) {
01019         n=n1->neighbor(ind1);
01020         //ind=this->mirror_index(n1,ind1); 
01021         // mirror_index does not work in this case
01022         ind = cw(n->index(n1->vertex(cw(ind1))));
01023         n1=n->neighbor(ind); 
01024         ind1= this->mirror_index(n,ind);
01025       }
01026       n2=(*next).first;
01027       ind2=(*next).second;
01028       // in case n2 is no longer a triangle of the new triangulation
01029       if (n2->neighbor(ind2) != Face_handle() ) {
01030         n=n2->neighbor(ind2); 
01031         // ind=this->mirror_index(n2,ind2);
01032         // mirror_index does not work in this case
01033         ind = cw(n->index(n2->vertex(cw(ind2))));
01034         n2=n->neighbor(ind); 
01035         ind2= this->mirror_index(n,ind);
01036       }
01037 
01038       Vertex_handle v0=n1->vertex(ccw(ind1));
01039       Vertex_handle v1=n1->vertex(cw(ind1));
01040       Vertex_handle v2=n2->vertex(cw(ind2));
01041       orient = this->orientation(v0->point(),v1->point(),v2->point());
01042       switch (orient) {
01043       case RIGHT_TURN :                         
01044         // creates the new triangle v0v1v2
01045         // updates the neighbors, the constraints 
01046         //and the list of new edges
01047         newlf = create_face(v0,v2,v1);
01048         new_edges.push_back(Edge(newlf,2));
01049         newlf->set_neighbor(1, n1);
01050         newlf->set_neighbor(0, n2);
01051         n1->set_neighbor(ind1, newlf);
01052         n2->set_neighbor(ind2, newlf);
01053         if (n1->is_constrained(ind1)) {
01054           newlf->set_constraint(1,true);
01055         }
01056         if (n2->is_constrained(ind2)) {
01057           newlf->set_constraint(0,true);
01058         }
01059         // v0, v1 or v2.face() may have been removed
01060         v0->set_face(newlf); 
01061         v1->set_face(newlf);
01062         v2->set_face(newlf);
01063         // update list_edges
01064         tempo=current;
01065         current=list_edges.insert(current, Edge(newlf,2));
01066         list_edges.erase(tempo);
01067         list_edges.erase(next);
01068         next=current;
01069         if (v0 != va) {--current;} 
01070         else {++next;} 
01071         break;
01072       case LEFT_TURN :    
01073         ++current; ++next;
01074         break;
01075       case COLLINEAR : 
01076         ++current; ++next;
01077         break;
01078       }
01079     } while (list_edges.size()>1);
01080 }
01081 
01082 template < class Gt, class Tds, class Itag >
01083 void
01084 Constrained_triangulation_2<Gt, Tds, Itag>::
01085 file_output(std::ostream& os) const
01086 {
01087   Triangulation_2<Gt, Tds>::file_output(os);
01088 
01089   // write constrained status
01090   typename Tds::Face_iterator ib = this->_tds.face_iterator_base_begin();
01091   for( ; ib != this->_tds.face_iterator_base_end(); ++ib) {
01092     for(int j = 0; j < 3; ++j){
01093       if (ib->is_constrained(j)) { os << "C";}
01094       else { os << "N";}
01095       if(is_ascii(os)){
01096         if(j==2) {
01097           os << "\n";
01098         } else {
01099           os <<  ' ';
01100         }
01101       }
01102     }
01103   }
01104 }
01105 
01106 template < class Gt, class Tds, class Itag >
01107 std::ostream &
01108 operator<<(std::ostream& os, 
01109            const Constrained_triangulation_2<Gt,Tds,Itag> &ct)
01110 {
01111   ct.file_output(os);
01112   return os ;
01113 }
01114 
01115 //Helping functions to compute intersections of constrained edges
01116 template<class Gt>
01117 bool
01118 intersection(Gt ,
01119              const typename Gt::Point_2& , 
01120              const typename Gt::Point_2& , 
01121              const typename Gt::Point_2& , 
01122              const typename Gt::Point_2& ,
01123              typename Gt::Point_2& ,
01124              No_intersection_tag)
01125 {
01126   return false;
01127 }
01128              
01129 template<class Gt>
01130 bool
01131 intersection(Gt gt,
01132              const typename Gt::Point_2& pa, 
01133              const typename Gt::Point_2& pb, 
01134              const typename Gt::Point_2& pc, 
01135              const typename Gt::Point_2& pd,
01136              typename Gt::Point_2& pi,
01137              Exact_intersections_tag)
01138 {
01139   return compute_intersection(gt,pa,pb,pc,pd,pi);
01140 }
01141 
01142 
01143 template<class Gt>
01144 inline bool
01145 intersection(Gt gt,
01146              const typename Gt::Point_2& pa, 
01147              const typename Gt::Point_2& pb, 
01148              const typename Gt::Point_2& pc, 
01149              const typename Gt::Point_2& pd,
01150              typename Gt::Point_2& pi,
01151              Exact_predicates_tag)
01152 {
01153   return compute_intersection(gt,pa,pb,pc,pd,pi);
01154 }
01155 
01156 template<class Gt>
01157 bool
01158 compute_intersection(Gt gt,
01159              const typename Gt::Point_2& pa, 
01160              const typename Gt::Point_2& pb, 
01161              const typename Gt::Point_2& pc, 
01162              const typename Gt::Point_2& pd,
01163              typename Gt::Point_2& pi)
01164 {
01165   typename Gt::Intersect_2 compute_intersec=gt.intersect_2_object();
01166    typename Gt::Construct_segment_2  
01167     construct_segment=gt.construct_segment_2_object();
01168   Object result = compute_intersec(construct_segment(pa,pb),
01169                                    construct_segment(pc,pd));
01170   return assign(pi, result);
01171 }
01172 
01173 
01174 template<class Gt>
01175 int
01176 limit_intersection(Gt ,
01177                    const typename Gt::Point_2& , 
01178                    const typename Gt::Point_2& , 
01179                    const typename Gt::Point_2& , 
01180                    const typename Gt::Point_2& ,
01181                    No_intersection_tag)
01182 {
01183   return 0;
01184 }
01185 
01186 template<class Gt>
01187 int
01188 limit_intersection(Gt ,
01189                    const typename Gt::Point_2& , 
01190                    const typename Gt::Point_2& , 
01191                    const typename Gt::Point_2& , 
01192                    const typename Gt::Point_2& ,
01193                    Exact_intersections_tag)
01194 {
01195   return 0;
01196 }
01197 
01198 template<class Gt>
01199 int
01200 limit_intersection(Gt gt,
01201              const typename Gt::Point_2& pa, 
01202              const typename Gt::Point_2& pb, 
01203              const typename Gt::Point_2& pc, 
01204              const typename Gt::Point_2& pd,
01205              Exact_predicates_tag)
01206 {
01207   typename Gt::Construct_line_2 line = gt.construct_line_2_object();
01208   typename Gt::Compute_squared_distance_2 
01209     distance = gt.compute_squared_distance_2_object();
01210   typename Gt::Line_2 l1 = line(pa,pb);
01211   typename Gt::Line_2 l2 = line(pc,pd);
01212   int i = 0;
01213   typename Gt::FT dx = distance(l2,pa);
01214   typename Gt::FT db = distance(l2,pb);
01215   typename Gt::FT dc = distance(l1,pc);
01216   typename Gt::FT dd = distance(l1,pd);
01217   if ( db < dx  ) { dx = db; i = 1;}
01218   if ( dc < dx  ) { dx = dc; i = 2;}
01219   if ( dd < dx  ) { i = 3;}
01220   return i;
01221 }
01222 
01223 CGAL_END_NAMESPACE
01224 
01225 #endif //CGAL_CONSTRAINED_TRIANGULATION_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines