BWAPI
|
00001 // Copyright (c) 1997 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_agg_meta_traits.h $ 00015 // $Id: Gps_agg_meta_traits.h 50373 2009-07-05 14:44:48Z efif $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 00020 #ifndef CGAL_GPS_AGG_META_TRAITS_H 00021 #define CGAL_GPS_AGG_META_TRAITS_H 00022 00023 #include <vector> 00024 #include <boost/mpl/assert.hpp> 00025 #include <CGAL/Boolean_set_operations_2/Gps_traits_decorator.h> 00026 #include <CGAL/Boolean_set_operations_2/Curve_with_halfedge.h> 00027 #include <CGAL/Boolean_set_operations_2/Point_with_vertex.h> 00028 00029 CGAL_BEGIN_NAMESPACE 00030 00031 template <class Arrangement_> 00032 class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_> 00033 { 00034 protected: 00035 typedef Arrangement_ Arrangement; 00036 typedef typename Arrangement::Halfedge_handle Halfedge_handle; 00037 typedef Curve_with_halfedge<Arrangement_> Base; 00038 00039 const Arrangement* m_arr; // pointer to the arrangement containing the edge. 00040 unsigned int m_bc; // the boudary counter of the halfedge with the same 00041 //direction as the curve 00042 00043 unsigned int m_twin_bc; // the boudary counter of the halfedge with the same 00044 //direction as the curve 00045 00046 public: 00047 00048 Gps_agg_curve_data() : 00049 Base(), 00050 m_arr(NULL), 00051 m_bc(0), 00052 m_twin_bc(0) 00053 {} 00054 00055 Gps_agg_curve_data(const Arrangement* arr, 00056 Halfedge_handle he, 00057 unsigned int bc, 00058 unsigned int twin_bc): 00059 Base(he), 00060 m_arr(arr), 00061 m_bc(bc), 00062 m_twin_bc(twin_bc) 00063 {} 00064 00065 unsigned int bc() const 00066 { 00067 return m_bc; 00068 } 00069 00070 unsigned int twin_bc() const 00071 { 00072 return m_twin_bc; 00073 } 00074 00075 unsigned int& bc() 00076 { 00077 return m_bc; 00078 } 00079 00080 unsigned int& twin_bc() 00081 { 00082 return m_twin_bc; 00083 } 00084 00085 void set_bc(unsigned int bc) 00086 { 00087 m_bc = bc; 00088 } 00089 00090 void set_twin_bc(unsigned int twin_bc) 00091 { 00092 m_twin_bc = twin_bc; 00093 } 00094 00095 const Arrangement* arr() const 00096 { 00097 return m_arr; 00098 } 00099 00100 }; 00101 00102 00103 template <class Arrangement_> 00104 class Gps_agg_meta_traits : 00105 public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2, 00106 Gps_agg_curve_data<Arrangement_>, 00107 Point_with_vertex<Arrangement_> > 00108 { 00109 typedef Arrangement_ Arrangement; 00110 typedef typename Arrangement::Traits_adaptor_2 Traits; 00111 00112 typedef typename Traits::X_monotone_curve_2 Base_X_monotone_curve_2; 00113 typedef typename Traits::Point_2 Base_Point_2; 00114 typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2; 00115 typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2; 00116 typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2; 00117 typedef typename Traits::Compare_xy_2 Base_Compare_xy_2; 00118 typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2; 00119 typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2; 00120 typedef typename Traits::Intersect_2 Base_Intersect_2; 00121 typedef typename Traits::Split_2 Base_Split_2; 00122 00123 typedef typename Traits::Parameter_space_in_x_2 Base_Parameter_space_in_x_2; 00124 typedef typename Traits::Compare_y_near_boundary_2 00125 Base_Compare_y_near_boundary_2; 00126 00127 typedef typename Traits::Parameter_space_in_y_2 Base_Parameter_space_in_y_2; 00128 typedef typename Traits::Compare_x_near_boundary_2 00129 Base_Compare_x_near_boundary_2; 00130 00131 00132 typedef Gps_agg_meta_traits<Traits> Self; 00133 typedef Gps_traits_decorator<Traits, 00134 Gps_agg_curve_data<Arrangement_>, 00135 Point_with_vertex<Arrangement_> > 00136 Base; 00137 00138 public: 00139 typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; 00140 typedef typename Base::Point_2 Point_2; 00141 typedef typename Traits::Has_left_category Has_left_category; 00142 typedef typename Traits::Has_merge_category Has_merge_category; 00143 00144 typedef typename Arrangement::Arr_left_side_tag Arr_left_side_tag; 00145 typedef typename Arrangement::Arr_bottom_side_tag Arr_bottom_side_tag; 00146 typedef typename Arrangement::Arr_top_side_tag Arr_top_side_tag; 00147 typedef typename Arrangement::Arr_right_side_tag Arr_right_side_tag; 00148 00149 // a side is either oblivious or open (unbounded) 00150 BOOST_MPL_ASSERT( 00151 (boost::mpl::or_< 00152 boost::is_same< Arr_left_side_tag, Arr_oblivious_side_tag >, 00153 boost::is_same< Arr_left_side_tag, Arr_open_side_tag > > 00154 ) 00155 ); 00156 BOOST_MPL_ASSERT( 00157 (boost::mpl::or_< 00158 boost::is_same< Arr_bottom_side_tag, Arr_oblivious_side_tag >, 00159 boost::is_same< Arr_bottom_side_tag, Arr_open_side_tag > > 00160 ) 00161 ); 00162 BOOST_MPL_ASSERT( 00163 (boost::mpl::or_< 00164 boost::is_same< Arr_top_side_tag, Arr_oblivious_side_tag >, 00165 boost::is_same< Arr_top_side_tag, Arr_open_side_tag > > 00166 ) 00167 ); 00168 BOOST_MPL_ASSERT( 00169 (boost::mpl::or_< 00170 boost::is_same< Arr_right_side_tag, Arr_oblivious_side_tag >, 00171 boost::is_same< Arr_right_side_tag, Arr_open_side_tag > > 00172 ) 00173 ); 00174 00175 typedef typename Base::Curve_data Curve_data; 00176 typedef typename Base::Point_data Point_data; 00177 00178 typedef typename Arrangement::Halfedge_handle Halfedge_handle; 00179 typedef typename Arrangement::Vertex_handle Vertex_handle; 00180 00181 00182 Gps_agg_meta_traits() 00183 {} 00184 00185 Gps_agg_meta_traits(const Traits & base_tr) : Base(base_tr) 00186 {} 00187 00188 class Intersect_2 00189 { 00190 private: 00191 Base_Intersect_2 m_base; 00192 Base_Compare_endpoints_xy_2 m_base_cmp_endpoints; 00193 Base_Compare_xy_2 m_base_cmp_xy; 00194 Base_Construct_min_vertex_2 m_base_ctr_min_v; 00195 00196 public: 00198 Intersect_2 (const Base_Intersect_2& base, 00199 const Base_Compare_endpoints_xy_2& base_cmp_endpoints, 00200 const Base_Compare_xy_2& base_cmp_xy, 00201 const Base_Construct_min_vertex_2& base_ctr_min_v) : 00202 m_base(base), 00203 m_base_cmp_endpoints(base_cmp_endpoints), 00204 m_base_cmp_xy(base_cmp_xy), 00205 m_base_ctr_min_v(base_ctr_min_v) 00206 {} 00207 00208 template<class OutputIterator> 00209 OutputIterator operator() (const X_monotone_curve_2& cv1, 00210 const X_monotone_curve_2& cv2, 00211 OutputIterator oi) const 00212 { 00213 if (cv1.data().arr() == cv2.data().arr()) 00214 { 00215 return (oi); // the curves are disjoint-interior because they 00216 // are already at the same arrangement. 00217 } 00218 00219 const std::pair<Base_Point_2, unsigned int> *base_pt; 00220 const Base_X_monotone_curve_2 *overlap_cv; 00221 OutputIterator oi_end; 00222 if(m_base_cmp_xy(m_base_ctr_min_v(cv1.base()), 00223 m_base_ctr_min_v(cv2.base())) == LARGER) 00224 oi_end = m_base(cv1.base(), cv2.base(), oi); 00225 else 00226 oi_end = m_base(cv2.base(), cv1.base(), oi); 00227 00228 // convert objects that are associated with Base_X_monotone_curve_2 to 00229 // the extenede X_monotone_curve_2 00230 for(; oi != oi_end; ++oi) 00231 { 00232 base_pt = object_cast<std::pair<Base_Point_2, unsigned int> >(&(*oi)); 00233 00234 if (base_pt != NULL) 00235 { 00236 Point_2 point_plus (base_pt->first); // the extended point 00237 *oi = CGAL::make_object(std::make_pair(point_plus, 00238 base_pt->second)); 00239 } 00240 else 00241 { 00242 overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi)); 00243 00244 if (overlap_cv != NULL) 00245 { 00246 unsigned int ov_bc; 00247 unsigned int ov_twin_bc; 00248 if (m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2)) 00249 { 00250 // cv1 and cv2 have the same directions 00251 ov_bc = cv1.data().bc() + cv2.data().bc(); 00252 ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc(); 00253 } 00254 else 00255 { 00256 // cv1 and cv2 have opposite directions 00257 ov_bc = cv1.data().bc() + cv2.data().twin_bc(); 00258 ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc(); 00259 } 00260 00261 if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1)) 00262 { 00263 // overlap_cv, cv1 have opposite directions 00264 std::swap(ov_bc, ov_twin_bc); 00265 } 00266 00267 Curve_data cv_data(cv1.data().arr(), 00268 Halfedge_handle(), 00269 ov_bc, ov_twin_bc); 00270 *oi = CGAL::make_object (X_monotone_curve_2(*overlap_cv, cv_data)); 00271 } 00272 } 00273 } 00274 //return past-end iterator 00275 return oi_end; 00276 } 00277 }; 00278 00280 Intersect_2 intersect_2_object () const 00281 { 00282 return Intersect_2(this->m_base_tr->intersect_2_object(), 00283 this->m_base_tr->compare_endpoints_xy_2_object(), 00284 this->m_base_tr->compare_xy_2_object(), 00285 this->m_base_tr->construct_min_vertex_2_object()); 00286 } 00287 00288 00289 class Split_2 00290 { 00291 private: 00292 Base_Split_2 m_base_split; 00293 00294 public: 00295 00297 Split_2 (const Base_Split_2& base) : m_base_split (base) 00298 {} 00299 00300 void operator() (const X_monotone_curve_2& cv, const Point_2 & p, 00301 X_monotone_curve_2& c1, X_monotone_curve_2& c2) const 00302 { 00303 m_base_split(cv.base(), 00304 p.base(), 00305 c1.base(), 00306 c2.base()); 00307 const Curve_data& cv_data = cv.data(); 00308 c1.set_data(Curve_data(cv_data.arr(), 00309 Halfedge_handle(), 00310 cv_data.bc(), 00311 cv_data.twin_bc())); 00312 00313 c2.set_data(Curve_data(cv_data.arr(), 00314 Halfedge_handle(), 00315 cv_data.bc(), 00316 cv_data.twin_bc())); 00317 } 00318 }; 00319 00321 Split_2 split_2_object () const 00322 { 00323 return Split_2(this->m_base_tr->split_2_object()); 00324 } 00325 00326 00327 class Construct_min_vertex_2 00328 { 00329 private: 00330 Base_Construct_min_vertex_2 m_base; 00331 00332 public: 00333 00334 Construct_min_vertex_2(const Base_Construct_min_vertex_2& base) : 00335 m_base(base) 00336 {} 00337 00343 Point_2 operator() (const X_monotone_curve_2 & cv) const 00344 { 00345 if(cv.data().halfedge() == Halfedge_handle()) 00346 return (Point_2 (m_base(cv.base()))); 00347 00348 CGAL_assertion 00349 ((Arr_halfedge_direction)cv.data().halfedge()->direction() == 00350 ARR_LEFT_TO_RIGHT); 00351 return Point_2 (m_base(cv.base()), cv.data().halfedge()->source()); 00352 } 00353 }; 00354 00356 Construct_min_vertex_2 construct_min_vertex_2_object () const 00357 { 00358 return Construct_min_vertex_2(this->m_base_tr-> 00359 construct_min_vertex_2_object()); 00360 } 00361 00362 00363 class Construct_max_vertex_2 00364 { 00365 private: 00366 Base_Construct_max_vertex_2 m_base; 00367 00368 public: 00369 00370 Construct_max_vertex_2(const Base_Construct_max_vertex_2& base): 00371 m_base(base) 00372 {} 00373 00379 Point_2 operator() (const X_monotone_curve_2 & cv) const 00380 { 00381 if(cv.data().halfedge() == Halfedge_handle()) 00382 return (Point_2 (m_base(cv.base()))); 00383 00384 CGAL_assertion((Arr_halfedge_direction)cv.data().halfedge()->direction() == 00385 ARR_LEFT_TO_RIGHT); 00386 return Point_2 (m_base(cv.base()), cv.data().halfedge()->target()); 00387 } 00388 }; 00389 00391 Construct_max_vertex_2 construct_max_vertex_2_object () const 00392 { 00393 return Construct_max_vertex_2(this->m_base_tr-> 00394 construct_max_vertex_2_object()); 00395 } 00396 00397 00398 class Compare_xy_2 00399 { 00400 private: 00401 Base_Compare_xy_2 m_base; 00402 00403 public: 00404 00405 Compare_xy_2(const Base_Compare_xy_2& base): 00406 m_base(base) 00407 {} 00408 00409 00415 Comparison_result operator() (const Point_2& p1, const Point_2& p2) const 00416 { 00417 const Point_data& inf1 = p1.data(); 00418 const Point_data& inf2 = p2.data(); 00419 00420 if(inf1.vertex() == Vertex_handle() || inf2.vertex() == Vertex_handle()) 00421 { 00422 return(m_base(p1.base(), p2.base())); 00423 } 00424 00425 if(inf1.vertex() == inf2.vertex()) 00426 return (EQUAL); 00427 00428 return(m_base(p1.base(), p2.base())); 00429 } 00430 }; 00431 00432 00434 Compare_xy_2 compare_xy_2_object () const 00435 { 00436 return Compare_xy_2(this->m_base_tr->compare_xy_2_object()); 00437 } 00438 00439 00440 00441 // left-right 00442 00443 00444 class Parameter_space_in_x_2 00445 { 00446 private: 00447 Base_Parameter_space_in_x_2 m_base; 00448 00449 public: 00450 00451 Parameter_space_in_x_2(const Base_Parameter_space_in_x_2& base): 00452 m_base(base) 00453 {} 00454 00457 Arr_parameter_space operator() (const X_monotone_curve_2 & cv, 00458 const Arr_curve_end& end) const 00459 { 00460 return m_base(cv.base(), end); 00461 } 00462 00465 Arr_parameter_space operator() (const X_monotone_curve_2 & cv) const 00466 { 00467 return m_base(cv.base()); 00468 } 00469 00472 Arr_parameter_space operator() (const Point_2 & pt) const 00473 { 00474 return m_base(pt.base()); 00475 } 00476 }; 00477 00479 Parameter_space_in_x_2 parameter_space_in_x_2_object () const 00480 { 00481 return Parameter_space_in_x_2( 00482 this->m_base_tr->parameter_space_in_x_2_object() 00483 ); 00484 } 00485 00486 class Compare_y_near_boundary_2 00487 { 00488 private: 00489 Base_Compare_y_near_boundary_2 m_base; 00490 00491 public: 00492 00493 Compare_y_near_boundary_2(const Base_Compare_y_near_boundary_2& base): 00494 m_base(base) 00495 {} 00496 00500 Comparison_result operator() (const X_monotone_curve_2 & xcv1, 00501 const X_monotone_curve_2 & xcv2, 00502 Arr_curve_end ce) const 00503 { 00504 return m_base(xcv1, xcv2, ce); 00505 } 00506 }; 00507 00509 Compare_y_near_boundary_2 compare_y_near_boundary_2_object () const 00510 { 00511 return Compare_y_near_boundary_2( 00512 this->m_base_tr->compare_y_near_boundary_2_object() 00513 ); 00514 } 00515 00516 // TODO Compare_y_on_boundary_2 00517 // TODO Is_on_x_identification_2 00518 00519 // bottom-top 00520 00521 00522 class Parameter_space_in_y_2 00523 { 00524 private: 00525 Base_Parameter_space_in_y_2 m_base; 00526 00527 public: 00528 00529 Parameter_space_in_y_2(const Base_Parameter_space_in_y_2& base): 00530 m_base(base) 00531 {} 00532 00535 Arr_parameter_space operator() (const X_monotone_curve_2 & cv, 00536 const Arr_curve_end& end) const 00537 { 00538 return m_base(cv.base(), end); 00539 } 00540 00543 Arr_parameter_space operator() (const X_monotone_curve_2 & cv) const 00544 { 00545 return m_base(cv.base()); 00546 } 00547 00550 Arr_parameter_space operator() (const Point_2 & pt) const 00551 { 00552 return m_base(pt.base()); 00553 } 00554 00555 }; 00556 00558 Parameter_space_in_y_2 parameter_space_in_y_2_object () const 00559 { 00560 return Parameter_space_in_y_2 00561 (this->m_base_tr->parameter_space_in_y_2_object()); 00562 } 00563 00564 class Compare_x_near_boundary_2 00565 { 00566 private: 00567 Base_Compare_x_near_boundary_2 m_base; 00568 00569 public: 00570 00571 Compare_x_near_boundary_2(const Base_Compare_x_near_boundary_2& base): 00572 m_base(base) 00573 {} 00574 00578 Comparison_result operator() (const Point_2 & p, 00579 const X_monotone_curve_2 & xcv, 00580 Arr_curve_end ce) const 00581 { 00582 return m_base(p, xcv, ce); 00583 } 00584 00587 Comparison_result operator() (const X_monotone_curve_2 & xcv1, 00588 Arr_curve_end ce1, 00589 const X_monotone_curve_2 & xcv2, 00590 Arr_curve_end ce2) const 00591 { 00592 return m_base(xcv1, ce1, xcv2, ce2); 00593 } 00594 }; 00595 00597 Compare_x_near_boundary_2 compare_x_near_boundary_2_object () const 00598 { 00599 return Compare_x_near_boundary_2 00600 (this->m_base_tr->compare_x_near_boundary_2_object()); 00601 } 00602 00603 // TODO Compare_x_on_boundary_2 00604 // TODO Is_on_y_identification_2 00605 00606 }; 00607 00608 CGAL_END_NAMESPACE 00609 00610 #endif