BWAPI
|
00001 // Copyright (c) 1997 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Polygon/include/CGAL/Polygon_2.h $ 00019 // $Id: Polygon_2.h 41437 2008-01-03 19:13:08Z spion $ 00020 // 00021 // 00022 // Author(s) : Geert-Jan Giezeman <geert@cs.uu.nl> 00023 // Wieger Wesselink 00024 00025 #ifndef CGAL_POLYGON_2_H 00026 #define CGAL_POLYGON_2_H 00027 00028 #include <CGAL/basic.h> 00029 #include <vector> 00030 #include <list> 00031 #include <iterator> 00032 00033 #include <CGAL/circulator.h> 00034 #include <CGAL/enum.h> 00035 00036 #include <CGAL/Aff_transformation_2.h> 00037 00038 #include <CGAL/Polygon_2_algorithms.h> 00039 #include <CGAL/Polygon_2/Polygon_2_vertex_circulator.h> 00040 #include <CGAL/Polygon_2/Polygon_2_edge_iterator.h> 00041 #include <CGAL/Polygon_2/Polygon_2_edge_circulator.h> 00042 00043 CGAL_BEGIN_NAMESPACE 00044 00045 template <class Traits_P, class Container_P 00046 = std::vector<typename Traits_P::Point_2> > 00047 class Polygon_2 { 00048 00049 public: 00050 00051 typedef Traits_P Traits; 00052 typedef Container_P Container; 00053 00054 typedef typename Traits_P::FT FT; 00055 typedef typename Traits_P::Point_2 Point_2; 00056 typedef typename Traits_P::Segment_2 Segment_2; 00057 00058 typedef typename Container_P::difference_type difference_type; 00059 typedef typename Container_P::value_type value_type; 00060 typedef typename Container_P::pointer pointer; 00061 typedef typename Container_P::reference reference; 00062 typedef typename Container_P::const_reference const_reference; 00063 00064 00065 //-------------------------------------------------------// 00066 // this intermediary step is required by Sun C++ 4.1 00067 typedef typename Container_P::iterator iterator; 00068 typedef typename Container_P::const_iterator const_iterator; 00069 //-------------------------------------------------------// 00070 00071 typedef typename Container::iterator Vertex_iterator; 00072 typedef typename Container::iterator Vertex_const_iterator; 00073 //typedef typename Container::const_iterator Vertex_const_iterator; ?? 00074 00075 typedef Polygon_circulator<Container_P> Vertex_const_circulator; 00076 typedef Vertex_const_circulator Vertex_circulator; 00077 00078 typedef Polygon_2_edge_iterator<Traits_P,Container_P> 00079 Edge_const_iterator; 00080 00081 typedef Polygon_2_const_edge_circulator<Traits_P,Container_P> 00082 Edge_const_circulator; 00083 00084 //-------------------------------------------------------- 00085 // Creation 00086 //-------------------------------------------------------- 00087 00088 Polygon_2(const Traits & p_traits = Traits()) : traits(p_traits) {} 00089 00090 Polygon_2(const Polygon_2<Traits_P,Container_P>& polygon) 00091 : d_container(polygon.d_container), traits(polygon.traits) {} 00092 00093 template <class InputIterator> 00094 Polygon_2(InputIterator first, InputIterator last, 00095 Traits p_traits = Traits()) 00096 : d_container(), traits(p_traits) 00097 { 00098 // Sun STL switches off member templates for binary backward compat. 00099 std::copy(first, last, std::back_inserter(d_container)); 00100 } 00101 00102 //-------------------------------------------------------- 00103 // Operations 00104 //-------------------------------------------------------- 00105 00106 void set(Vertex_iterator pos, const Point_2& x) 00107 { *pos = x; } 00108 00109 void set(Polygon_circulator<Container>const &pos, const Point_2& x) 00110 { 00111 *pos.mod_iterator() = x; 00112 } 00113 00114 Vertex_iterator insert(Vertex_iterator pos, const Point_2& x) 00115 { 00116 return d_container.insert(pos,x); 00117 } 00118 00119 Vertex_iterator insert(Vertex_circulator pos, const Point_2& x) 00120 { 00121 return d_container.insert(pos.mod_iterator(),x); 00122 } 00123 00124 template <class InputIterator> 00125 void insert(Vertex_iterator pos, 00126 InputIterator first, 00127 InputIterator last) 00128 { d_container.insert(pos, first, last); } 00129 00130 template <class InputIterator> 00131 void insert(Vertex_circulator pos, 00132 InputIterator first, 00133 InputIterator last) 00134 { d_container.insert(pos.mod_iterator(), first, last); } 00135 00136 void push_back(const Point_2& x) 00137 { d_container.insert(d_container.end(), x); } 00138 00139 void erase(Vertex_iterator pos) 00140 { d_container.erase(pos); } 00141 00142 void erase(Vertex_circulator pos) 00143 { d_container.erase(pos.mod_iterator()); } 00144 00145 void erase(Vertex_iterator first, Vertex_iterator last) 00146 { 00147 d_container.erase(first, last); 00148 } 00149 00150 void clear() 00151 { 00152 d_container.clear(); 00153 } 00154 00155 void reverse_orientation() 00156 { 00157 if (size() <= 1) 00158 return; 00159 typename Container_P::iterator i = d_container.begin(); 00160 std::reverse(++i, d_container.end()); 00161 } 00162 00163 //-------------------------------------------------------- 00164 // Traversal of a polygon 00165 //-------------------------------------------------------- 00166 00167 // Vertex_iterator vertices_begin() 00168 // { return d_container.begin(); } 00169 00170 // Vertex_iterator vertices_end() 00171 // { return d_container.end(); } 00172 00173 Vertex_const_iterator vertices_begin() const 00174 { return const_cast<Polygon_2&>(*this).d_container.begin(); } 00175 00176 Vertex_const_iterator vertices_end() const 00177 { return const_cast<Polygon_2&>(*this).d_container.end(); } 00178 00179 // Vertex_const_circulator vertices_circulator() const 00180 // { return Vertex_const_circulator(&d_container, d_container.begin()); } 00181 00182 Vertex_const_circulator vertices_circulator() const 00183 { 00184 Polygon_2& self = const_cast<Polygon_2&>(*this); 00185 return Vertex_const_circulator(&self.d_container, 00186 self.d_container.begin()); 00187 } 00188 00189 Edge_const_iterator edges_begin() const 00190 { return Edge_const_iterator(&d_container, d_container.begin()); } 00191 00192 Edge_const_iterator edges_end() const 00193 { return Edge_const_iterator(&d_container, d_container.end()); } 00194 00195 Edge_const_circulator edges_circulator() const 00196 { return Edge_const_circulator(vertices_circulator()); } 00197 00198 //-------------------------------------------------------- 00199 // Predicates 00200 //-------------------------------------------------------- 00201 00202 bool is_simple() const 00203 { 00204 return is_simple_2(d_container.begin(),d_container.end(), traits); 00205 } 00206 00207 bool is_convex() const 00208 { 00209 return is_convex_2(d_container.begin(),d_container.end(), traits); 00210 } 00211 00212 Orientation orientation() const 00213 { 00214 return orientation_2(d_container.begin(), d_container.end(), traits); 00215 } 00216 00217 Oriented_side oriented_side(const Point_2& value) const 00218 { 00219 return oriented_side_2(d_container.begin(), d_container.end(), 00220 value, traits); 00221 } 00222 00223 Bounded_side bounded_side(const Point_2& value) const 00224 { 00225 CGAL_polygon_precondition(is_simple()); 00226 return bounded_side_2(d_container.begin(), d_container.end(), 00227 value, traits); 00228 } 00229 00230 Bbox_2 bbox() const 00231 { 00232 return bbox_2(d_container.begin(), d_container.end()); 00233 } 00234 00235 FT area() const 00236 { 00237 return polygon_area_2(d_container.begin(), d_container.end(), traits); 00238 } 00239 00240 Vertex_const_iterator left_vertex() const 00241 { 00242 Polygon_2 &self = const_cast<Polygon_2&>(*this); 00243 return left_vertex_2(self.d_container.begin(), 00244 self.d_container.end(), traits); 00245 } 00246 00247 //Vertex_iterator left_vertex() 00248 //{ 00249 //return left_vertex_2(d_container.begin(), d_container.end(), traits); 00250 //} 00251 00252 Vertex_const_iterator right_vertex() const 00253 { 00254 Polygon_2 &self = const_cast<Polygon_2&>(*this); 00255 return right_vertex_2(self.d_container.begin(), 00256 self.d_container.end(), traits); 00257 } 00258 00259 // Vertex_iterator right_vertex() 00260 // { 00261 // return right_vertex_2(d_container.begin(), d_container.end(), traits); 00262 // } 00263 00264 Vertex_const_iterator top_vertex() const 00265 { 00266 Polygon_2 &self = const_cast<Polygon_2&>(*this); 00267 return top_vertex_2(self.d_container.begin(), 00268 self.d_container.end(), traits); 00269 } 00270 00271 // Vertex_iterator top_vertex() 00272 // { 00273 // return top_vertex_2(d_container.begin(), d_container.end(), traits); 00274 // } 00275 00276 Vertex_const_iterator bottom_vertex() const 00277 { 00278 Polygon_2 &self = const_cast<Polygon_2&>(*this); 00279 return bottom_vertex_2(self.d_container.begin(), 00280 self.d_container.end(), traits); 00281 } 00282 00283 // Vertex_iterator bottom_vertex() 00284 // { 00285 // return bottom_vertex_2(d_container.begin(), d_container.end(), traits); 00286 // } 00287 00288 bool is_counterclockwise_oriented() const 00289 { return orientation() == COUNTERCLOCKWISE; } 00290 00291 bool is_clockwise_oriented() const 00292 { return orientation() == CLOCKWISE; } 00293 00294 bool is_collinear_oriented() const 00295 { return orientation() == COLLINEAR; } 00296 00297 bool has_on_positive_side(const Point_2& q) const 00298 { return oriented_side(q) == ON_POSITIVE_SIDE; } 00299 00300 bool has_on_negative_side(const Point_2& q) const 00301 { return oriented_side(q) == ON_NEGATIVE_SIDE; } 00302 00303 bool has_on_boundary(const Point_2& q) const 00304 { return bounded_side(q) == ON_BOUNDARY; } 00305 00306 bool has_on_bounded_side(const Point_2& q) const 00307 { return bounded_side(q) == ON_BOUNDED_SIDE; } 00308 00309 bool has_on_unbounded_side(const Point_2& q) const 00310 { return bounded_side(q) == ON_UNBOUNDED_SIDE; } 00311 00312 //-------------------------------------------------------- 00313 // Random access methods 00314 //-------------------------------------------------------- 00315 00316 const Point_2& vertex(int i) const 00317 { return *(d_container.begin() + i); } 00318 00319 // Point_2& vertex(int i) 00320 // { return *(d_container.begin() + i); } 00321 00322 const Point_2& operator[](int i) const 00323 { return vertex(i); } 00324 00325 // Point_2& operator[](int i) 00326 // { return vertex(i); } 00327 00328 Segment_2 edge(int i) const 00329 { return *(edges_begin() + i); } 00330 00331 //-------------------------------------------------------- 00332 // Miscellaneous 00333 //-------------------------------------------------------- 00334 00335 int size() const 00336 { return d_container.size(); } 00337 00338 bool is_empty() const 00339 { return d_container.empty(); } 00340 00341 const Container_P& container() const 00342 { return d_container; } 00343 00344 bool identical(const Polygon_2<Traits_P,Container_P> &q) const 00345 { return this == &q; } 00346 00347 00348 Traits_P const &traits_member() const { return traits;} 00349 00350 private: 00351 Container_P d_container; 00352 Traits_P traits; 00353 }; 00354 00355 //-----------------------------------------------------------------------// 00356 // Globally defined operators 00357 //-----------------------------------------------------------------------// 00358 00359 template <class Traits_P, class Container1_P, class Container2_P> 00360 bool operator==( const Polygon_2<Traits_P,Container1_P> &x, 00361 const Polygon_2<Traits_P,Container2_P> &y ); 00362 00363 template <class Traits_P, class Container1_P, class Container2_P> 00364 inline 00365 bool 00366 operator!=(const Polygon_2<Traits_P,Container1_P> &x, 00367 const Polygon_2<Traits_P,Container2_P> &y); 00368 00369 template <class Transformation, class Traits_P, class Container_P> 00370 Polygon_2<Traits_P,Container_P> 00371 transform(const Transformation& t, const Polygon_2<Traits_P,Container_P>& p); 00372 00373 //-----------------------------------------------------------------------// 00374 // I/O 00375 //-----------------------------------------------------------------------// 00376 00377 template <class Traits_P, class Container_P> 00378 std::istream &operator>>(std::istream &is, Polygon_2<Traits_P,Container_P>& p); 00379 00380 template <class Traits_P, class Container_P> 00381 std::ostream 00382 &operator<<(std::ostream &os, const Polygon_2<Traits_P,Container_P>& p); 00383 00384 //-----------------------------------------------------------------------// 00385 // implementation 00386 //-----------------------------------------------------------------------// 00387 00388 CGAL_END_NAMESPACE 00389 00390 #include <CGAL/Polygon_2/Polygon_2_impl.h> 00391 00392 CGAL_BEGIN_NAMESPACE 00393 00394 template <class Traits_P, class Container1_P, class Container2_P> 00395 inline 00396 bool 00397 operator!=(const Polygon_2<Traits_P,Container1_P> &x, 00398 const Polygon_2<Traits_P,Container2_P> &y) 00399 { 00400 return !(x==y); 00401 } 00402 00403 CGAL_END_NAMESPACE 00404 00405 #endif