BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Arr_vert_decomp_sl_visitor.h
Go to the documentation of this file.
00001 // Copyright (c) 2007  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/Sweep_line_2/Arr_vert_decomp_sl_visitor.h $
00015 // $Id: Arr_vert_decomp_sl_visitor.h 49772 2009-06-03 21:25:53Z eric $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein <wein@post.tau.ac.il>
00019 
00020 #ifndef CGAL_ARR_VERT_DECOMP_SL_VISITOR_H
00021 #define CGAL_ARR_VERT_DECOMP_SL_VISITOR_H
00022 
00027 CGAL_BEGIN_NAMESPACE
00028 
00029 #include <CGAL/Object.h>
00030 
00035 template <class Helper_, class OutputIterator_>
00036 class Arr_vert_decomp_sl_visitor :
00037   public Helper_::Base_visitor
00038 {
00039 public:
00040 
00041   typedef Helper_                                       Helper;
00042   typedef OutputIterator_                               OutputIterator;
00043 
00044   typedef typename Helper::Traits_2                     Traits_2;
00045   typedef typename Helper::Arrangement_2                Arrangement_2;
00046   typedef typename Helper::Base_visitor                 Base;
00047   typedef typename Helper::Event                        Event;
00048   typedef typename Helper::Subcurve                     Subcurve;
00049 
00050   typedef typename Arrangement_2::Vertex_const_handle   Vertex_const_handle;
00051 
00052   typedef std::pair<CGAL::Object, CGAL::Object>         Vert_pair;
00053   typedef std::pair<Vertex_const_handle, Vert_pair>     Vert_entry;
00054 
00055 protected:
00056 
00057   typedef typename Base::Status_line_iterator           Status_line_iterator;
00058   typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
00059   //typedef typename Arrangement_2::Vertex_const_handle   Vertex_const_handle;
00060   typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
00061                                       Halfedge_around_vertex_const_circulator;
00062 
00063   // Data members:
00064   Helper                m_helper;    // The helper class.
00065 
00066   const typename Arrangement_2::Geometry_traits_2    *m_traits;
00067                                      // The traits class.
00068 
00069   const Vertex_const_handle                  invalid_vh;
00070                                      // An invalid vertex handle.
00071 
00072   Vertex_const_handle   m_prev_vh;   // The previous vertex.
00073   CGAL::Object    m_prev_obj_below;  // The object this vertex sees below it.
00074   CGAL::Object    m_prev_obj_above;  // The object this vertex sees above it.
00075 
00076   OutputIterator       *m_out;       // An output iterator for the result.
00077 
00078 public:
00079 
00085   Arr_vert_decomp_sl_visitor (const Arrangement_2 *arr,
00086                               OutputIterator *oi) :
00087     m_helper (arr),
00088     m_traits (arr->geometry_traits()),
00089     invalid_vh(),
00090     m_out (oi)
00091   {}
00092   
00093   /* A notification issued before the sweep process starts. */
00094   void before_sweep ();
00095 
00104   bool after_handle_event (Event* event,
00105                            Status_line_iterator above,
00106                            bool on_above);
00107 
00111   void after_sweep ();
00112 };
00113 
00114 //-----------------------------------------------------------------------------
00115 // Memeber-function definitions:
00116 //-----------------------------------------------------------------------------
00117 
00118 //-----------------------------------------------------------------------------
00119 // A notification issued before the sweep process starts.
00120 //
00121 template <class Hlpr, class OutIt>
00122 void Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::before_sweep ()
00123 {
00124   // Notify the helper that the sweep process now starts.
00125   m_helper.before_sweep();
00126 
00127   // Set an invalid previous vertex.
00128   m_prev_vh = Vertex_const_handle();
00129 
00130   return;
00131 }
00132 
00133 //-----------------------------------------------------------------------------
00134 // A notification invoked after the sweep-line finishes handling the given
00135 // event.
00136 //
00137 template <class Hlpr, class OutIt>
00138 bool Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::after_handle_event
00139     (Event* event,
00140      Status_line_iterator above, bool /* on_above */)
00141 {
00142   // Notify the helper on the event.
00143   m_helper.after_handle_event (event);
00144 
00145   // We are only interested in events associated with valid points:
00146   if (! event->is_closed())
00147     return (true);
00148 
00149   // Get the vertex handle associated with the current event (stored with
00150   // the point).
00151   Vertex_const_handle  vh = event->point().vertex_handle();
00152   CGAL::Object         obj_above, obj_below;
00153 
00154   // Check the feature from above.
00155   if (above == this->status_line_end())
00156   {
00157     // There is no concrete subcurve above the current event point, so we use
00158     // the helper class to obtain the object above.
00159     obj_above = m_helper.top_object();
00160   }
00161   else
00162   {
00163     // We have a valid subcurve above the event: get its halfedge handle
00164     // and associate it with the vertex.
00165     obj_above =
00166       CGAL::make_object((*above)->last_curve().halfedge_handle());
00167   }
00168 
00169   // Check if the previous vertex we handled has the same x-coordinate
00170   // as the current one (it lies vertically below the current vertex).
00171   const bool         prev_same_x =
00172     (m_prev_vh != invalid_vh &&
00173      m_traits->compare_x_2_object() (vh->point(),
00174                                      m_prev_vh->point()) == EQUAL);
00175 
00176   // Decrement the status-line iterator to reach the subcurve below the
00177   // event point. If the number of right subcurves associated with the
00178   // event is n_right, we decrement the iterator n_right times, then
00179   // check if it is possible to further decrement it.
00180   Status_line_iterator  below = above;
00181   const int             n_right = event->number_of_right_curves();
00182   int                   k;
00183 
00184   for (k = 0; k < n_right; k++)
00185     --below;
00186 
00187   if (below == this->status_line_begin())
00188   {
00189     if (prev_same_x)
00190     {
00191       // The previous vertex is vertically below the current vertex,
00192       // so we update their respective entries in the output map.
00193       // We first check if the two vertices are connected (by a vertical
00194       // segment) - if so, they "see" empty features.
00195       bool          vert_connected = false;
00196         
00197       if (! vh->is_isolated())
00198       {
00199         Halfedge_around_vertex_const_circulator   circ, first;
00200 
00201         first = circ = vh->incident_halfedges();
00202         do
00203         {
00204           if (circ->source() == m_prev_vh)
00205             vert_connected = true;
00206           ++circ;
00207         } while (! vert_connected && circ != first);
00208       }
00209 
00210       if (! vert_connected)
00211       {
00212         obj_below = CGAL::make_object(m_prev_vh);
00213         m_prev_obj_above = CGAL::make_object(vh);
00214       }
00215       else
00216       {
00217         obj_below = CGAL::Object();
00218         m_prev_obj_above = CGAL::Object();
00219       }
00220     }
00221     else
00222     {
00223       // There is no concrete subcurve below the current event point, so we
00224       // use the helper class to obtain the object below.
00225       obj_below = m_helper.bottom_object();
00226     }
00227   }
00228   else
00229   {
00230     // Decrement the iterator once more in order to reach the subcurve below
00231     // the current event.
00232     --below;
00233 
00234     // If the previous event has the same x-coordinate as the current one,
00235     // we check whether it lies below or above the subcurve below. We do this
00236     // to distinguish between the following scenarios:
00237     //
00238     //
00239     //           *                      *
00240     //
00241     //         --------                 x
00242     //
00243     //           x                   ---------
00244     //
00245     if (prev_same_x &&
00246         (m_traits->compare_y_at_x_2_object()
00247             (m_prev_vh->point(),
00248              (*below)->last_curve().base()) != SMALLER))
00249     {
00250         // The previous vertex is vertically below the current vertex,
00251         // and above the subcurve that lies below vh. We therefore update
00252         // the respective entries in the output map accordingly.
00253         // We first check if the two vertices are connected (by a vertical
00254         // segment) - if so, they "see" empty features.
00255         bool          vert_connected = false;
00256         
00257         if (! vh->is_isolated())
00258         {
00259           Halfedge_around_vertex_const_circulator   circ, first;
00260 
00261           first = circ = vh->incident_halfedges();
00262           do
00263           {
00264             if (circ->source() == m_prev_vh)
00265               vert_connected = true;
00266             ++circ;
00267           } while (! vert_connected && circ != first);
00268         }
00269 
00270         if (! vert_connected)
00271         {
00272           obj_below = CGAL::make_object(m_prev_vh);
00273           m_prev_obj_above = CGAL::make_object(vh);
00274         }
00275         else
00276         {
00277           obj_below = CGAL::Object();
00278           m_prev_obj_above = CGAL::Object();
00279         }
00280       }
00281       else
00282       {
00283         // Get the halfedge handle of the subcurve below the current event and
00284         // associate it with its vertex.
00285         obj_below =
00286           CGAL::make_object((*below)->last_curve().halfedge_handle());
00287       }
00288     }
00289 
00290     // We can now create the entry for the previous vertex, as we are not
00291     // going to change the identity of the features below or above it.
00292     if (m_prev_vh != Vertex_const_handle())
00293     {
00294       *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below,
00295                                                     m_prev_obj_above));
00296       ++(*m_out);
00297     }
00298 
00299     // We are done with the current vertex, but we cannot create the entry
00300     // yet - so we store it for the next event.
00301     m_prev_vh = vh;
00302     m_prev_obj_below = obj_below;
00303     m_prev_obj_above = obj_above;
00304 
00305     // It is safe to deallocate the event.
00306     return (true);
00307 }
00308 
00309 //-----------------------------------------------------------------------------
00310 // A notification issued when the sweep process is over.
00311 //
00312 template <class Hlpr, class OutIt>
00313 void Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::after_sweep ()
00314 {
00315   // Create an entry for the last vertex (the xy-largest one). 
00316   if (m_prev_vh != invalid_vh)
00317   {
00318     *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below,
00319                                                   m_prev_obj_above));
00320     ++(*m_out);
00321   }
00322 
00323   return;
00324 }
00325 
00326 CGAL_END_NAMESPACE
00327 
00328 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines