BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_topology_traits/Arr_planar_topology_traits_base_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2006  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_planar_topology_traits_base_2.h $
00015 // $Id: Arr_planar_topology_traits_base_2.h 50366 2009-07-05 12:56:48Z 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_TOPOLOGY_TRAITS_BASE_2_H
00022 #define CGAL_ARR_PLANAR_TOPOLOGY_TRAITS_BASE_2_H
00023 
00028 #include <CGAL/Arr_enums.h>
00029 #include <CGAL/Arr_default_dcel.h>
00030 #include <CGAL/Arr_walk_along_line_point_location.h>
00031 #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
00032 #include <CGAL/Sweep_line_2/Arr_construction_event.h>
00033 #include <CGAL/Sweep_line_2/Arr_construction_subcurve.h>
00034 #include <CGAL/Sweep_line_2/Arr_construction_sl_visitor.h>
00035 #include <CGAL/Sweep_line_2/Arr_basic_insertion_traits_2.h>
00036 #include <CGAL/Sweep_line_2/Arr_basic_insertion_sl_visitor.h>
00037 #include <CGAL/Sweep_line_2/Arr_insertion_traits_2.h>
00038 #include <CGAL/Sweep_line_2/Arr_insertion_sl_visitor.h>
00039 #include <CGAL/Sweep_line_2/Arr_overlay_subcurve.h>
00040 #include <CGAL/Sweep_line_2/Arr_overlay_traits_2.h>
00041 #include <CGAL/Sweep_line_2/Arr_overlay_sl_visitor.h>
00042 #include <CGAL/Sweep_line_2/Arr_batched_pl_sl_visitor.h>
00043 #include <CGAL/Sweep_line_2/Arr_vert_decomp_sl_visitor.h>
00044 #include <CGAL/Arr_point_location/Arr_batched_point_location_traits_2.h>
00045 
00046 CGAL_BEGIN_NAMESPACE
00047 
00052 template <class GeomTraits_,
00053           class Dcel_ = Arr_default_dcel<GeomTraits_> >
00054 class Arr_planar_topology_traits_base_2
00055 {
00056 public:
00057 
00059 
00060   typedef GeomTraits_                                     Geometry_traits_2;
00061   typedef typename Geometry_traits_2::Point_2             Point_2;
00062   typedef typename Geometry_traits_2::X_monotone_curve_2  X_monotone_curve_2;
00064 
00066 
00067   typedef Dcel_                                           Dcel;
00068   typedef typename Dcel::Size                             Size;
00069   typedef typename Dcel::Vertex                           Vertex;
00070   typedef typename Dcel::Halfedge                         Halfedge;
00071   typedef typename Dcel::Face                             Face;
00072   typedef typename Dcel::Outer_ccb                        Outer_ccb;
00073   typedef typename Dcel::Inner_ccb                        Inner_ccb;
00074   typedef typename Dcel::Isolated_vertex                  Isolated_vertex;
00076 
00077   typedef Arr_planar_topology_traits_base_2<Geometry_traits_2,
00078                                             Dcel>         Self;
00079 
00080 protected:
00081 
00082   typedef Arr_traits_basic_adaptor_2<Geometry_traits_2>    Traits_adaptor_2;
00083 
00084   // Data members:
00085   Dcel                m_dcel;       // The DCEL.
00086 
00087   const Traits_adaptor_2 * traits;       // The geometry-traits adaptor.
00088   bool                own_traits;   // Inidicate whether we should evetually
00089                                     // free the traits object.
00090 
00091   // Copy constructor and assignment operator - not supported.
00092   Arr_planar_topology_traits_base_2 (const Self& );
00093   Self& operator= (const Self& );
00094 
00095 public:
00096 
00098 
00099 
00101   Arr_planar_topology_traits_base_2 () :
00102     own_traits (true)
00103   {
00104     traits = new Traits_adaptor_2;
00105   }
00106 
00108   Arr_planar_topology_traits_base_2 (const Geometry_traits_2 * geom_traits) :
00109     own_traits (false)
00110   {
00111     traits = static_cast<const Traits_adaptor_2*>(geom_traits);
00112   }
00113 
00115   void assign (const Self& other);
00116 
00118   virtual ~Arr_planar_topology_traits_base_2 ()
00119   {
00120     // Clear the DCEL.
00121     m_dcel.delete_all();
00122 
00123     if (own_traits)
00124       delete traits;    
00125   }
00127 
00129 
00130 
00132   const Dcel& dcel () const
00133   {
00134     return (m_dcel);
00135   }
00136 
00138   Dcel& dcel ()
00139   {
00140     return (m_dcel);
00141   }
00142 
00152   void notify_on_boundary_vertex_creation (Vertex *,
00153                                            const X_monotone_curve_2& ,
00154                                            Arr_curve_end,
00155                                            Arr_parameter_space /* ps_x */,
00156                                            Arr_parameter_space /* ps_y */)
00157   {
00158     // In the planar-topology traits this function should never be invoked:
00159     return;
00160   }
00161 
00174   std::pair<bool, bool>
00175   face_split_after_edge_insertion(const Halfedge *
00176                                     CGAL_precondition_code(prev1),
00177                                   const Halfedge *
00178                                     CGAL_precondition_code(prev2),
00179                                   const X_monotone_curve_2 & /* cv */) const
00180   {
00181     CGAL_precondition (prev1->is_on_inner_ccb());
00182     CGAL_precondition (prev2->is_on_inner_ccb());
00183     CGAL_precondition (prev1->inner_ccb() == prev2->inner_ccb());
00184 
00185     // In case of a planar topology, connecting two vertices on the same
00186     // inner CCB closes a new face that becomes a hole in the original face:
00187     return (std::make_pair (true, true));
00188   }
00189 
00190 #if CGAL_NEW_FACE_SPLIT_STRATEGY
00191 
00203   std::pair<bool, bool>
00204   face_update_upon_edge_insertion(const Halfedge *
00205                                     CGAL_precondition_code(prev1),
00206                                   const Halfedge *
00207                                     CGAL_precondition_code(prev2),
00208                                   const X_monotone_curve_2 & cv) const
00209   {
00210       // In case of a planar topology, connecting two vertices on the same
00211       // CCB closes a new face that becomes a hole in the original face:
00212       return (std::make_pair (true, true));
00213   }
00214 #endif
00215 
00216 
00224   bool hole_creation_after_edge_removal (const Halfedge *he) const
00225   {
00226     CGAL_precondition (! he->is_on_inner_ccb());
00227     CGAL_precondition (! he->opposite()->is_on_inner_ccb());
00228 
00229     // Check whether the halfedge and its twin belong to the same outer CCB
00230     // (and are therefore incident to the same face).
00231     if (he->outer_ccb() == he->opposite()->outer_ccb())
00232     {
00233       // In this case we cut an antenna, therefore we seperate a new hole
00234       // from the outer CCB of the face.
00235       return (true);
00236     }
00237     else
00238     {
00239       // The edge separates two faces. When we remove it, these two faces will
00240       // be merged, but no new hole will be created.
00241       return (false);
00242     }
00243   }
00244 
00261   bool is_on_new_perimetric_face_boundary (const Halfedge *,
00262                                            const Halfedge *,
00263                                            const X_monotone_curve_2&) const
00264   {
00265     // We can never have perimetric faces in a planar topology:
00266     CGAL_error();
00267     return (false);
00268   }
00269 
00278   bool boundaries_of_same_face (const Halfedge *,
00279                                 const Halfedge *) const
00280   {
00281     // This predicate is only used for case 3.3.2 of the insertion process,
00282     // therefore it should never be invoked in the planar case.
00283     CGAL_error();
00284     return (false);
00285   }
00286 
00287 
00288 #if CGAL_ARRANGEMENT_ON_SURFACE_INSERT_VERBOSE || CGAL_NEW_FACE_SPLIT_STRATEGY
00289 
00296   CGAL::Sign _sign_of_subpath(const Halfedge* he1, const Halfedge* he2) 
00297     const {
00298     return CGAL::ZERO;
00299   }
00300     
00309   CGAL::Sign _sign_of_subpath(const Halfedge* he1, 
00310                               const bool target,
00311                               const X_monotone_curve_2& cv2,
00312                               const CGAL::Arr_curve_end& end2) const {
00313     return CGAL::ZERO;
00314   }
00315 #endif
00316 
00325   bool is_in_face (const Face *f, const Point_2& p, const Vertex *v) const;
00327 
00329 
00330 
00332   virtual const Face* initial_face () const = 0;
00334 
00336 
00337 
00344   virtual Comparison_result compare_x (const Point_2& p,
00345                                        const Vertex* v) const = 0;
00346 
00353   virtual Comparison_result compare_xy (const Point_2& p,
00354                                         const Vertex* v) const = 0;
00355 
00364   virtual Comparison_result compare_y_at_x (const Point_2& p,
00365                                             const Halfedge* he) const = 0;
00367 };
00368 
00369 //-----------------------------------------------------------------------------
00370 // Memeber-function definitions:
00371 //-----------------------------------------------------------------------------
00372 
00373 //-----------------------------------------------------------------------------
00374 // Assign the contents of another topology-traits class.
00375 //
00376 template <class GeomTraits, class Dcel_>
00377 void Arr_planar_topology_traits_base_2<GeomTraits, Dcel_>::assign
00378     (const Self& other)
00379 {
00380   // Clear the current DCEL and duplicate the other DCEL.
00381   m_dcel.delete_all();
00382   m_dcel.assign (other.m_dcel);
00383   
00384   // Take care of the traits object.
00385   if (own_traits && traits != NULL)
00386     delete traits;
00387   
00388   if (other.own_traits)
00389     traits = new Traits_adaptor_2;
00390   else
00391     traits = other.traits;
00392   own_traits = other.own_traits;
00393 
00394   return;
00395 }
00396 
00397 //-----------------------------------------------------------------------------
00398 // Determine whether the given vertex lies in the interior of the given face.
00399 //
00400 template <class GeomTraits, class Dcel_>
00401 bool Arr_planar_topology_traits_base_2<GeomTraits, Dcel_>::
00402 is_in_face(const Face *f, const Point_2& p, const Vertex *v) const
00403 {
00404   CGAL_precondition (v == NULL || ! v->has_null_point());
00405   CGAL_precondition (v == NULL || 
00406                      traits->equal_2_object()(p, v->point()));
00407 
00408   // In case the face is unbounded and has no outer ccbs, this is the single
00409   // unbounded face of an arrangement of bounded curves. This face obviously
00410   // contains any point in its interior.
00411   if (f->is_unbounded() && f->number_of_outer_ccbs() == 0)
00412     return (true);
00413 
00414   // Keep a counter of the number of x-monotone curves that intersect an upward
00415   // vertical emanating from p (except for some degenerate cases that are
00416   // explained below).
00417   unsigned int       n_ray_intersections = 0;
00418 
00419   // Get a halfedge along the outer CCB of the given face, go over all curves
00420   // of the boundary component, and count those which are above p.
00421   // We begin by comparing p to the source vertex of the first halfedge.
00422   // Note that if p coincides with this vertex, p is obviously not in the
00423   // interior of the component.
00424   const Halfedge    *first = *(f->outer_ccbs_begin());
00425   const Halfedge    *curr = first;
00426   Comparison_result  res_source;
00427   Comparison_result  res_target;
00428   Comparison_result  res_y_at_x;
00429 
00430   if (curr->opposite()->vertex() == v)
00431     return (false);
00432 
00433   res_source = compare_xy (p, curr->opposite()->vertex());
00434 
00435   do
00436   {
00437     // Compare p to the target vertex of the current halfedge.
00438     // If the vertex v associated with p (if v is given and is not NULL)
00439     // on the boundary of the component, p is obviously not in the interior
00440     // the component.
00441     if (curr->vertex() == v)
00442       return (false);
00443 
00444     res_target = compare_xy (p, curr->vertex());
00445 
00446     // In case the current halfedge belongs to an "antenna", namely its
00447     // incident face is the same as its twin's, we can simply skip it
00448     // (in order not to count it twice).
00449     if (! curr->opposite()->is_on_inner_ccb() &&
00450         curr->outer_ccb()->face() == curr->opposite()->outer_ccb()->face())
00451     {
00452       curr = curr->next();
00453       res_source = res_target;
00454       continue;
00455     }
00456 
00457     // Check that if we shoot a "tilted" vertical ray from p upward
00458     // (by "tilted" we mean the angle it forms with the x-axis is
00459     //  PI/2 + epsilon, where epsilon is arbitrarily small), then we hit
00460     // the x-monotone curve associated with curr once.
00461     if (res_source != res_target)
00462     {
00463       res_y_at_x = compare_y_at_x (p, curr);
00464 
00465       if (res_y_at_x == SMALLER)
00466       {
00467         n_ray_intersections++;
00468       }        
00469       else if (res_y_at_x == EQUAL)
00470       {
00471         // In this case p lies on the current edge, so it is obviously not
00472         // contained in the interior of the component.
00473         return (false);
00474       }
00475     }
00476 
00477     // Proceed to the next halfedge along the component boundary.
00478     // Note that the source vertex of this halfedge is the current target.
00479     curr = curr->next();
00480     res_source = res_target;
00481 
00482   } while (curr != first);
00483 
00484   // The query point lies inside the connected components if and only if the
00485   // ray we shoot from it intersects the boundary an odd number of time.
00486   return ((n_ray_intersections % 2) != 0);
00487 }
00488 
00489 CGAL_END_NAMESPACE
00490 
00491 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines