13template<fishnet::math::Number T>
18 std::vector<Ring<T>> holes;
31 if (std::ranges::any_of(
getHoles(),[point](
const auto & hole){
32 return hole.isInside(point);
39 std::vector<Ring<T>> rings;
40 std::ranges::copy(ringRange, std::back_inserter(rings));
44 constexpr bool equals(
IPolygon auto const & other)
const noexcept {
45 return this->
getBoundary() == other.getBoundary() && std::ranges::is_permutation(this->
getHoles(),other.getHoles());
61 if (std::ranges::any_of(holes, [&boundary](
const auto & hole){
return not boundary.
contains(hole);}))
62 throw InvalidGeometryException(
"Hole not contained within Boundary of Polygon");
63 if (std::ranges::any_of(holes, [&boundary,&holes](
const auto & h1){
64 return std::ranges::any_of(holes, [&boundary,&h1](
const auto & h2){
65 return h1.crosses(h2);
67 }))
throw InvalidGeometryException(
"Holes of Polygon are intersecting each other");
77 return static_cast<const Ring<T> &
>(*this);
81 return std::views::all(holes);
90 return holes.size() == 0;
104 for(
const auto & hole : holes) {
119 auto polygonArea = this->
area();
121 for(
const auto & hole: this->
getHoles()){
122 accCentroid = accCentroid + hole.centroid() * (-hole.area() / polygonArea);
128 auto location = polygonPointLocation(point);
133 return this->
getBoundary().contains(segment) && std::ranges::none_of(this->
getHoles(),[&segment](
const auto & hole){
return hole.intersects(segment);});
149 return this->
getBoundary().intersects(linearFeature) || std::ranges::any_of(
getHoles(),[linearFeature](
const auto & hole){
150 return hole.intersects(linearFeature);
155 std::unordered_set<Vec2D<double>> intersectionSet;
156 std::ranges::for_each(this->
getBoundary().
intersections(linearFeature),[&intersectionSet](
const auto & p){intersectionSet.insert(p);});
157 std::ranges::for_each(this->
getHoles(), [&intersectionSet,&linearFeature](
const auto & hole){
158 std::ranges::for_each(hole.intersections(linearFeature),[&intersectionSet](
const auto & p){intersectionSet.insert(p);});
160 return intersectionSet;
164 return std::ranges::any_of(this->
getHoles(),[&point](
const auto & hole){
165 return hole.contains(point);
170 return std::ranges::any_of(this->
getHoles(),[&other](
const auto & hole){
171 return hole.contains(other.getBoundary());
176 if(this->equals(other))
180 return this->
getBoundary().contains(other.getBoundary()) && std::ranges::none_of(this->
getHoles(),[&other](
const auto & hole){
182 return hole.crosses(other.getBoundary()) || other.getBoundary().contains(hole);
189 return this->
getBoundary().crosses(other.getBoundary()) || std::ranges::any_of(this->
getHoles(),[&other](
const auto & hole){
190 return hole.crosses(other.getBoundary());
197 return this->
getBoundary().touches(other.getBoundary()) || std::ranges::any_of(this->
getHoles(), [&other](
const auto & hole){
198 return hole.contains(other.getBoundary()) && std::ranges::any_of(other.getBoundary().getPoints(),[&hole](
const auto & p){
199 return hole.isOnBoundary(p);
211 if(this->
touches(other))
return 0;
214 if(hole.contains(other.getBoundary())){
219 return this->
getBoundary().distance(other.getBoundary());
222 template<fishnet::math::Number U>
224 return this->equals(other);
227 constexpr size_t hash() const noexcept{
229 auto holesHashView = this->
getHoles() | std::views::transform([](
const auto & ring){
return ring.hash();});
230 auto holesHash = std::accumulate(std::ranges::begin(holesHashView),std::ranges::end(holesHashView),
size_t(0));
231 return boundaryHash ^ holesHash;
235 std::ostringstream oss;
240 for(
const auto & hole : this->
getHoles()){
241 if(!first) oss <<
"},{";
242 oss << hole.toString();
251template<math::Number T>
254template<math::Number T>
Polygon implementation A Polygon consist of a boundary (IRing) and zero or more holes (IRing)
Definition Polygon.hpp:14
constexpr fishnet::math::DEFAULT_FLOATING_POINT area() const noexcept
Calculate the area of the polygon Subtract accumulated area of holes from the area contained within t...
Definition Polygon.hpp:102
constexpr bool operator==(const Polygon< U > &other) const noexcept
Definition Polygon.hpp:223
static constexpr GeometryType type
Definition Polygon.hpp:50
constexpr size_t hash() const noexcept
Definition Polygon.hpp:227
constexpr bool contains(IPolygon auto const &other) const noexcept
Definition Polygon.hpp:175
Polygon(const Ring< T > &boundary, const util::forward_range_of< Ring< T > > auto &holes, bool checked=false)
Definition Polygon.hpp:70
Polygon(const SimplePolygon< T > &boundary, const std::vector< Ring< T > > &holes={}, bool checked=false)
Definition Polygon.hpp:72
constexpr bool containsInHole(IPoint auto const &point) const noexcept
Definition Polygon.hpp:163
constexpr util::view_of< Segment< T > > auto getSegments()=delete
constexpr util::random_access_range_of< Vec2D< T > > auto getPoints()=delete
constexpr const SimplePolygon< T > & toSimple() const noexcept
Definition Polygon.hpp:93
constexpr std::unordered_set< Vec2D< double > > intersections(LinearGeometry auto const &linearFeature) const noexcept
Definition Polygon.hpp:154
constexpr std::string toString() const noexcept
Definition Polygon.hpp:234
constexpr bool isInside(IPoint auto const &point) const noexcept
Definition Polygon.hpp:136
Polygon(const Ring< T > &boundary, const std::vector< Ring< T > > &holes={}, bool checked=false)
Construct a new Polygon object using boundary and holes.
Definition Polygon.hpp:58
constexpr const Ring< T > & getBoundary() const noexcept
Definition Polygon.hpp:76
constexpr Vec2DReal centroid() const noexcept
Calculate weighted centroid of the polygon https://en.wikipedia.org/wiki/Centroid.
Definition Polygon.hpp:118
constexpr bool isOutside(IPoint auto const &point) const noexcept
Definition Polygon.hpp:144
Polygon(const SimplePolygon< T > &boundary, const util::forward_range_of< Ring< T > > auto &holes, bool checked=false)
Definition Polygon.hpp:74
constexpr bool crosses(IPolygon auto const &other) const noexcept
Definition Polygon.hpp:186
constexpr bool isOnBoundary(IPoint auto const &point) const noexcept
Definition Polygon.hpp:140
constexpr bool isSimple() const noexcept
Definition Polygon.hpp:89
constexpr bool contains(ISegment auto const &segment) const noexcept
Definition Polygon.hpp:132
constexpr bool touches(IPolygon auto const &other) const noexcept
Definition Polygon.hpp:194
T numeric_type
Definition Polygon.hpp:49
constexpr util::view_of< Ring< T > > auto getHoles() const noexcept
Definition Polygon.hpp:80
constexpr fishnet::math::DEFAULT_FLOATING_POINT distance(IPolygon auto const &other) const noexcept
Distance between the two polygons.
Definition Polygon.hpp:209
constexpr bool contains(IPoint auto const &point) const noexcept
Definition Polygon.hpp:127
constexpr bool intersects(LinearGeometry auto const &linearFeature) const noexcept
Definition Polygon.hpp:148
constexpr bool containsInHole(IPolygon auto const &other) const noexcept
Definition Polygon.hpp:169
Implementation of a ring.
Definition Ring.hpp:31
constexpr bool contains(IPoint auto const &point) const noexcept
Definition Ring.hpp:196
constexpr PointLocation getPointLocation(IPoint auto const &point) const noexcept
Get the location of a point with regard to the ring (INSIDE | OUTSIDE | BOUNDARY) Uses the Ray-Castin...
Definition Ring.hpp:80
Simple polygon implementation with no holes.
Definition SimplePolygon.hpp:13
Implementation of a two-dimensional vector.
Definition Vec2D.hpp:16
Interface for a point.
Definition IPoint.hpp:92
Interface for a polygon A polygon is a two-dimensional shape defined by a boundary and zero or more h...
Definition IPolygon.hpp:98
Interface for a segment A segment is formed between two points p and q, containing only the points on...
Definition ISegment.hpp:105
Definition IGeometry.hpp:13
A geometry enclosing an area: a ring, a polygon or a multi-polygon.
Definition IGeometry.hpp:23
Definition CollectionConcepts.hpp:27
Definition CollectionConcepts.hpp:39
Definition CollectionConcepts.hpp:45
Definition BoundingBoxWrapper.hpp:5
PointLocation
Definition Ring.hpp:21
GeometryType
Definition GeometryBase.hpp:6
static fishnet::math::DEFAULT_FLOATING_POINT shapeDistance(Shape auto const &lhs, Shape auto const &rhs, util::BiFunction< Vec2DReal, Vec2DReal, fishnet::math::DEFAULT_FLOATING_POINT > auto const &distanceFunction) noexcept
Compute the distance between two shapes, with custom distance function.
Definition PolygonDistance.hpp:465
double DEFAULT_FLOATING_POINT
Definition NumericConcepts.hpp:12