BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_topology_traits/Arr_inc_insertion_zone_visitor.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Tel-Aviv University (Israel).
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/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_inc_insertion_zone_visitor.h $
00015 // $Id: Arr_inc_insertion_zone_visitor.h 41108 2007-12-06 15:26:30Z efif $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein          <wein@post.tau.ac.il>
00019 //                 Efi Fogel         <efif@post.tau.ac.il>
00020 
00021 #ifndef CGAL_ARR_PLANAR_INC_INSERTION_ZONE_VISITOR_H
00022 #define CGAL_ARR_PLANAR_INC_INSERTION_ZONE_VISITOR_H
00023 
00028 #include <CGAL/Arr_accessor.h>
00029 #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
00030 
00031 CGAL_BEGIN_NAMESPACE
00032 
00040 template <class Arrangement_>
00041 class Arr_inc_insertion_zone_visitor
00042 {
00043 public:
00044 
00045   typedef Arrangement_                                Arrangement_2;
00046   typedef typename Arrangement_2::Geometry_traits_2   Geometry_traits_2;
00047 
00048   typedef typename Arrangement_2::Vertex_handle       Vertex_handle;
00049   typedef typename Arrangement_2::Halfedge_handle     Halfedge_handle;
00050   typedef typename Arrangement_2::Face_handle         Face_handle;
00051 
00052   typedef typename Arrangement_2::Point_2             Point_2;
00053   typedef typename Arrangement_2::X_monotone_curve_2  X_monotone_curve_2;
00054 
00055   typedef std::pair<Halfedge_handle, bool>            Result;
00056 
00057 protected:
00058 
00059   typedef Arr_traits_basic_adaptor_2<Geometry_traits_2>  Traits_adaptor_2;
00060 
00061 private:
00062 
00063   Arrangement_2         *p_arr;         // The arrangement into which we
00064                                         // insert the curves.
00065   Traits_adaptor_2      *geom_traits;   // The arrangement geometry-traits.
00066 
00067   const Vertex_handle    invalid_v;     // An invalid vertex handle.
00068   const Halfedge_handle  invalid_he;    // An invalid halfedge handle.
00069 
00070   X_monotone_curve_2     sub_cv1;       // Auxiliary varibale (for splitting).
00071   X_monotone_curve_2     sub_cv2;       // Auxiliary varibale (for splitting).
00072 
00073 public:
00074 
00076   Arr_inc_insertion_zone_visitor () :
00077     p_arr (NULL),
00078     geom_traits (NULL),
00079     invalid_v (),
00080     invalid_he ()
00081   {}
00082 
00084   void init (Arrangement_2 *arr)
00085   {
00086     p_arr = arr;
00087     geom_traits = const_cast<Traits_adaptor_2*> 
00088       (static_cast<const Traits_adaptor_2*> (p_arr->geometry_traits()));
00089   }
00090 
00106   Result found_subcurve (const X_monotone_curve_2& cv,
00107                          Face_handle face,
00108                          Vertex_handle left_v, Halfedge_handle left_he,
00109                          Vertex_handle right_v, Halfedge_handle right_he);
00110 
00122   Result found_overlap (const X_monotone_curve_2& cv,
00123                         Halfedge_handle he,
00124                         Vertex_handle left_v, Vertex_handle right_v);
00125 
00126 private:
00127 
00134   void _split_edge (Halfedge_handle he,
00135                     const Point_2& p,
00136                     Arr_accessor<Arrangement_2>& arr_access);
00137 
00138 };
00139 
00140 //-----------------------------------------------------------------------------
00141 // Memeber-function definitions:
00142 //-----------------------------------------------------------------------------
00143 
00144 //-----------------------------------------------------------------------------
00145 // Handle the a subcurve located in the interior of a given face.
00146 //
00147 template <class Arrangement>
00148 typename Arr_inc_insertion_zone_visitor<Arrangement>::Result
00149 Arr_inc_insertion_zone_visitor<Arrangement>::
00150 found_subcurve (const X_monotone_curve_2& cv, Face_handle face,
00151                 Vertex_handle left_v, Halfedge_handle left_he,
00152                 Vertex_handle right_v, Halfedge_handle right_he)
00153 {
00154   // Create an arrangement accessor.
00155   Arr_accessor<Arrangement_2>    arr_access (*p_arr);
00156   
00157   // Get the boundary conditions of the curve ends.
00158   const Arr_parameter_space bx_l =
00159     geom_traits->parameter_space_in_x_2_object()(cv, ARR_MIN_END);
00160   const Arr_parameter_space by_l =
00161     geom_traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END);
00162 
00163   const Arr_parameter_space bx_r =
00164     geom_traits->parameter_space_in_x_2_object()(cv, ARR_MAX_END);
00165   const Arr_parameter_space by_r =
00166     geom_traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END);
00167 
00168   // Check if the left and the right endpoints of cv should be associated
00169   // with arrangement vertices.
00170   const bool vertex_for_left =
00171     (left_v != invalid_v) || (left_he != invalid_he);
00172   const bool vertex_for_right =
00173     (right_v != invalid_v) || (right_he != invalid_he);
00174 
00175   // Find the previous halfedges for the left and right endpoints (if any).
00176   Halfedge_handle  prev_he_left;
00177   Halfedge_handle  prev_he_right;
00178 
00179   if (vertex_for_left)
00180   {
00181     // If we are given the previous halfedge, use it. Otherwise, we are given
00182     // the vertex and we should locate cv around it.
00183     if (left_he != invalid_he)
00184       prev_he_left = left_he;
00185     else if (! left_v->is_isolated())
00186       prev_he_left = arr_access.locate_around_vertex (left_v, cv);
00187 
00188     // In case the vertex does not exist, split left_he at cv's left endpoint
00189     // and create the vertex.
00190     if (left_v == invalid_v)
00191     {
00192       _split_edge (left_he,
00193                    geom_traits->construct_min_vertex_2_object() (cv),
00194                    arr_access);
00195 
00196       // Check if we have just split the halfedge that right_he refers to,
00197       // and if this halfedge is directed from left to right.
00198       // If so, right_he's target is now the new vertex, and we have to
00199       // proceed to the next halfedge (which is going to be split).
00200       if (right_he == left_he && left_he->direction() == ARR_LEFT_TO_RIGHT)
00201         right_he = right_he->next();
00202     }
00203   }
00204   else
00205   {
00206     // Check if the left end of cv is bounded of not.
00207     if ((bx_l == ARR_LEFT_BOUNDARY) || (by_l != ARR_INTERIOR)) {
00208       // Use the arrangement accessor and obtain a vertex associated with
00209       // the unbounded left end (possibly with a predecessor halfedge).
00210       std::pair<Vertex_handle, Halfedge_handle>  pos =
00211         arr_access.place_and_set_curve_end (face, cv, ARR_MIN_END, bx_l, by_l);
00212 
00213       if (pos.second != invalid_he)
00214         // Use the predecessor halfedge, if possible:
00215         prev_he_left = pos.second;
00216       else
00217         // Use just the isolated vertex:
00218         left_v = pos.first;
00219     }
00220   }
00221 
00222   if (vertex_for_right)
00223   {
00224     // If we are given the previous halfedge, use it. Otherwise, we are given
00225     // the vertex and we should locate cv around it.
00226     if (right_he != invalid_he)
00227       prev_he_right = right_he;
00228     else if (! right_v->is_isolated())
00229       prev_he_right = arr_access.locate_around_vertex (right_v, cv);
00230     
00231     // In case the vertex does not exist, split right_he at cv's right
00232     // endpoint and create the vertex.
00233     if (right_v == invalid_v)
00234     {
00235       _split_edge (right_he,
00236                    geom_traits->construct_max_vertex_2_object() (cv),
00237                    arr_access);
00238       
00239       // Check if we have just split the halfedge that left_he refers to.
00240       // If so, prev_he_right's target is now the new vertex, and we have to
00241       // proceed to the next halfedge (whose target is right_v).
00242       if (right_he == prev_he_left)
00243       {
00244         prev_he_left = prev_he_left->next();
00245       }
00246     }
00247   }
00248   else
00249   {
00250     // Check if the right end of cv is bounded of not.    
00251     if ((bx_r == ARR_RIGHT_BOUNDARY) || (by_r != ARR_INTERIOR)) {
00252       // Use the arrangement accessor and obtain a vertex associated with
00253       // the unbounded right end (possibly with a predecessor halfedge).
00254       std::pair<Vertex_handle, Halfedge_handle>  pos =
00255         arr_access.place_and_set_curve_end (face, cv, ARR_MAX_END, bx_r, by_r);
00256 
00257       if (pos.second != invalid_he)
00258         // Use the predecessor halfedge, if possible:
00259         prev_he_right = pos.second;
00260       else
00261         // Use just the isolated vertex:
00262         right_v = pos.first;
00263     }
00264   }
00265 
00266   // Insert the curve into the arrangement.
00267   Halfedge_handle   inserted_he;
00268 
00269   if (prev_he_left == invalid_he)
00270   {
00271     // The left endpoint is associated with an isolated vertex, or is not
00272     // associated with any vertex. In the latter case, we create such a vertex
00273     // now.
00274     if (left_v == invalid_v)
00275     {
00276       if (bx_l == ARR_INTERIOR && by_l == ARR_INTERIOR)
00277       {
00278         left_v = arr_access.create_vertex 
00279           (geom_traits->construct_min_vertex_2_object() (cv));
00280       }
00281       else
00282       {
00283         left_v =
00284           arr_access.create_boundary_vertex (cv, ARR_MIN_END, bx_l, by_l);
00285       }
00286     }
00287 
00288     if (prev_he_right == invalid_he)
00289     {
00290       // The right endpoint is associated with an isolated vertex, or is not
00291       // associated with any vertex. In the latter case, we create such a
00292       // vertex now.
00293       if (right_v == invalid_v)
00294       {
00295         if (bx_r == ARR_INTERIOR && by_r == ARR_INTERIOR)
00296         {
00297           right_v = arr_access.create_vertex 
00298             (geom_traits->construct_max_vertex_2_object() (cv));
00299         }
00300         else
00301         {
00302           right_v = arr_access.create_boundary_vertex (cv, ARR_MAX_END,
00303                                                        bx_r, by_r);
00304         }
00305       }
00306      
00307       // We should insert the curve in the interior of the face.
00308       inserted_he = arr_access.insert_in_face_interior_ex (cv, face,
00309                                                            left_v, right_v,
00310                                                            SMALLER);
00311     }
00312     else
00313     {
00314       // The right endpoint is associated with an arrangement vertex, and
00315       // we have the predecessor halfedge for the insertion.
00316       inserted_he = arr_access.insert_from_vertex_ex (cv, prev_he_right,
00317                                                       left_v, LARGER);
00318 
00319       // The returned halfedge is directed to the newly created vertex
00320       // (the left one), so we take its twin.
00321       inserted_he = inserted_he->twin();
00322     }
00323   }
00324   else
00325   {
00326     // We have a vertex associated with the left end of the curve, along
00327     // with a predecessor halfedge.
00328     if (prev_he_right == invalid_he)
00329     {
00330       // The right endpoint is associated with an isolated vertex, or is not
00331       // associated with any vertex. In the latter case, we create such a
00332       // vertex now.
00333       if (right_v == invalid_v)
00334       {
00335         if (bx_r == ARR_INTERIOR && by_r == ARR_INTERIOR)
00336         {
00337           right_v = arr_access.create_vertex 
00338               (geom_traits->construct_max_vertex_2_object() (cv));
00339         }
00340         else
00341         {
00342           right_v =
00343             arr_access.create_boundary_vertex (cv, ARR_MAX_END, bx_r, by_r);
00344         }
00345       }
00346      
00347       // Use the left predecessor for the insertion.
00348       inserted_he = arr_access.insert_from_vertex_ex (cv, prev_he_left,
00349                                                       right_v, SMALLER);
00350     }
00351     else
00352     {
00353       // The right endpoint is associated with an arrangement vertex, and
00354       // we have the predecessor halfedge for the insertion.
00355       CGAL_assertion (prev_he_right != invalid_he);
00356 
00357       // Perform the insertion using the predecessor halfedges.
00358       inserted_he = p_arr->insert_at_vertices (cv,
00359                                                prev_he_left,
00360                                                prev_he_right);
00361     }
00362   }
00363 
00364   // Return the inserted halfedge, and indicate we should not halt the
00365   // zone-computation process.
00366   Result    res = Result (inserted_he, false);
00367   
00368   return (res);
00369 }
00370 
00371 //-----------------------------------------------------------------------------
00372 // Handle the a subcurve located in the interior of a given face.
00373 //
00374 template <class Arrangement>
00375 typename Arr_inc_insertion_zone_visitor<Arrangement>::Result
00376 Arr_inc_insertion_zone_visitor<Arrangement>::
00377 found_overlap (const X_monotone_curve_2& cv,
00378                Halfedge_handle he,
00379                Vertex_handle left_v, Vertex_handle right_v)
00380 {
00381   // Get the boundary conditions of the curve ends.
00382   const Arr_parameter_space bx_l =
00383     geom_traits->parameter_space_in_x_2_object()(cv, ARR_MIN_END);
00384   const Arr_parameter_space by_l =
00385     geom_traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END);
00386 
00387   const Arr_parameter_space bx_r =
00388     geom_traits->parameter_space_in_x_2_object()(cv, ARR_MAX_END);
00389   const Arr_parameter_space by_r =
00390     geom_traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END);
00391 
00392   // Modify (perhaps split) the overlapping arrangement edge.
00393   Halfedge_handle   updated_he;
00394 
00395   if (left_v == invalid_v &&
00396       ! ((bx_l == ARR_LEFT_BOUNDARY) || (by_l != ARR_INTERIOR)))
00397   {
00398     // Split the curve associated with he at the left endpoint of cv.
00399     geom_traits->split_2_object()
00400       (he->curve(),
00401        geom_traits->construct_min_vertex_2_object() (cv), sub_cv1, sub_cv2);
00402 
00403     if (right_v == invalid_v &&
00404         ! ((bx_r == ARR_RIGHT_BOUNDARY) || (by_r != ARR_INTERIOR)))
00405     {
00406       // The overlapping curve is contained strictly in the interior of he:
00407       // Split he as an intermediate step.
00408       updated_he = p_arr->split_edge (he, sub_cv1, sub_cv2);
00409       updated_he = updated_he->next();
00410 
00411       // Split the left subcurve at the right endpoint of cv.
00412       geom_traits->split_2_object()
00413         (updated_he->curve(),
00414          geom_traits->construct_max_vertex_2_object() (cv), sub_cv1, sub_cv2);
00415 
00416       // Split updated_he once again, so that the left portion corresponds
00417       // to the overlapping curve and the right portion corresponds to
00418       // sub_cv2.
00419       updated_he = p_arr->split_edge (updated_he, cv, sub_cv2);
00420     }
00421     else
00422     {
00423       // Split he, such that the left portion corresponds to sub_cv1 and the
00424       // right portion corresponds to the overlapping curve.
00425       updated_he = p_arr->split_edge (he, sub_cv1, cv);
00426       updated_he = updated_he->next();
00427     }
00428   }
00429   else
00430   {
00431     if (right_v == invalid_v &&
00432         ! ((bx_r == ARR_RIGHT_BOUNDARY) || (by_r != ARR_INTERIOR)))
00433     {
00434       // Split the curve associated with he at the right endpoint of cv.
00435       geom_traits->split_2_object()
00436         (he->curve(),
00437          geom_traits->construct_max_vertex_2_object() (cv), sub_cv1, sub_cv2);
00438 
00439       // Split he, such that the left portion corresponds to the overlapping
00440       // curve and the right portion corresponds to sub_cv2.
00441       updated_he = p_arr->split_edge (he, cv, sub_cv2);
00442     }
00443     else
00444     {
00445       // The entire edge is overlapped: Modify the curve associated with cv
00446       // to be the overlapping curve.
00447       updated_he = p_arr->modify_edge (he, cv);
00448     }
00449   }
00450 
00451   // Return the updated halfedge, and indicate we should not halt the
00452   // zone-computation process.
00453   Result    res = Result (updated_he, false);
00454 
00455   return (res);
00456 }
00457 
00458 //-----------------------------------------------------------------------------
00459 // Split an arrangement edge.
00460 //
00461 template <class Arrangement>
00462 void Arr_inc_insertion_zone_visitor<Arrangement>::
00463 _split_edge (Halfedge_handle he, const Point_2& p,
00464              Arr_accessor<Arrangement_2>& arr_access)
00465 {
00466   // Split the curve at the split point.
00467   geom_traits->split_2_object() (he->curve(), p, sub_cv1, sub_cv2);
00468 
00469   // sub_cv1 is always to the left of the split point p and sub_cv2 lies to
00470   // its right. Thus, if the split edge is directed from left to right then
00471   // left end of sub_cv1 equals he's source, and if the edge is directed from
00472   // right to left, we have to reverse the subcurve order.
00473   if (he->direction() == ARR_LEFT_TO_RIGHT)
00474   {
00475     arr_access.split_edge_ex (he, p, sub_cv1, sub_cv2);
00476   }
00477   else
00478   {
00479     arr_access.split_edge_ex (he, p, sub_cv2, sub_cv1);
00480   }
00481 
00482   return;
00483 }
00484 
00485 CGAL_END_NAMESPACE
00486 
00487 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines