BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Sweep_line_functors.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/Sweep_line_2/Sweep_line_functors.h $
00015 // $Id: Sweep_line_functors.h 50366 2009-07-05 12:56:48Z efif $
00016 // 
00017 //
00018 // Author(s)     : Tali Zvi <talizvi@post.tau.ac.il>
00019 //                 Baruch Zukerman <baruchzu@post.tau.ac.il>
00020 //                 Ron Wein <wein@post.tau.ac.il>
00021 //                 Efi Fogel <efif@post.tau.ac.il>
00022 
00023 #ifndef CGAL_SWEEP_LINE_FUNCTORS_H
00024 #define CGAL_SWEEP_LINE_FUNCTORS_H
00025 
00030 #include <CGAL/assertions.h>
00031 #include <CGAL/enum.h>
00032 #include <CGAL/Arr_enums.h>
00033 #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
00034 
00035 CGAL_BEGIN_NAMESPACE
00036 
00042 template <class Traits_, class Event_>
00043 class Compare_events
00044 {
00045 public:
00046 
00047   typedef Traits_                                   Traits_2;
00048   typedef Event_                                    Event;
00049 
00050   typedef typename Traits_2::Point_2                Point_2;
00051   typedef typename Traits_2::X_monotone_curve_2     X_monotone_curve_2;
00052 
00053   // should be ok, as Traits_2 is supposed to be the adaptor
00054   typedef typename Traits_2::Arr_left_side_tag          Arr_left_side_tag;
00055   typedef typename Traits_2::Arr_bottom_side_tag        Arr_bottom_side_tag;
00056   typedef typename Traits_2::Arr_top_side_tag           Arr_top_side_tag;
00057   typedef typename Traits_2::Arr_right_side_tag         Arr_right_side_tag;
00058 
00059 private:
00060 
00061   // Data members:
00062   const Traits_2 * m_traits;                // The geometric-traits object.
00063   
00064   Arr_parameter_space  m_ps_in_x;           // Storing curve information when
00065   Arr_parameter_space  m_ps_in_y;           // comparing a curve end with
00066   Arr_curve_end        m_index;             // boundary conditions.
00067 
00068 public:
00069   
00071   Compare_events (const Traits_2 * traits) :
00072     m_traits (traits)
00073   {}
00074   
00080   Comparison_result operator()(const Event* e1, const Event* e2) const
00081   {
00082     const bool  on_boundary1 = e1->is_on_boundary();
00083     const bool  on_boundary2 = e2->is_on_boundary();
00084 
00085     if (! on_boundary1 && ! on_boundary2)
00086     {
00087       // Both events do not have boundary conditions - just compare the points.
00088       return (m_traits->compare_xy_2_object()(e1->point(), e2->point()));
00089     }
00090 
00091     if (! on_boundary1)
00092     {
00093       // Compare the point associated with the first event with the second
00094       // boundary event.
00095       return ( this->operator()(e1->point(), e2) );
00096     }
00097 
00098     if (! on_boundary2)
00099     {
00100       // Compare the point associated with the second event with the first
00101       // boundary event.
00102       return (CGAL::opposite(this->operator()(e2->point(), e1)));
00103     }
00104 
00105     return (_compare_curve_end_with_event (e1->curve(), _curve_end(e1),
00106                                            e1->parameter_space_in_x(),
00107                                            e1->parameter_space_in_y(),
00108                                            e2));
00109   }
00110 
00115   Comparison_result operator() (const Point_2& pt, const Event* e2) const
00116   {
00117     const bool  on_boundary2 = e2->is_on_boundary();
00118     
00119     if (! on_boundary2)
00120     {
00121       // If e2 is a normal event, just compare pt and the event point.
00122       return (m_traits->compare_xy_2_object() (pt, e2->point()));
00123     }
00124 
00125     // Get the sign of the event's boundary condition in x. Note that a valid
00126     // point is always larger than any negative boundary event and smaller
00127     // than any positive boundary event.
00128     Arr_parameter_space ps_x2 = e2->parameter_space_in_x();
00129 
00130     if (ps_x2 == ARR_LEFT_BOUNDARY)
00131       return (LARGER);
00132     else if (ps_x2 == ARR_RIGHT_BOUNDARY)
00133       return (SMALLER);
00134     
00135     // Get the curve end that e2 represents, and compare the x-position of the
00136     // given point and this curve end.
00137     Arr_curve_end         ind = _curve_end(e2);
00138     Comparison_result res =
00139       m_traits->compare_x_near_boundary_2_object()(pt, e2->curve(), ind);
00140 
00141     if (res != EQUAL)
00142       return (res);
00143 
00144     // The event and the point has the same x-position. Get the sign of the
00145     // event's boundary condition in y. Note that a valid point is always
00146     // larger than any negative boundary event and smaller than any positive
00147     // boundary event.
00148     Arr_parameter_space ps_y2 = e2->parameter_space_in_y();
00149 
00150     CGAL_assertion (ps_y2 != ARR_INTERIOR);
00151     return (ps_y2 == ARR_BOTTOM_BOUNDARY) ? LARGER : SMALLER;
00152   }
00153 
00160   Comparison_result operator() (const X_monotone_curve_2& cv,
00161                                 const Event* e2) const
00162   {
00163     return _compare_curve_end_with_event(cv, m_index, m_ps_in_x, m_ps_in_y, e2);
00164   }
00165 
00167 
00168   void set_parameter_space_in_x (Arr_parameter_space bx)
00169   {
00170     m_ps_in_x = bx;
00171   }
00172 
00173   void set_parameter_space_in_y (Arr_parameter_space by)
00174   {
00175     m_ps_in_y = by;
00176   }
00177 
00178   void set_index (Arr_curve_end ind)
00179   {
00180     m_index = ind;
00181   }
00183 
00184 private:
00185 
00195   Comparison_result 
00196   _compare_curve_end_with_event (const X_monotone_curve_2& cv,
00197                                  Arr_curve_end ind,
00198                                  Arr_parameter_space ps_x,
00199                                  Arr_parameter_space ps_y,
00200                                  const Event* e2) const
00201   {
00202     // Check if the curve end has a boundary condition in x.
00203     if (ps_x == ARR_LEFT_BOUNDARY)
00204     {
00205       if (e2->parameter_space_in_x() == ARR_LEFT_BOUNDARY)
00206       {
00207         // Both defined on the left boundary - compare them there.
00208         CGAL_assertion (ind == ARR_MIN_END);
00209 
00210         return (m_traits->compare_y_near_boundary_2_object() (cv, e2->curve(),
00211                                                               ind));
00212       }
00213 
00214       // The curve end is obviously smaller.
00215       return (SMALLER);
00216     }
00217 
00218     if (ps_x == ARR_RIGHT_BOUNDARY)
00219     {
00220       if (e2->parameter_space_in_x() == ARR_RIGHT_BOUNDARY)
00221       {
00222         // Both defined on the right boundary - compare them there.
00223         CGAL_assertion (ind == ARR_MAX_END);
00224 
00225         return (m_traits->compare_y_near_boundary_2_object() (cv, e2->curve(),
00226                                                               ind));
00227       }
00228 
00229       // The curve end is obviously larger.
00230       return (LARGER);
00231     }
00232       
00233     // Check if the event has a boundary condition in x. Note that if it
00234     // has a negative boundary condition, the curve end is larger than it,
00235     // and if it has a positive boundary condition, the curve end is smaller.
00236     if (e2->parameter_space_in_x() == ARR_LEFT_BOUNDARY)
00237       return (LARGER);
00238     
00239     if (e2->parameter_space_in_x() == ARR_RIGHT_BOUNDARY)
00240       return (SMALLER);
00241 
00242     CGAL_assertion (ps_y != ARR_INTERIOR);
00243     Comparison_result res;
00244 
00245     // Act according to the boundary sign of the event.
00246     if (e2->parameter_space_in_y() == ARR_BOTTOM_BOUNDARY)
00247     {
00248       // Compare the x-positions of the two entities.
00249       res = m_traits->compare_x_near_boundary_2_object() (cv, ind, e2->curve(),
00250                                                           _curve_end(e2));
00251 
00252       if (res != EQUAL)
00253         return (res);
00254       
00255       // In case of equal x-positions, the curve end is larger than the event,
00256       // which lies on the bottom boundary (unless it also lies on the bottom
00257       // boundary).
00258       if (ps_y == ARR_BOTTOM_BOUNDARY)
00259         return (EQUAL);
00260 
00261       return (LARGER);
00262     }
00263 
00264     if (e2->parameter_space_in_y() == ARR_TOP_BOUNDARY)
00265     {
00266       // Compare the x-positions of the two entities.
00267       res = m_traits->compare_x_near_boundary_2_object() (cv, ind, e2->curve(),
00268                                                           _curve_end(e2));
00269 
00270       if (res != EQUAL)
00271         return (res);
00272        
00273       // In case of equal x-positions, the curve end is smaller than the event,
00274       // which lies on the top boundary (unless it also lies on the top
00275       // boundary).
00276       if (ps_y == ARR_TOP_BOUNDARY)
00277         return (EQUAL);
00278 
00279       return (SMALLER);
00280     }
00281 
00282     // If we reached here, e2 is not a boundary event and is associated with
00283     // a valid point. We compare the x-position of this point with the curve
00284     // end.
00285     res = m_traits->compare_x_near_boundary_2_object() (e2->point(), cv, ind);
00286 
00287     if (res != EQUAL)
00288       return (CGAL::opposite(res));
00289 
00290     // In case of equal x-positions, is the curve end has a negative boundary
00291     // sign, then it lies on the bottom boundary below the event. Otherwise,
00292     // it lies on the top aboundary above the event e2.
00293     return (ps_y == ARR_BOTTOM_BOUNDARY) ? SMALLER : LARGER;
00294   }
00295 
00297   inline Arr_curve_end _curve_end (const Event* e) const
00298   {
00299     return (e->has_left_curves()) ?
00300       ((e->is_right_end()) ? ARR_MAX_END : ARR_MIN_END) :
00301       ((e->is_left_end()) ? ARR_MIN_END : ARR_MAX_END);
00302   }
00303 };
00304 
00305 // Forward decleration:
00306 template <class Traits, class Subcurve>
00307 class Sweep_line_event;
00308 
00314 template <class Traits_, class Subcurve_> 
00315 class Curve_comparer 
00316 {
00317 public:
00318 
00319   typedef Traits_                                        Traits_2;
00320   typedef Subcurve_                                      Subcurve;
00321   typedef Arr_traits_basic_adaptor_2<Traits_2>           Traits_adaptor_2;
00322 
00323   typedef typename Traits_adaptor_2::Point_2 Point_2;
00324   typedef typename Traits_adaptor_2::X_monotone_curve_2  X_monotone_curve_2;
00325   typedef Sweep_line_event<Traits_2, Subcurve>           Event;
00326 
00327 private:
00328 
00329   const Traits_adaptor_2 * m_traits;    // A geometric-traits object.
00330   Event            **m_curr_event;      // Points to the current event point.
00331 
00332 public:
00333   
00335   template <class Sweep_event>
00336   Curve_comparer (const Traits_adaptor_2 * t, Sweep_event** e_ptr) :
00337     m_traits(t),
00338     m_curr_event(reinterpret_cast<Event**>(e_ptr))
00339   {}
00340 
00345   Comparison_result operator()(const Subcurve *c1, const Subcurve *c2) const
00346   {
00347     // In case to two curves are right curves at the same event, compare
00348     // to the right of the event point.
00349     if (std::find((*m_curr_event)->right_curves_begin(), 
00350                   (*m_curr_event)->right_curves_end(),
00351                   c1) != (*m_curr_event)->right_curves_end() &&
00352         std::find((*m_curr_event)->right_curves_begin(), 
00353                   (*m_curr_event)->right_curves_end(),
00354                   c2) != (*m_curr_event)->right_curves_end())
00355     {
00356       return (m_traits->compare_y_at_x_right_2_object()
00357               (c1->last_curve(), c2->last_curve(), (*m_curr_event)->point()));
00358     }
00359 
00360     Arr_parameter_space ps_x1 = 
00361       m_traits->parameter_space_in_x_2_object()(c1->last_curve(), ARR_MIN_END);
00362     Arr_parameter_space ps_y1 = 
00363       m_traits->parameter_space_in_y_2_object()(c1->last_curve(), ARR_MIN_END);
00364 
00365     if ((ps_x1 == ARR_INTERIOR) && (ps_y1 == ARR_INTERIOR))
00366     {
00367       // The first curve has a valid left endpoint. Compare the y-position
00368       // of this endpoint to the second subcurve. 
00369       return m_traits->compare_y_at_x_2_object()
00370         (m_traits->construct_min_vertex_2_object()(c1->last_curve()),
00371          c2->last_curve());
00372     }
00373 
00374     // We use the fact that the two curves are interior disjoint. As c2 is
00375     // already in the status line, then if c1 left end has a negative boundary
00376     // condition it obviously above it.
00377     CGAL_assertion (ps_x1 != ARR_RIGHT_BOUNDARY);
00378 
00379     if (ps_x1 == ARR_LEFT_BOUNDARY)
00380       return (LARGER);
00381 
00382     // For similar reasons, if c1 begins on the bottom boundary it is below
00383     // c2, if it is on the top boundary it is above it.
00384     CGAL_assertion (ps_y1 != ARR_INTERIOR);
00385     return (ps_y1 == ARR_BOTTOM_BOUNDARY) ? SMALLER : LARGER;
00386   }
00387 
00391   Comparison_result operator() (const Point_2& pt, const Subcurve *sc) const
00392   {
00393     return (m_traits->compare_y_at_x_2_object()(pt, sc->last_curve()));
00394   }
00395 
00396 };
00397 
00398 CGAL_END_NAMESPACE
00399 
00400 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines