bool Polygon::containsSegment(GeoLib::LineSegment const& segment) const { std::vector<GeoLib::Point> s(getAllIntersectionPoints(segment)); GeoLib::Point const& a { segment.getBeginPoint() }; GeoLib::Point const& b { segment.getEndPoint() }; // no intersections -> check if at least one point of segment is in polygon if (s.empty()) { return (isPntInPolygon(a)); } const double tol(std::numeric_limits<float>::epsilon()); // one intersection, intersection in line segment end point if (s.size() == 1) { const double sqr_dist_as(MathLib::sqrDist(a,s[0])); if (sqr_dist_as < tol) { return (isPntInPolygon(b)); } const double sqr_dist_bs(MathLib::sqrDist(b,s[0])); if (sqr_dist_bs < tol) { return (isPntInPolygon(a)); } } // Sorting the intersection with respect to the distance to the point a. // This induces a partition of the line segment into sub segments. std::sort(s.begin(), s.end(), [&a] (GeoLib::Point const& p0, GeoLib::Point const& p1) { return MathLib::sqrDist(a, p0) < MathLib::sqrDist(a, p1); } ); // remove sub segments with almost zero length for (std::size_t k(0); k<s.size()-1; ) { if (MathLib::sqrDist(s[k], s[k+1]) < tol) { s.erase(s.begin()+k+1); } else { k++; } } // Check if all sub segments are within the polygon. if (!isPntInPolygon(GeoLib::Point(0.5*(a[0]+s[0][0]), 0.5*(a[1]+s[0][1]), 0.5*(a[2]+s[0][2])))) return false; const std::size_t n_sub_segs(s.size()-1); for (std::size_t k(0); k<n_sub_segs; k++) { if (!isPntInPolygon(GeoLib::Point(0.5*(s[k][0]+s[k+1][0]), 0.5*(s[k][1]+s[k+1][1]), 0.5*(s[k][2]+s[k+1][2])))) return false; } if (!isPntInPolygon(GeoLib::Point(0.5*(s[0][0]+b[0]), 0.5*(s[0][1]+b[1]), 0.5*(s[0][2]+b[2])))) return false; return true; }
bool Polygon::isPartOfPolylineInPolygon(const Polyline& ply) const { const std::size_t ply_size (ply.getNumberOfPoints()); // check points for (std::size_t k(0); k < ply_size; k++) { if (isPntInPolygon (*(ply.getPoint(k)))) { return true; } } GeoLib::Point s; for (auto polygon_seg : *this) { for (auto polyline_seg : ply) { if (GeoLib::lineSegmentIntersect(polyline_seg, polygon_seg, s)) { return true; } } } return false; }
bool Polygon::isPntInPolygon(double x, double y, double z) const { const GeoLib::Point pnt(x,y,z); return isPntInPolygon (pnt); }