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/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_traits_decorator.h $ 00015 // $Id: Gps_traits_decorator.h 50368 2009-07-05 13:14:14Z efif $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 00020 #ifndef CGAL_GPS_TRAITS_DECORATOR_H 00021 #define CGAL_GPS_TRAITS_DECORATOR_H 00022 00023 #include <boost/mpl/assert.hpp> 00024 00025 CGAL_BEGIN_NAMESPACE 00026 00027 template <class Traits_, class Curve_data_, class Point_data_> 00028 class Gps_traits_decorator 00029 { 00030 public: 00031 typedef Traits_ Base; 00032 typedef typename Base::X_monotone_curve_2 Base_X_monotone_curve_2; 00033 typedef typename Base::Point_2 Base_Point_2; 00034 00035 typedef Gps_traits_decorator<Traits_, Curve_data_, Point_data_> Self; 00036 00037 typedef Curve_data_ Curve_data; 00038 typedef Point_data_ Point_data; 00039 00040 typedef typename Base::Compare_x_2 Base_Compare_x_2; 00041 typedef typename Base::Compare_xy_2 Base_Compare_xy_2; 00042 typedef typename Base::Construct_min_vertex_2 Base_Construct_min_vertex_2; 00043 typedef typename Base::Construct_max_vertex_2 Base_Construct_max_vertex_2; 00044 typedef typename Base::Is_vertical_2 Base_Is_vertical_2; 00045 typedef typename Base::Compare_y_at_x_2 Base_Compare_y_at_x_2; 00046 typedef typename Base::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2; 00047 typedef typename Base::Equal_2 Base_Equal_2; 00048 typedef typename Base::Split_2 Base_Split_2; 00049 typedef typename Base::Intersect_2 Base_Intersect_2; 00050 typedef typename Base::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2; 00051 typedef typename Base::Construct_opposite_2 Base_Construct_opposite_2; 00052 typedef typename Base::Has_left_category Has_left_category; 00053 typedef typename Base::Has_merge_category Has_merge_category; 00054 00055 typedef typename Base::Arr_left_side_tag Arr_left_side_tag; 00056 typedef typename Base::Arr_bottom_side_tag Arr_bottom_side_tag; 00057 typedef typename Base::Arr_top_side_tag Arr_top_side_tag; 00058 typedef typename Base::Arr_right_side_tag Arr_right_side_tag; 00059 00060 // a side is either oblivious or open (unbounded) 00061 BOOST_MPL_ASSERT( 00062 (boost::mpl::or_< 00063 boost::is_same< Arr_left_side_tag, Arr_oblivious_side_tag >, 00064 boost::is_same< Arr_left_side_tag, Arr_open_side_tag > > 00065 ) 00066 ); 00067 BOOST_MPL_ASSERT( 00068 (boost::mpl::or_< 00069 boost::is_same< Arr_bottom_side_tag, Arr_oblivious_side_tag >, 00070 boost::is_same< Arr_bottom_side_tag, Arr_open_side_tag > > 00071 ) 00072 ); 00073 BOOST_MPL_ASSERT( 00074 (boost::mpl::or_< 00075 boost::is_same< Arr_top_side_tag, Arr_oblivious_side_tag >, 00076 boost::is_same< Arr_top_side_tag, Arr_open_side_tag > > 00077 ) 00078 ); 00079 BOOST_MPL_ASSERT( 00080 (boost::mpl::or_< 00081 boost::is_same< Arr_right_side_tag, Arr_oblivious_side_tag >, 00082 boost::is_same< Arr_right_side_tag, Arr_open_side_tag > > 00083 ) 00084 ); 00085 00086 class Ex_point_2 00087 { 00088 protected: 00089 Base_Point_2 m_base; 00090 Point_data m_data; 00091 00092 public: 00093 Ex_point_2(): m_base(), 00094 m_data() 00095 {} 00096 00097 Ex_point_2(const Base_Point_2& pt) : m_base(pt), 00098 m_data() 00099 {} 00100 00101 Ex_point_2(const Base_Point_2& pt, const Point_data& data): m_base(pt), 00102 m_data(data) 00103 {} 00104 00105 const Base_Point_2& base() const 00106 { 00107 return m_base; 00108 } 00109 00110 Base_Point_2& base() 00111 { 00112 return m_base; 00113 } 00114 00115 operator const Base_Point_2& () const 00116 { 00117 return (m_base); 00118 } 00119 00120 Point_data& data() 00121 { 00122 return m_data; 00123 } 00124 00125 const Point_data& data() const 00126 { 00127 return m_data; 00128 } 00129 00130 void set_data(const Point_data& data) 00131 { 00132 m_data = data; 00133 } 00134 00135 00136 }; 00137 00138 class Ex_x_monotone_curve_2 00139 { 00140 protected: 00141 Base_X_monotone_curve_2 m_base; 00142 Curve_data m_data; 00143 00144 public: 00145 Ex_x_monotone_curve_2(): m_base(), 00146 m_data() 00147 {} 00148 00149 Ex_x_monotone_curve_2(const Base_X_monotone_curve_2& pt) : m_base(pt), 00150 m_data() 00151 {} 00152 00153 Ex_x_monotone_curve_2(const Base_X_monotone_curve_2& pt, 00154 const Curve_data& data): m_base(pt), 00155 m_data(data) 00156 {} 00157 00158 const Base_X_monotone_curve_2& base() const 00159 { 00160 return m_base; 00161 } 00162 00163 Base_X_monotone_curve_2& base() 00164 { 00165 return m_base; 00166 } 00167 00168 operator const Base_X_monotone_curve_2& () const 00169 { 00170 return (m_base); 00171 } 00172 00173 Curve_data& data() 00174 { 00175 return m_data; 00176 } 00177 00178 const Curve_data& data() const 00179 { 00180 return m_data; 00181 } 00182 00183 void set_data(const Curve_data& data) 00184 { 00185 m_data = data; 00186 } 00187 }; 00188 00189 friend std::ostream& operator<< (std::ostream& os, const Ex_x_monotone_curve_2 & cv) 00190 { 00191 os << cv.base(); 00192 return (os); 00193 } 00194 00195 friend std::ostream& operator<< (std::ostream& os, const Ex_point_2 & pt) 00196 { 00197 os << pt.base(); 00198 return (os); 00199 } 00200 00201 typedef Ex_point_2 Point_2; 00202 typedef Ex_x_monotone_curve_2 X_monotone_curve_2; 00203 00204 protected: 00205 00206 //Data members 00207 const Base * m_base_tr; 00208 bool m_traits_owner; 00209 00210 public: 00211 00212 Gps_traits_decorator() : 00213 m_base_tr(new Base()), 00214 m_traits_owner(true) 00215 {} 00216 00217 Gps_traits_decorator(const Base & base_traits) : 00218 m_base_tr(&base_traits), 00219 m_traits_owner(false) 00220 {} 00221 00222 ~Gps_traits_decorator() 00223 { 00224 if (m_traits_owner) 00225 delete m_base_tr; 00226 } 00227 00228 class Compare_x_2 00229 { 00230 protected: 00231 00232 Base_Compare_x_2 m_base; 00233 00234 public: 00235 Compare_x_2(Base_Compare_x_2& base) : m_base(base) 00236 {} 00237 00238 Comparison_result operator() (const Point_2& p1, const Point_2& p2) const 00239 { 00240 return (m_base(p1.base(), p2.base())); 00241 } 00242 }; 00243 00245 Compare_x_2 compare_x_2_object () const 00246 { 00247 return Compare_x_2(m_base_tr->compare_x_2_object()); 00248 } 00249 00250 00251 class Compare_xy_2 00252 { 00253 protected: 00254 00255 Base_Compare_xy_2 m_base; 00256 00257 public: 00258 Compare_xy_2(const Base_Compare_xy_2& base) : m_base(base) 00259 {} 00260 00261 Comparison_result operator() (const Point_2& p1, const Point_2& p2) const 00262 { 00263 return (m_base(p1.base(), p2.base())); 00264 } 00265 }; 00266 00268 Compare_xy_2 compare_xy_2_object () const 00269 { 00270 return Compare_xy_2(m_base_tr->compare_xy_2_object()); 00271 } 00272 00273 class Construct_min_vertex_2 00274 { 00275 protected: 00276 00277 Base_Construct_min_vertex_2 m_base; 00278 00279 public: 00280 Construct_min_vertex_2(const Base_Construct_min_vertex_2& base) : 00281 m_base(base) 00282 {} 00283 00284 Point_2 operator() (const X_monotone_curve_2& cv) const 00285 { 00286 return Point_2(m_base(cv.base())); 00287 } 00288 }; 00289 00291 Construct_min_vertex_2 construct_min_vertex_2_object () const 00292 { 00293 return Construct_min_vertex_2(m_base_tr->construct_min_vertex_2_object()); 00294 } 00295 00296 class Construct_max_vertex_2 00297 { 00298 protected: 00299 00300 Base_Construct_max_vertex_2 m_base; 00301 00302 public: 00303 Construct_max_vertex_2(const Base_Construct_max_vertex_2& base) : 00304 m_base(base) 00305 {} 00306 00307 Point_2 operator() (const X_monotone_curve_2& cv) const 00308 { 00309 return Point_2(m_base(cv.base())); 00310 } 00311 }; 00312 00314 Construct_max_vertex_2 construct_max_vertex_2_object () const 00315 { 00316 return Construct_max_vertex_2(m_base_tr->construct_max_vertex_2_object()); 00317 } 00318 00319 00320 class Is_vertical_2 00321 { 00322 protected: 00323 00324 Base_Is_vertical_2 m_base; 00325 00326 public: 00327 Is_vertical_2(const Base_Is_vertical_2& base) : m_base(base) 00328 {} 00329 00330 bool operator() (const X_monotone_curve_2& cv) const 00331 { 00332 return (m_base(cv.base())); 00333 } 00334 }; 00335 00337 Is_vertical_2 is_vertical_2_object() const 00338 { 00339 return Is_vertical_2(m_base_tr->is_vertical_2_object()); 00340 } 00341 00342 00343 class Compare_y_at_x_2 00344 { 00345 protected: 00346 00347 Base_Compare_y_at_x_2 m_base; 00348 00349 public: 00350 Compare_y_at_x_2(const Base_Compare_y_at_x_2& base) : m_base(base) 00351 {} 00352 00353 Comparison_result operator() (const Point_2& p, 00354 const X_monotone_curve_2& cv) const 00355 { 00356 return m_base(p.base(), cv.base()); 00357 } 00358 }; 00359 00361 Compare_y_at_x_2 compare_y_at_x_2_object() const 00362 { 00363 return Compare_y_at_x_2(m_base_tr->compare_y_at_x_2_object()); 00364 } 00365 00366 00367 class Compare_y_at_x_right_2 00368 { 00369 protected: 00370 00371 Base_Compare_y_at_x_right_2 m_base; 00372 00373 public: 00374 Compare_y_at_x_right_2(const Base_Compare_y_at_x_right_2& base) : 00375 m_base(base) 00376 {} 00377 00378 Comparison_result operator() (const X_monotone_curve_2& cv1, 00379 const X_monotone_curve_2& cv2, 00380 const Point_2& p) const 00381 { 00382 return m_base(cv1.base(), cv2.base(), p.base()); 00383 } 00384 }; 00385 00387 Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const 00388 { 00389 return Compare_y_at_x_right_2(m_base_tr->compare_y_at_x_right_2_object()); 00390 } 00391 00392 00393 class Equal_2 00394 { 00395 protected: 00396 00397 Base_Equal_2 m_base; 00398 00399 public: 00400 Equal_2(const Base_Equal_2& base) : m_base(base) 00401 {} 00402 00403 bool operator() (const Point_2& p1, const Point_2& p2) const 00404 { 00405 return m_base(p1.base(), p2.base()); 00406 } 00407 }; 00408 00410 Equal_2 equal_2_object() const 00411 { 00412 return Equal_2(m_base_tr->equal_2_object()); 00413 } 00414 00415 00416 class Split_2 00417 { 00418 protected: 00419 00420 Base_Split_2 m_base; 00421 00422 public: 00423 Split_2(const Base_Split_2& base) : m_base(base) 00424 {} 00425 00426 void operator() (const X_monotone_curve_2& cv, 00427 const Point_2& p, 00428 X_monotone_curve_2& c1, X_monotone_curve_2& c2) const 00429 { 00430 m_base(cv.base(), p.base(), c1.base(), c2.base()); 00431 } 00432 }; 00433 00435 Split_2 split_2_object() const 00436 { 00437 return Split_2(m_base_tr->split_2_object()); 00438 } 00439 00440 00441 class Intersect_2 00442 { 00443 protected: 00444 00445 Base_Intersect_2 m_base; 00446 Base_Compare_xy_2 m_base_cmp_xy; 00447 Base_Construct_min_vertex_2 m_ctr_min_v; 00448 00449 public: 00450 Intersect_2(Base_Intersect_2& base, 00451 Base_Compare_xy_2& base_cmp_xy, 00452 Base_Construct_min_vertex_2& base_ctr_min_v) : 00453 m_base(base), 00454 m_base_cmp_xy(base_cmp_xy), 00455 m_ctr_min_v(base_ctr_min_v) 00456 {} 00457 00458 template<class OutputIterator> 00459 OutputIterator operator() (const X_monotone_curve_2& cv1, 00460 const X_monotone_curve_2& cv2, 00461 OutputIterator oi) const 00462 { 00463 const std::pair<Base_Point_2, unsigned int> *base_pt; 00464 const Base_X_monotone_curve_2 *overlap_cv; 00465 00466 OutputIterator oi_end; 00467 if(m_base_cmp_xy(m_ctr_min_v(cv1.base()), 00468 m_ctr_min_v(cv2.base())) == LARGER) 00469 oi_end = m_base(cv1.base(), cv2.base(), oi); 00470 else 00471 oi_end = m_base(cv2.base(), cv1.base(), oi); 00472 00473 // convert objects that are associated with Base_X_monotone_curve_2 to 00474 // the extenede X_monotone_curve_2 00475 for(; oi != oi_end; ++oi) 00476 { 00477 base_pt = object_cast<std::pair<Base_Point_2, unsigned int> >(&(*oi)); 00478 00479 if (base_pt != NULL) 00480 { 00481 Point_2 point_plus (base_pt->first); // the extended point 00482 *oi = CGAL::make_object(std::make_pair(point_plus, 00483 base_pt->second)); 00484 } 00485 else 00486 { 00487 overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi)); 00488 CGAL_assertion(overlap_cv != NULL); 00489 *oi = CGAL::make_object (X_monotone_curve_2 (*overlap_cv)); 00490 } 00491 } 00492 //return past-end iterator 00493 return oi_end; 00494 } 00495 }; 00496 00498 Intersect_2 intersect_2_object() const 00499 { 00500 return Intersect_2(m_base_tr->intersect_2_object(), 00501 m_base_tr->compare_xy_2_object(), 00502 m_base_tr->construct_min_vertex_2_object()); 00503 } 00504 00505 00506 class Compare_endpoints_xy_2 00507 { 00508 protected: 00509 00510 Base_Compare_endpoints_xy_2 m_base; 00511 00512 public: 00513 Compare_endpoints_xy_2(const Base_Compare_endpoints_xy_2& base) : 00514 m_base(base) 00515 {} 00516 00517 Comparison_result operator()(const X_monotone_curve_2& cv) const 00518 { 00519 return (m_base(cv)); 00520 00521 } 00522 }; 00523 00525 Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const 00526 { 00527 return Compare_endpoints_xy_2(m_base_tr->compare_endpoints_xy_2_object()); 00528 } 00529 00530 00531 class Construct_opposite_2 00532 { 00533 protected: 00534 00535 Base_Construct_opposite_2 m_base; 00536 00537 public: 00538 Construct_opposite_2(Base_Construct_opposite_2& base) :m_base(base) 00539 {} 00540 00541 X_monotone_curve_2 operator()(const X_monotone_curve_2& cv) const 00542 { 00543 return (X_monotone_curve_2(m_base(cv))); 00544 } 00545 }; 00546 00548 Construct_opposite_2 construct_opposite_2_object() const 00549 { 00550 return Construct_opposite_2(m_base_tr->construct_opposite_2_object()); 00551 } 00552 00553 }; 00554 00555 CGAL_END_NAMESPACE 00556 00557 #endif