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/Arr_curve_data_traits_2.h $ 00015 // $Id: Arr_curve_data_traits_2.h 50779 2009-07-23 12:14:52Z 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_CURVE_DATA_TRAITS_2_H 00022 #define CGAL_ARR_CURVE_DATA_TRAITS_2_H 00023 00028 #include<CGAL/Arr_tags.h> 00029 #include<CGAL/Arr_geometry_traits/Curve_data_aux.h> 00030 #include<list> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00046 template <class Traits_, class XMonotoneCurveData_, 00047 class Merge_ = _Default_merge_func<XMonotoneCurveData_>, 00048 class CurveData_ = XMonotoneCurveData_, 00049 class Convert_ = _Default_convert_func<CurveData_, 00050 XMonotoneCurveData_> > 00051 class Arr_curve_data_traits_2 : public Traits_ 00052 { 00053 public: 00054 00055 typedef Traits_ Base_traits_2; 00056 typedef XMonotoneCurveData_ X_monotone_curve_data; 00057 typedef Merge_ Merge; 00058 typedef CurveData_ Curve_data; 00059 typedef Convert_ Convert; 00060 00061 typedef typename Base_traits_2::Curve_2 Base_curve_2; 00062 typedef typename Base_traits_2::X_monotone_curve_2 Base_x_monotone_curve_2; 00063 typedef typename Base_traits_2::Point_2 Point_2; 00064 00065 typedef typename Base_traits_2::Has_left_category Has_left_category; 00066 00067 typedef typename Base_traits_2::Has_merge_category Base_has_merge_category; 00068 typedef Tag_true Has_merge_category; 00069 00070 typedef typename CGALi::Arr_complete_left_side_tag< Base_traits_2 >::Tag 00071 Arr_left_side_tag; 00072 typedef typename CGALi::Arr_complete_bottom_side_tag< Base_traits_2 >::Tag 00073 Arr_bottom_side_tag; 00074 typedef typename CGALi::Arr_complete_top_side_tag< Base_traits_2 >::Tag 00075 Arr_top_side_tag; 00076 typedef typename CGALi::Arr_complete_right_side_tag< Base_traits_2 >::Tag 00077 Arr_right_side_tag; 00078 00079 // Representation of a curve with an addtional data field: 00080 typedef _Curve_data_ex<Base_curve_2, Curve_data> Curve_2; 00081 00082 // Representation of an x-monotone curve with an addtional data field: 00083 typedef _Curve_data_ex<Base_x_monotone_curve_2, 00084 X_monotone_curve_data> X_monotone_curve_2; 00085 00086 typedef typename Base_traits_2::Multiplicity Multiplicity; 00087 00088 public: 00089 00091 00092 00094 Arr_curve_data_traits_2 () 00095 {} 00096 00098 Arr_curve_data_traits_2 (const Base_traits_2 & traits) : 00099 Base_traits_2 (traits) 00100 {} 00102 00104 00105 00106 class Make_x_monotone_2 00107 { 00108 private: 00109 const Base_traits_2 * base; 00110 00111 public: 00112 00114 Make_x_monotone_2 (const Base_traits_2 * _base) : 00115 base (_base) 00116 {} 00117 00126 template<class OutputIterator> 00127 OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const 00128 { 00129 // Make the original curve x-monotone. 00130 std::list<CGAL::Object> base_objects; 00131 00132 base->make_x_monotone_2_object() (cv, 00133 std::back_inserter (base_objects)); 00134 00135 // Attach the data to each of the resulting x-monotone curves. 00136 typename std::list<CGAL::Object>::const_iterator it; 00137 const Base_x_monotone_curve_2 *base_x_curve; 00138 X_monotone_curve_data xdata = Convert()(cv.data()); 00139 00140 for (it = base_objects.begin(); it != base_objects.end(); ++it) 00141 { 00142 base_x_curve = object_cast<Base_x_monotone_curve_2> (&(*it)); 00143 if (base_x_curve != NULL) 00144 { 00145 // Current object is an x-monotone curve: Attach data to it. 00146 *oi = make_object (X_monotone_curve_2 (*base_x_curve, 00147 xdata)); 00148 } 00149 else 00150 { 00151 // Current object is an isolated point: Leave it as is. 00152 CGAL_assertion (object_cast<Point_2> (&(*it)) != NULL); 00153 *oi = *it; 00154 } 00155 ++oi; 00156 } 00157 00158 return (oi); 00159 } 00160 }; 00161 00163 Make_x_monotone_2 make_x_monotone_2_object () const 00164 { 00165 return Make_x_monotone_2 (this); 00166 } 00167 00168 class Split_2 00169 { 00170 private: 00171 const Base_traits_2 * base; 00172 00173 public: 00174 00176 Split_2 (const Base_traits_2 * _base) : 00177 base (_base) 00178 {} 00179 00188 void operator() (const X_monotone_curve_2& cv, const Point_2 & p, 00189 X_monotone_curve_2& c1, X_monotone_curve_2& c2) const 00190 { 00191 // Split the original curve. 00192 base->split_2_object() (cv, p, c1, c2); 00193 00194 // Attach data to the split curves. 00195 c1.set_data (cv.data()); 00196 c2.set_data (cv.data()); 00197 00198 return; 00199 } 00200 }; 00201 00203 Split_2 split_2_object () const 00204 { 00205 return Split_2 (this); 00206 } 00207 00208 class Intersect_2 00209 { 00210 private: 00211 const Base_traits_2 * base; 00212 00213 public: 00214 00216 Intersect_2 (const Base_traits_2 * _base) : 00217 base (_base) 00218 {} 00219 00229 template<class OutputIterator> 00230 OutputIterator operator() (const X_monotone_curve_2& cv1, 00231 const X_monotone_curve_2& cv2, 00232 OutputIterator oi) const 00233 { 00234 // Use the base functor to obtain all intersection objects. 00235 std::list<CGAL::Object> base_objects; 00236 00237 base->intersect_2_object() (cv1, cv2, 00238 std::back_inserter (base_objects)); 00239 00240 // Stop if the list is empty: 00241 if (base_objects.empty()) 00242 return (oi); 00243 00244 // Go over all intersection objects and prepare the output. 00245 typename std::list<CGAL::Object>::const_iterator it; 00246 const Base_x_monotone_curve_2 *base_cv; 00247 00248 for (it = base_objects.begin(); it != base_objects.end(); ++it) 00249 { 00250 if ((base_cv = object_cast<Base_x_monotone_curve_2> (&(*it))) != NULL) 00251 { 00252 // The current intersection object is an overlapping x-monotone 00253 // curve: Merge the data fields of both intersecting curves and 00254 // associate the result with the overlapping curve. 00255 X_monotone_curve_2 cv (*base_cv, 00256 Merge() (cv1.data(), cv2.data())); 00257 00258 *oi = make_object (cv); 00259 } 00260 else 00261 { 00262 // The current intersection object is an intersection point: 00263 // Copy it as is. 00264 *oi = *it; 00265 } 00266 ++oi; 00267 } 00268 00269 return (oi); 00270 } 00271 }; 00272 00274 Intersect_2 intersect_2_object () const 00275 { 00276 return Intersect_2 (this); 00277 } 00278 00279 class Are_mergeable_2 00280 { 00281 private: 00282 const Base_traits_2 * base; 00283 00284 public: 00285 00287 Are_mergeable_2 (const Base_traits_2 * _base) : 00288 base (_base) 00289 {} 00290 00297 bool operator() (const X_monotone_curve_2& cv1, 00298 const X_monotone_curve_2& cv2) const 00299 { 00300 return (_are_mergeable_base_imp (cv1, cv2, Base_has_merge_category())); 00301 } 00302 00303 private: 00304 00308 bool _are_mergeable_base_imp (const X_monotone_curve_2& cv1, 00309 const X_monotone_curve_2& cv2, 00310 Tag_true) const 00311 { 00312 // In case the two base curves are not mergeable, the extended curves 00313 // are not mergeable as well. 00314 if (! (base->are_mergeable_2_object() (cv1, cv2))) 00315 return (false); 00316 00317 // In case the two base curves are mergeable, check that they have the 00318 // same data fields. 00319 return (cv1.data() == cv2.data()); 00320 } 00321 00325 bool _are_mergeable_base_imp (const X_monotone_curve_2& , 00326 const X_monotone_curve_2& , 00327 Tag_false) const 00328 { 00329 // Curve merging is not supported: 00330 return (false); 00331 } 00332 }; 00333 00335 Are_mergeable_2 are_mergeable_2_object () const 00336 { 00337 return Are_mergeable_2 (this); 00338 } 00339 00340 class Merge_2 00341 { 00342 private: 00343 const Base_traits_2 * base; 00344 00345 public: 00346 00348 Merge_2 (const Base_traits_2 * _base) : 00349 base (_base) 00350 {} 00351 00359 void operator() (const X_monotone_curve_2& cv1, 00360 const X_monotone_curve_2& cv2, 00361 X_monotone_curve_2& c) const 00362 { 00363 // The function is implemented based on the base Has_merge category. 00364 _merge_imp (cv1, cv2, c, Base_has_merge_category()); 00365 } 00366 00367 private: 00368 00372 void _merge_imp (const X_monotone_curve_2& cv1, 00373 const X_monotone_curve_2& cv2, 00374 X_monotone_curve_2& c, 00375 Tag_true) const 00376 { 00377 // Merge the two base curve. 00378 Base_x_monotone_curve_2 base_cv; 00379 00380 base->merge_2_object() (cv1, cv2, base_cv); 00381 00382 // Attach data from one of the curves. 00383 CGAL_precondition (cv1.data() == cv2.data()); 00384 00385 c = X_monotone_curve_2 (base_cv, cv1.data()); 00386 return; 00387 } 00388 00392 void _merge_imp (const X_monotone_curve_2& , 00393 const X_monotone_curve_2& , 00394 X_monotone_curve_2& , 00395 Tag_false) const 00396 { 00397 // This function should never be called! 00398 CGAL_error_msg("Merging curves is not supported."); 00399 } 00400 }; 00401 00403 Merge_2 merge_2_object () const 00404 { 00405 return Merge_2 (this); 00406 } 00407 00408 class Construct_x_monotone_curve_2 00409 { 00410 private: 00411 const Base_traits_2 * base; 00412 00413 public: 00414 00416 Construct_x_monotone_curve_2 (const Base_traits_2 * _base) : 00417 base (_base) 00418 {} 00419 00427 X_monotone_curve_2 operator() (const Point_2& p, const Point_2& q) const 00428 { 00429 Base_x_monotone_curve_2 base_cv = 00430 base->construct_x_monotone_curve_2_object() (p, q); 00431 00432 return (X_monotone_curve_2 (base_cv, X_monotone_curve_data())); 00433 } 00434 }; 00435 00437 Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const 00438 { 00439 return Construct_x_monotone_curve_2 (this); 00440 } 00442 00443 }; 00444 00445 CGAL_END_NAMESPACE 00446 00447 #endif 00448