// Copyright (c) 2005 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : Baruch Zukerman #ifndef CGAL_POLYGON_WITH_HOLES_2_H #define CGAL_POLYGON_WITH_HOLES_2_H #include #include #include #include namespace CGAL { /*! \ingroup PkgPolygon2 The class `Polygon_with_holes_2` models the concept `GeneralPolygonWithHoles_2`. It represents a linear polygon with holes. It is parameterized with two types (`Kernel` and `Container`) that are used to instantiate the type `Polygon_2`. The latter is used to represents the outer boundary and the boundary of the holes (if any exist). \cgalModels `GeneralPolygonWithHoles_2` */ template > class Polygon_with_holes_2 : public General_polygon_with_holes_2 > { public: typedef CGAL::Polygon_2 Polygon_2; typedef General_polygon_with_holes_2 Base; typedef typename Base::Hole_const_iterator Hole_const_iterator; typedef typename Base::Size Size; /*! Default constructor. */ Polygon_with_holes_2 () : Base() {} /*! Constructor from the base class. */ Polygon_with_holes_2 (const Base& base) : Base (base) {} /*! Constructor from a polygon. */ explicit Polygon_with_holes_2 (const Polygon_2& pgn_boundary) : Base (pgn_boundary) {} /*! Constructor from a polygon (outer boundary) and hole polygons. */ template Polygon_with_holes_2 (const Polygon_2& pgn_boundary, HolesInputIterator h_begin, HolesInputIterator h_end) : Base (pgn_boundary, h_begin, h_end) {} /*! Obtain the bounding box of the polygon with holes */ Bbox_2 bbox() const { return this->outer_boundary().bbox(); } }; //-----------------------------------------------------------------------// // operator<< //-----------------------------------------------------------------------// /*! This operator exports a polygon with holes to the output stream `out`. An ASCII and a binary format exist. The format can be selected with the \cgal modifiers for streams, `set_ascii_mode()` and `set_binary_mode()` respectively. The modifier `set_pretty_mode()` can be used to allow for (a few) structuring comments in the output. Otherwise, the output would be free of comments. The default for writing is ASCII without comments. The number of points of the outer boundary is exported followed by the points themselves in counterclockwise order. Then, the number of holes is exported, and for each hole, the number of points on its outer boundary is exported followed by the points themselves in clockwise order. \relates Polygon_with_holes_2 */ template std::ostream& operator<<(std::ostream &os, const Polygon_with_holes_2& p) { typename Polygon_with_holes_2::Hole_const_iterator i; switch(get_mode(os)) { case IO::ASCII : os << p.outer_boundary() << ' ' << p.number_of_holes()<<' '; for (i = p.holes_begin(); i != p.holes_end(); ++i) { os << *i << ' '; } return os; case IO::BINARY : os << p.outer_boundary() << p.number_of_holes(); for (i = p.holes_begin(); i != p.holes_end(); ++i) { os << *i ; } return os; default: os << "Polygon_with_holes_2(" << std::endl; if(p.is_unbounded()) os << "No outer bounary" << std::endl; else { os << "Boundary(" << std::endl; os << p.outer_boundary() << std::endl; } os << "Holes" << std::endl; os << p.number_of_holes()<> //-----------------------------------------------------------------------// /*! This operator imports a polygon with holes from the input stream `in`. An ASCII and a binary format exist. The stream detects the format automatically and can read both. The format consists of the number of points of the outer boundary followed by the points themselves in counterclockwise order, followed by the number of holes, and for each hole, the number of points of the outer boundary is followed by the points themselves in clockwise order. \relates Polygon_with_holes_2 */ template std::istream &operator>>(std::istream &is, Polygon_with_holes_2& p) { typedef CGAL::Polygon_2 Polygon_2; p.clear(); is >> p.outer_boundary(); unsigned int n; // number of holes; is >> n; if(is) { for (unsigned int i=0; i> hole; p.add_hole(hole); } } return is; } //-----------------------------------------------------------------------// // operator== //-----------------------------------------------------------------------// template bool operator==(const Polygon_with_holes_2& p1, const Polygon_with_holes_2& p2) { typedef typename Polygon_with_holes_2::Hole_const_iterator HCI; typedef CGAL::Polygon_2 Polygon_2; if(&p1 == &p2) return (true); if(p1.number_of_holes() != p2.number_of_holes()) return (false); if(p1.outer_boundary() != p2.outer_boundary()) return (false); std::list tmp_list(p2.holes_begin(), p2.holes_end()); HCI i = p1.holes_begin(); for(; i!= p1.holes_end(); ++i) { typename std::list::iterator j = (std::find(tmp_list.begin(), tmp_list.end(), *i)); if(j == tmp_list.end()) return (false); tmp_list.erase(j); } CGAL_assertion(tmp_list.empty()); return (true); } //-----------------------------------------------------------------------// // operator!= //-----------------------------------------------------------------------// template inline bool operator!=(const Polygon_with_holes_2& p1, const Polygon_with_holes_2& p2) { return (!(p1==p2)); } //-----------------------------------------------------------------------// // operator== //-----------------------------------------------------------------------// template bool operator==(const Polygon_with_holes_2& p1, const Polygon_2& p2) { return (p1.outer_boundary() == p2 && !p1.number_of_holes()); } template inline bool operator==(const Polygon_2& p1, const Polygon_with_holes_2& p2) { return (p2 == p1); } template inline bool operator!=(const Polygon_with_holes_2& p1, const Polygon_2& p2) { return (!(p1==p2)); } template inline bool operator!=(const Polygon_2& p1, const Polygon_with_holes_2& p2) { return (!(p1==p2)); } } //namespace CGAL #endif