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_simplifier_traits.h $ 00015 // $Id: Gps_simplifier_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_SIMPLIFIER_TRAITS_H 00021 #define CGAL_GPS_SIMPLIFIER_TRAITS_H 00022 00023 #include <CGAL/Boolean_set_operations_2/Gps_traits_decorator.h> 00024 00025 CGAL_BEGIN_NAMESPACE 00026 00027 class Gps_simplifier_curve_data 00028 { 00029 protected: 00030 unsigned int m_bc; 00031 unsigned int m_twin_bc; 00032 unsigned int m_index; 00033 00034 public: 00035 Gps_simplifier_curve_data() 00036 {} 00037 00038 Gps_simplifier_curve_data(unsigned int bc, 00039 unsigned int twin_bc, 00040 unsigned int index): 00041 m_bc(bc), 00042 m_twin_bc(twin_bc), 00043 m_index(index) 00044 {} 00045 00046 unsigned int bc() const 00047 { 00048 return m_bc; 00049 } 00050 00051 unsigned int twin_bc() const 00052 { 00053 return m_twin_bc; 00054 } 00055 00056 unsigned int index() const 00057 { 00058 return m_index; 00059 } 00060 00061 unsigned int& index() 00062 { 00063 return m_index; 00064 } 00065 00066 unsigned int& twin_bc() 00067 { 00068 return m_twin_bc; 00069 } 00070 00071 void set_bc(unsigned int bc) 00072 { 00073 m_bc = bc; 00074 } 00075 00076 void set_twin_bc(unsigned int twin_bc) 00077 { 00078 m_twin_bc = twin_bc; 00079 } 00080 00081 void set_index(unsigned int index) 00082 { 00083 m_index = index; 00084 } 00085 }; 00086 00087 struct Gps_simplifier_point_data 00088 { 00089 protected: 00090 unsigned int m_index; 00091 00092 public: 00093 Gps_simplifier_point_data() 00094 {} 00095 00096 Gps_simplifier_point_data(unsigned int index) : m_index(index) 00097 {} 00098 00099 unsigned int index() const 00100 { 00101 return m_index; 00102 } 00103 00104 void set_index(unsigned int index) 00105 { 00106 m_index = index; 00107 } 00108 }; 00109 00110 template <class Traits_> 00111 class Gps_simplifier_traits : 00112 public Gps_traits_decorator<Traits_, 00113 Gps_simplifier_curve_data, 00114 Gps_simplifier_point_data> 00115 { 00116 public: 00117 typedef Traits_ Traits; 00118 typedef Gps_traits_decorator<Traits_, 00119 Gps_simplifier_curve_data, 00120 Gps_simplifier_point_data> Base; 00121 typedef Gps_simplifier_traits<Traits> Self; 00122 typedef typename Traits::X_monotone_curve_2 Base_X_monotone_curve_2; 00123 typedef typename Traits::Point_2 Base_Point_2; 00124 typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2; 00125 typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2; 00126 typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2; 00127 typedef typename Traits::Compare_xy_2 Base_Compare_xy_2; 00128 typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2; 00129 typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2; 00130 typedef typename Traits::Intersect_2 Base_Intersect_2; 00131 typedef typename Traits::Split_2 Base_Split_2; 00132 00133 protected: 00134 unsigned int m_pgn_size; 00135 00136 00137 public: 00138 00139 typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; 00140 typedef typename Base::Point_2 Point_2; 00141 00142 typedef typename Base::Curve_data Curve_data; 00143 typedef typename Base::Point_data Point_data; 00144 00145 Gps_simplifier_traits() 00146 {} 00147 00148 Gps_simplifier_traits(const Traits & tr) : Base(tr) 00149 {} 00150 00151 unsigned int polygon_size() const 00152 { 00153 return m_pgn_size; 00154 } 00155 00156 void set_polygon_size(unsigned int pgn_size) 00157 { 00158 m_pgn_size = pgn_size; 00159 } 00160 00161 bool is_valid_index(unsigned int index) const 00162 { 00163 return (index < m_pgn_size); 00164 } 00165 00166 unsigned int invalid_index() const 00167 { 00168 return (m_pgn_size); 00169 } 00170 00171 00172 class Intersect_2 00173 { 00174 private: 00175 00176 Base_Intersect_2 m_base; 00177 Base_Compare_endpoints_xy_2 m_base_cmp_endpoints; 00178 Base_Compare_xy_2 m_base_cmp_xy; 00179 Base_Construct_min_vertex_2 m_ctr_min_v; 00180 const Self * m_self_tr; 00181 00182 public: 00183 00185 Intersect_2 (const Base_Intersect_2& base, 00186 const Base_Compare_endpoints_xy_2& base_cmp_endpoints, 00187 const Base_Compare_xy_2& base_cmp_xy, 00188 const Base_Construct_min_vertex_2& , 00189 const Self* tr) : 00190 m_base(base), 00191 m_base_cmp_endpoints(base_cmp_endpoints), 00192 m_base_cmp_xy(base_cmp_xy), 00193 m_self_tr(tr) 00194 {} 00195 00196 template<class OutputIterator> 00197 OutputIterator operator() (const X_monotone_curve_2& cv1, 00198 const X_monotone_curve_2& cv2, 00199 OutputIterator oi) const 00200 { 00202 //if(m_self_tr->is_valid_index(cv1.data().index()) && 00203 // m_self_tr->is_valid_index(cv2.data().index())) 00204 //{ 00205 // unsigned int index_diff = 00206 // (cv1.data().index() > cv2.data().index()) ? 00207 // (cv1.data().index() - cv2.data().index()): 00208 // (cv2.data().index() - cv1.data().index()); 00209 00210 // if(index_diff == 1 ||index_diff == m_self_tr->polygon_size() -1) 00211 // { 00212 // return (oi); 00213 // } 00214 //} 00215 const std::pair<Base_Point_2, unsigned int> *base_pt; 00216 const Base_X_monotone_curve_2 *overlap_cv; 00217 OutputIterator oi_end; 00218 if(m_base_cmp_xy(m_ctr_min_v(cv1.base()), 00219 m_ctr_min_v(cv2.base())) == LARGER) 00220 oi_end = m_base(cv1.base(), cv2.base(), oi); 00221 else 00222 oi_end = m_base(cv2.base(), cv1.base(), oi); 00223 00224 // convert objects that are associated with Base_X_monotone_curve_2 to 00225 // the extenede X_monotone_curve_2 00226 for(; oi != oi_end; ++oi) 00227 { 00228 base_pt = object_cast<std::pair<Base_Point_2, unsigned int> >(&(*oi)); 00229 00230 if (base_pt != NULL) 00231 { 00232 Point_data pt_data(m_self_tr->invalid_index()); 00233 Point_2 point_plus (base_pt->first, pt_data); // the extended point 00234 *oi = CGAL::make_object(std::make_pair(point_plus, 00235 base_pt->second)); 00236 } 00237 else 00238 { 00239 overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi)); 00240 00241 if (overlap_cv != NULL) 00242 { 00243 unsigned int ov_bc; 00244 unsigned int ov_twin_bc; 00245 if(m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2)) 00246 { 00247 // cv1 and cv2 have the same directions 00248 ov_bc = cv1.data().bc() + cv2.data().bc(); 00249 ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc(); 00250 } 00251 else 00252 { 00253 // cv1 and cv2 have opposite directions 00254 ov_bc = cv1.data().bc() + cv2.data().twin_bc(); 00255 ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc(); 00256 } 00257 00258 if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1)) 00259 { 00260 // overlap_cv, cv1 have opposite directions 00261 std::swap(ov_bc, ov_twin_bc); 00262 } 00263 00264 Curve_data cv_data(ov_bc, ov_twin_bc, m_self_tr->invalid_index()); 00265 *oi = CGAL::make_object (X_monotone_curve_2 (*overlap_cv, cv_data)); 00266 } 00267 } 00268 } 00269 //return past-end iterator 00270 return oi_end; 00271 } 00272 }; 00273 00275 Intersect_2 intersect_2_object () const 00276 { 00277 return Intersect_2(this->m_base_tr->intersect_2_object(), 00278 this->m_base_tr->compare_endpoints_xy_2_object(), 00279 this->m_base_tr->compare_xy_2_object(), 00280 this->m_base_tr->construct_min_vertex_2_object(), 00281 this); 00282 } 00283 00284 class Split_2 00285 { 00286 private: 00287 Base_Split_2 m_base_split; 00288 const Self * m_self_tr; 00289 00290 public: 00291 00293 Split_2 (const Base_Split_2& base, const Self* tr) : 00294 m_base_split(base), 00295 m_self_tr(tr) 00296 {} 00297 00298 void operator() (const X_monotone_curve_2& cv, const Point_2 & p, 00299 X_monotone_curve_2& c1, X_monotone_curve_2& c2) const 00300 { 00301 m_base_split(cv.base(), 00302 p.base(), 00303 c1.base(), 00304 c2.base()); 00305 const Curve_data& cv_data = cv.data(); 00306 c1.set_data(Curve_data(cv_data.bc(), 00307 cv_data.twin_bc(), 00308 m_self_tr->invalid_index())); 00309 00310 c2.set_data(Curve_data(cv_data.bc(), 00311 cv_data.twin_bc(), 00312 m_self_tr->invalid_index())); 00313 } 00314 }; 00315 00317 Split_2 split_2_object () const 00318 { 00319 return Split_2(this->m_base_tr->split_2_object(), this); 00320 } 00321 00322 class Construct_min_vertex_2 00323 { 00324 private: 00325 Base_Construct_min_vertex_2 m_base; 00326 Base_Compare_endpoints_xy_2 m_base_cmp_endpoints; 00327 const Self * m_self_tr; 00328 00329 public: 00330 00331 Construct_min_vertex_2(const Base_Construct_min_vertex_2& base, 00332 const Base_Compare_endpoints_xy_2& base_cmp_endpoints, 00333 const Self * tr): 00334 m_base(base), 00335 m_base_cmp_endpoints(base_cmp_endpoints), 00336 m_self_tr(tr) 00337 {} 00338 00344 Point_2 operator() (const X_monotone_curve_2 & cv) const 00345 { 00346 if(!m_self_tr->is_valid_index(cv.data().index())) 00347 { 00348 return Point_2 (m_base(cv.base()), m_self_tr->invalid_index()); 00349 } 00350 00351 Comparison_result res = m_base_cmp_endpoints(cv); 00352 Point_data pt_data; 00353 if(res == SMALLER) 00354 { 00355 // min vertex is the source 00356 pt_data.set_index(cv.data().index()); 00357 } 00358 else 00359 { 00360 // min vertex is the target 00361 pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size()); 00362 } 00363 return Point_2 (m_base(cv.base()), pt_data); 00364 } 00365 }; 00366 00368 Construct_min_vertex_2 construct_min_vertex_2_object () const 00369 { 00370 return Construct_min_vertex_2 00371 (this->m_base_tr->construct_min_vertex_2_object(), 00372 this->m_base_tr->compare_endpoints_xy_2_object(), 00373 this); 00374 } 00375 00376 00377 class Construct_max_vertex_2 00378 { 00379 private: 00380 Base_Construct_max_vertex_2 m_base; 00381 Base_Compare_endpoints_xy_2 m_base_cmp_endpoints; 00382 const Self * m_self_tr; 00383 00384 public: 00385 00386 Construct_max_vertex_2(const Base_Construct_max_vertex_2& base, 00387 const Base_Compare_endpoints_xy_2& base_cmp_endpoints, 00388 const Self * tr): 00389 m_base(base), 00390 m_base_cmp_endpoints(base_cmp_endpoints), 00391 m_self_tr(tr) 00392 {} 00393 00399 Point_2 operator() (const X_monotone_curve_2 & cv) const 00400 { 00401 if(!m_self_tr->is_valid_index(cv.data().index())) 00402 { 00403 return Point_2 (m_base(cv.base()), m_self_tr->invalid_index()); 00404 } 00405 Comparison_result res = m_base_cmp_endpoints(cv); 00406 Point_data pt_data; 00407 if(res == SMALLER) 00408 { 00409 // min vertex is the target 00410 pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size()); 00411 } 00412 else 00413 { 00414 // min vertex is the source 00415 pt_data.set_index(cv.data().index()); 00416 } 00417 return Point_2 (m_base(cv.base()), pt_data); 00418 } 00419 }; 00420 00422 Construct_max_vertex_2 construct_max_vertex_2_object () const 00423 { 00424 return Construct_max_vertex_2 00425 (this->m_base_tr->construct_max_vertex_2_object(), 00426 this->m_base_tr->compare_endpoints_xy_2_object(), 00427 this); 00428 } 00429 00430 class Compare_xy_2 00431 { 00432 private: 00433 Base_Compare_xy_2 m_base; 00434 const Self * m_self_tr; 00435 00436 public: 00437 Compare_xy_2(const Base_Compare_xy_2& base, 00438 const Self * tr): 00439 m_base(base), 00440 m_self_tr(tr) 00441 {} 00442 00443 00449 Comparison_result operator() (const Point_2& p1, const Point_2& p2) const 00450 { 00451 //if one of the indexes is invalid, compare p1 and p2 00452 if(! m_self_tr->is_valid_index(p1.data().index()) || 00453 ! m_self_tr->is_valid_index(p2.data().index())) 00454 return (m_base(p1.base(), p2.base())); 00455 00456 // if the two point has the same index, return EQUAL 00457 if(p1.data().index() == p2.data().index()) 00458 { 00459 return EQUAL; 00460 } 00461 00462 return (m_base(p1.base(), p2.base())); 00463 } 00464 }; 00465 00466 00468 Compare_xy_2 compare_xy_2_object () const 00469 { 00470 return Compare_xy_2(this->m_base_tr->compare_xy_2_object(), this); 00471 } 00472 }; 00473 00474 CGAL_END_NAMESPACE 00475 00476 #endif