BWAPI
|
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