24template <
class Number,
class Label>
25template<Po
intConcept OtherPo
int>
30template <
class Number,
class Label>
31template<SegmentConcept OtherSegment>
36template <
class Number,
class Label>
37template<OrientedSegmentConcept OtherOrientedSegment>
42template <
class Number,
class Label>
43template<LineConcept OtherLine>
48template <
class Number,
class Label>
49template<OrientedLineConcept OtherOrientedLine>
54template <
class Number,
class Label>
55template<RayConcept OtherRay>
60template <
class Number,
class Label>
61template<HalfplaneConcept OtherHalfplane>
66template <
class Number,
class Label>
67template<RectangleConcept OtherRectangle>
77template <
class Number,
class Label>
78template<TriangleConcept OtherTriangle>
83template <
class Number,
class Label>
84template<ConvexConcept OtherConvex>
89template <
class Number,
class Label>
90template<PolygonConcept OtherPolygon>
95template <
class Number,
class Label>
96template<DiskConcept OtherDisk>
108template <
class Po
intType,
class LabelType>
109template<Po
intConcept OtherPo
int>
121template <
class Po
intType,
class LabelType>
122template<Po
intConcept OtherPo
int>
124 const auto boundary =
edges();
125 return boundary[0].contains(point) || boundary[1].contains(point) || boundary[2].contains(point);
128template <
class Po
intType,
class LabelType>
129template<SegmentConcept OtherSegment>
131 return detail::polygonBoundaryContainsSegment(*
this, other);
134template <
class Po
intType,
class LabelType>
135template<OrientedSegmentConcept OtherOrientedSegment>
140template <
class Po
intType,
class LabelType>
141template<LineConcept OtherLine>
146template <
class Po
intType,
class LabelType>
147template<OrientedLineConcept OtherOrientedLine>
152template <
class Po
intType,
class LabelType>
153template<RayConcept OtherRay>
158template <
class Po
intType,
class LabelType>
159template<HalfplaneConcept OtherHalfplane>
164template <
class Po
intType,
class LabelType>
165template<RectangleConcept OtherRectangle>
172 if (!other.isDegenerate()) {
175 if (other.min() == other.max()) {
181template <
class Po
intType,
class LabelType>
182template<TriangleConcept OtherTriangle>
184 if (!other.isDegenerate()) {
187 if (other.a() == other.c()) {
193template <
class Po
intType,
class LabelType>
194template<ConvexConcept OtherConvex>
196 if (other.size() == 0) {
199 if (other.size() == 1) {
202 if (other.size() == 2) {
214template <
class Po
intType,
class LabelType>
215template<Po
intConcept OtherPo
int>
226template <
class Po
intType,
class LabelType>
227template<Po
intConcept OtherPo
int>
239template <
class Po
intType,
class LabelType>
240template<Po
intConcept OtherPo
int>
252template <
class Po
intType,
class LabelType>
253template<Po
intConcept OtherPo
int>
265template <
class Po
intType,
class LabelType>
266template<Po
intConcept OtherPo
int>
273 return point.x() ==
min().x() ||
274 point.x() ==
max().x() ||
275 point.y() ==
min().y() ||
276 point.y() ==
max().y();
279template <
class Po
intType,
class LabelType>
280template<SegmentConcept OtherSegment>
284 return detail::coversNoPoint(other);
286 return detail::polygonBoundaryContainsSegment(*
this, other);
289template <
class Po
intType,
class LabelType>
290template<OrientedSegmentConcept OtherOrientedSegment>
294 return detail::coversNoPoint(other);
299template <
class Po
intType,
class LabelType>
300template<LineConcept OtherLine>
304 return detail::coversNoPoint(other);
309template <
class Po
intType,
class LabelType>
310template<OrientedLineConcept OtherOrientedLine>
314 return detail::coversNoPoint(other);
319template <
class Po
intType,
class LabelType>
320template<RayConcept OtherRay>
324 return detail::coversNoPoint(other);
329template <
class Po
intType,
class LabelType>
330template<HalfplaneConcept OtherHalfplane>
334 return detail::coversNoPoint(other);
339template <
class Po
intType,
class LabelType>
340template<RectangleConcept OtherRectangle>
348 if (!other.isDegenerate()) {
356 if (other.min() == other.max()) {
362template <
class Po
intType,
class LabelType>
363template<TriangleConcept OtherTriangle>
367 return detail::coversNoPoint(other);
369 if (!other.isDegenerate()) {
372 if (other.a() == other.c()) {
378template <
class Po
intType,
class LabelType>
379template<ConvexConcept OtherConvex>
383 return detail::coversNoPoint(other);
385 if (other.size() == 0) {
388 if (other.size() == 1) {
391 if (other.size() == 2) {
403template <
class Po
intType,
class LabelType>
404template<Po
intConcept OtherPo
int>
412template <
class Po
intType,
class LabelType>
413template<SegmentConcept OtherSegment>
418template <
class Po
intType,
class LabelType>
419template<LineConcept OtherLine>
424template <
class Po
intType,
class LabelType>
425template<OrientedSegmentConcept OtherOrientedSegment>
430template <
class Po
intType,
class LabelType>
431template<OrientedLineConcept OtherOrientedLine>
436template <
class Po
intType,
class LabelType>
437template<RayConcept OtherRay>
442template <
class Po
intType,
class LabelType>
443template<RectangleConcept OtherRectangle>
450 return other.isDegenerate() &&
455template <
class Po
intType,
class LabelType>
456template<TriangleConcept OtherTriangle>
458 return other.isDegenerate() &&
464template <
class Po
intType,
class LabelType>
465template<HalfplaneConcept OtherHalfplane>
467 return other.isDegenerate() &&
487template <
class Po
intType,
class LabelType>
488template<Po
intConcept OtherPo
int>
497 return inCircleSign(
a(),
b(),
c(), point) == std::partial_ordering::equivalent;
500template <
class Po
intType,
class LabelType>
501template<SegmentConcept OtherSegment>
512template <
class Po
intType,
class LabelType>
513template<OrientedSegmentConcept OtherOrientedSegment>
524template <
class Po
intType,
class LabelType>
525template<LineConcept OtherLine>
536template <
class Po
intType,
class LabelType>
537template<OrientedLineConcept OtherOrientedLine>
548template <
class Po
intType,
class LabelType>
549template<RayConcept OtherRay>
560template <
class Po
intType,
class LabelType>
561template<HalfplaneConcept OtherHalfplane>
572template <
class Po
intType,
class LabelType>
573template<TriangleConcept OtherTriangle>
582 const bool is_point = other.a() == other.b() && other.a() == other.c();
586template <
class Po
intType,
class LabelType>
587template<RectangleConcept OtherRectangle>
601 const bool is_point = other.min() == other.max();
605template <
class Po
intType,
class LabelType>
606template<ConvexConcept OtherConvex>
618template <
class Po
intType,
class LabelType>
619template<DiskConcept OtherDisk>
623 if (other.a() == other.b()) {
637template <
class Po
intType,
class LabelType>
640 [
this](
const auto& value) {
650template <
class Po
intType,
class LabelType>
651template<Po
intConcept OtherPo
int>
653 if (points_.empty()) {
660 using CommonNumberType = std::common_type_t<NumberType, typename OtherPoint::NumberType>;
664 if (points_.size() == 1) {
665 return translatedPoint == points_[0];
667 if (points_.size() == 2) {
670 if (points_.size() == 3) {
681 auto it_end = points_.begin() + max_i + 1;
682 auto it = std::lower_bound(points_.begin(), it_end, translatedPoint, lexLessCrossType);
686 if (it == points_.begin()) {
687 return *it == translatedPoint;
694 auto it_begin = std::make_reverse_iterator(points_.end());
695 auto it_end = std::make_reverse_iterator(points_.begin() + max_i);
697 auto it = std::lower_bound(it_begin, it_end, translatedPoint, lexLessCrossType);
702 if (it == it_begin) {
713 if (max_i == 1 || max_i + 1 == points_.size()) {
716 return translatedPoint == points_[0] || translatedPoint == points_[max_i];
719template <
class Po
intType,
class LabelType>
720template<SegmentConcept OtherSegment>
722 if (other.isDegenerate()) {
730 for (
const auto &edgePair : {
edgesAtX(other.min().x()),
edgesAtX(other.max().x())}) {
734 if (other.isVertical()) {
747 for (
const auto &
edge : *edgePair) {
748 if (
edge.contains(other)) {
756template <
class Po
intType,
class LabelType>
757template<OrientedSegmentConcept OtherOrientedSegment>
762template <
class Po
intType,
class LabelType>
763template<LineConcept OtherLine>
768template <
class Po
intType,
class LabelType>
769template<OrientedLineConcept OtherOrientedLine>
774template <
class Po
intType,
class LabelType>
775template<RayConcept OtherRay>
780template <
class Po
intType,
class LabelType>
781template<HalfplaneConcept OtherHalfplane>
786template <
class Po
intType,
class LabelType>
787template<RectangleConcept OtherRectangle>
794 if (!other.isDegenerate()) {
797 if (other.min() == other.max()) {
803template <
class Po
intType,
class LabelType>
804template<TriangleConcept OtherTriangle>
806 if (!other.isDegenerate()) {
809 if (other.a() == other.c()) {
815template <
class Po
intType,
class LabelType>
816template<ConvexConcept OtherConvex>
818 if (other.size() == 0) {
821 if (other.size() == 1) {
824 if (other.size() == 2) {
830template <
class Po
intType,
class LabelType>
831template<DiskConcept OtherDisk>
833 if (other[0] == other[1] && other[0] == other[2]) {
839template <
class Po
intType,
class LabelType>
840template <Po
intConcept OtherPo
int>
843 [
this](
const auto& value) {
853template <
class Po
intType,
class LabelType>
854template<Po
intConcept OtherPo
int>
856 const std::size_t n =
size();
863 const auto p = point - translation_;
864 for (std::size_t i = 0; i < n; ++i) {
872template <
class Po
intType,
class LabelType>
873template<SegmentConcept OtherSegment>
875 if (other.isDegenerate()) {
882 if (
edge.contains(other)) {
889template <
class Po
intType,
class LabelType>
890template<OrientedSegmentConcept OtherOrientedSegment>
895template <
class Po
intType,
class LabelType>
896template<LineConcept OtherLine>
901template <
class Po
intType,
class LabelType>
902template<OrientedLineConcept OtherOrientedLine>
907template <
class Po
intType,
class LabelType>
908template<RayConcept OtherRay>
913template <
class Po
intType,
class LabelType>
914template<HalfplaneConcept OtherHalfplane>
919template <
class Po
intType,
class LabelType>
920template<RectangleConcept OtherRectangle>
927 if (!other.isDegenerate()) {
930 if (other.min() == other.max()) {
936template <
class Po
intType,
class LabelType>
937template<TriangleConcept OtherTriangle>
939 if (!other.isDegenerate()) {
942 if (other.a() == other.c()) {
948template <
class Po
intType,
class LabelType>
949template<ConvexConcept OtherConvex>
951 if (other.size() == 0) {
954 if (other.size() == 1) {
957 if (other.size() == 2) {
963template <
class Po
intType,
class LabelType>
964template<PolygonConcept OtherPolygon>
966 if (other.size() == 0) {
969 if (other.size() == 1) {
972 if (other.size() == 2) {
978template <
class Po
intType,
class LabelType>
979template<DiskConcept OtherDisk>
981 if (other[0] == other[1] && other[0] == other[2]) {
987template <
class Po
intType,
class LabelType>
988template<Po
intConcept OtherPo
int>
991 [
this](
const auto& value) {
997template <
class Po
intType,
class LabelType>
998template<PolygonConcept OtherPolygon>
1000 if (other.size() == 0) {
1003 if (other.size() == 1) {
1006 if (other.size() == 2) {
1012template <
class Po
intType,
class LabelType>
1013template<PolygonConcept OtherPolygon>
1032template <
class Po
intType,
class LabelType>
1033template<DiskConcept OtherDisk>
1035 return other[0] == other[1] && other[1]==other[2] &&
boundaryContains(other[0]);
1038template <
class Po
intType,
class LabelType>
1039template<PolygonConcept OtherPolygon>
1041 return asConvex().boundaryContains(other);
1044template <
class Po
intType,
class LabelType>
1045template<PolygonConcept OtherPolygon>
1049 return detail::coversNoPoint(other);
1051 return asConvex().boundaryContains(other);
1054template <
class Po
intType,
class LabelType>
1055template<DiskConcept OtherDisk>
1059 return detail::coversNoPoint(other);
1061 return other[0] == other[1] && other[1]==other[2] &&
boundaryContains(other[0]);
1069template <
class Number,
class Label>
1072 [
this](
const auto& value) {
1073 return this->boundaryContains(value);
1078template <
class Po
intType,
class LabelType>
1079template<Po
intConcept OtherPo
int>
1082 [
this](
const auto& value) {
1088template <
class Po
intType,
class LabelType>
1091 [
this](
const auto& value) {
1097template <
class Po
intType,
class LabelType>
1100 [
this](
const auto& value) {
1106template <
class Po
intType,
class LabelType>
1109 [
this](
const auto& value) {
1115template <
class Po
intType,
class LabelType>
1118 [
this](
const auto& value) {
1124template <
class Po
intType,
class LabelType>
1127 [
this](
const auto& value) {
1133template <
class Po
intType,
class LabelType>
1136 [
this](
const auto& value) {
1142template <
class Po
intType,
class LabelType>
1145 [
this](
const auto& value) {
1157template <
class Po
intType,
class LabelType,
class Storage>
1158template<Po
intConcept OtherPo
int>
1160 if (points_.empty()) {
1163 return point == points_.front() + translation_ || point == points_.back() + translation_;
1166template <
class Po
intType,
class LabelType,
class Storage>
1167template<Po
intConcept OtherPo
int>
1170 [
this](
const auto& value) {
1176template <
class Number,
class Label>
1177template<MonotoneChainConcept OtherChain>
1182template <
class Po
intType,
class LabelType>
1183template<MonotoneChainConcept OtherChain>
1187 for (
const auto&
vertex : other) {
1195template <
class Po
intType,
class LabelType>
1196template<MonotoneChainConcept OtherChain>
1200 return detail::coversNoPoint(other);
1202 return asConvex().boundaryContains(other);
1205template <
class Po
intType,
class LabelType>
1206template<MonotoneChainConcept OtherChain>
1208 return asConvex().boundaryContains(other);
1211template <
class Po
intType,
class LabelType>
1212template<MonotoneChainConcept OtherChain>
1224template <
class Po
intType,
class LabelType>
1225template<MonotoneChainConcept OtherChain>
1229 if (other.empty()) {
1232 if (other.size() == 1) {
1235 for (std::size_t i = 0; i + 1 < other.size(); ++i) {
1243template <
class Po
intType,
class LabelType>
1244template<MonotoneChainConcept OtherChain>
1246 if (other.empty()) {
1249 if (other.size() == 1) {
1252 for (std::size_t i = 0; i + 1 < other.size(); ++i) {
1266template <
class Po
intType,
class LabelType>
1267template<Po
intConcept OtherPo
int>
1269 if (points_.empty()) {
1272 return point == points_.front() + translation_ || point == points_.back() + translation_;
1275template <
class Po
intType,
class LabelType>
1276template<Po
intConcept OtherPo
int>
1279 [
this](
const auto& value) {
1285template <
class Number,
class Label>
1286template<PolylineConcept OtherPolyline>
1291template <
class Po
intType,
class LabelType>
1292template<PolylineConcept OtherPolyline>
1296 for (
const auto&
vertex : other) {
1304template <
class Po
intType,
class LabelType>
1305template<PolylineConcept OtherPolyline>
1309 return detail::coversNoPoint(other);
1311 return asConvex().boundaryContains(other);
1314template <
class Po
intType,
class LabelType>
1315template<PolylineConcept OtherPolyline>
1317 return asConvex().boundaryContains(other);
1320template <
class Po
intType,
class LabelType>
1321template<PolylineConcept OtherPolyline>
1331 return other.empty() || (other.isDegenerate() &&
boundaryContains(other[0]));
1334template <
class Po
intType,
class LabelType>
1335template<PolylineConcept OtherPolyline>
1339 if (other.empty()) {
1342 if (other.size() == 1) {
1345 for (std::size_t i = 0; i + 1 < other.size(); ++i) {
1353template <
class Po
intType,
class LabelType>
1354template<PolylineConcept OtherPolyline>
1356 if (other.empty()) {
1359 if (other.size() == 1) {
1362 for (std::size_t i = 0; i + 1 < other.size(); ++i) {
1374template <
class Po
intType,
class LabelType>
1375template <Po
intConcept OtherPo
int>
1380 return pointStatus(point) == 0;
1383template <
class Po
intType,
class LabelType>
1384template <SegmentConcept OtherSegment>
1397 for (
const std::ptrdiff_t idx : {sameDirectionIndex(along), sameDirectionIndex(along.
opposite())}) {
1398 if (idx >= 0 && constraintSide(
static_cast<std::size_t
>(idx), other.min()) == 0 &&
1399 constraintSide(
static_cast<std::size_t
>(idx), other.max()) == 0) {
1406template <
class Po
intType,
class LabelType>
1407template <OrientedSegmentConcept OtherOrientedSegment>
1412template <
class Po
intType,
class LabelType>
1413template <LineConcept OtherLine>
1420 for (
const auto& halfplane : halfplanes_) {
1421 if (halfplane.boundaryContains(other)) {
1428template <
class Po
intType,
class LabelType>
1429template <OrientedLineConcept OtherOrientedLine>
1434template <
class Po
intType,
class LabelType>
1435template <RayConcept OtherRay>
1444 for (
const std::ptrdiff_t idx : {sameDirectionIndex(along), sameDirectionIndex(along.
opposite())}) {
1445 if (idx >= 0 && halfplanes_[
static_cast<std::size_t
>(idx)].
boundaryContains(other)) {
1452template <
class Po
intType,
class LabelType>
1453template <HalfplaneConcept OtherHalfplane>
1460template <
class Po
intType,
class LabelType>
1461template <RectangleConcept OtherRectangle>
1463 if (other.empty()) {
1470 if (!other.isDegenerate()) {
1476template <
class Po
intType,
class LabelType>
1477template <TriangleConcept OtherTriangle>
1484template <
class Po
intType,
class LabelType>
1485template <DiskConcept OtherDisk>
1488 if (!other.isDegenerate()) {
1491 return boundaryContains(other.template center<typename OtherDisk::NumberType>());
1494template <
class Po
intType,
class LabelType>
1495template <ConvexConcept OtherConvex>
1499 if (other.size() == 0) {
1502 if (!other.isDegenerate()) {
1505 if (other.size() == 1) {
1511template <
class Po
intType,
class LabelType>
1512template <MonotoneChainConcept OtherChain>
1514 if (other.size() == 0) {
1517 if (other.size() == 1) {
1520 for (
const auto&
edge : other.edgesView()) {
1528template <
class Po
intType,
class LabelType>
1529template <PolylineConcept OtherPolyline>
1531 if (other.size() == 0) {
1534 if (other.size() == 1) {
1537 for (
const auto&
edge : other.edgesView()) {
1545template <
class Po
intType,
class LabelType>
1546template <PolygonConcept OtherPolygon>
1550 if (other.size() == 0) {
1553 if (other.size() == 1) {
1556 if (!other.isDegenerate()) {
1559 for (
const auto&
edge : other.edgesView()) {
1567template <
class Po
intType,
class LabelType>
1568template <HalfplaneIntersectionConcept OtherRegion>
1573 if (other.empty()) {
1576 if (!other.isDegenerate()) {
1579 return std::visit([
this](
const auto& carrier) {
return this->
boundaryContains(carrier); },
1580 detail::degenerateRegionCarrier(other));
1583template <
class Po
intType,
class LabelType>
1584template <Po
intConcept OtherPo
int>
1587 [
this](
const auto& value) {
1608template <
class Shape2,
class Region>
1609constexpr bool boundaryContainsDegenerateRegion(
const Shape2& shape,
const Region& region) {
1611 [&shape](
const auto& carrier) {
1612 if constexpr (
requires { shape.boundaryContains(carrier); }) {
1613 return shape.boundaryContains(carrier);
1619 degenerateRegionCarrier(region));
1624template <
class Number,
class Label>
1625template <HalfplaneIntersectionConcept OtherRegion>
1627 if (other.empty()) {
1630 if (!other.isDegenerate()) {
1633 return detail::boundaryContainsDegenerateRegion(*
this, other);
1636template <
class Po
intType,
class LabelType>
1637template <HalfplaneIntersectionConcept OtherRegion>
1639 if (other.empty()) {
1642 if (!other.isDegenerate()) {
1645 return detail::boundaryContainsDegenerateRegion(*
this, other);
1648template <
class Po
intType,
class LabelType>
1649template <HalfplaneIntersectionConcept OtherRegion>
1651 return asSegment().boundaryContains(other);
1654template <
class Po
intType,
class LabelType>
1655template <HalfplaneIntersectionConcept OtherRegion>
1657 if (other.empty()) {
1660 if (!other.isDegenerate()) {
1663 return detail::boundaryContainsDegenerateRegion(*
this, other);
1666template <
class Po
intType,
class LabelType>
1667template <HalfplaneIntersectionConcept OtherRegion>
1669 return asLine().boundaryContains(other);
1672template <
class Po
intType,
class LabelType>
1673template <HalfplaneIntersectionConcept OtherRegion>
1675 if (other.empty()) {
1678 if (!other.isDegenerate()) {
1681 return detail::boundaryContainsDegenerateRegion(*
this, other);
1684template <
class Po
intType,
class LabelType>
1685template <HalfplaneIntersectionConcept OtherRegion>
1687 if (other.empty()) {
1690 if (!other.isDegenerate()) {
1693 return detail::boundaryContainsDegenerateRegion(*
this, other);
1696template <
class Po
intType,
class LabelType>
1697template <HalfplaneIntersectionConcept OtherRegion>
1701 return detail::coversNoPoint(other);
1703 if (other.empty()) {
1706 if (!other.isDegenerate()) {
1709 return detail::boundaryContainsDegenerateRegion(*
this, other);
1712template <
class Po
intType,
class LabelType>
1713template <HalfplaneIntersectionConcept OtherRegion>
1715 if (other.empty()) {
1718 if (!other.isDegenerate()) {
1721 return detail::boundaryContainsDegenerateRegion(*
this, other);
1724template <
class Po
intType,
class LabelType>
1725template <HalfplaneIntersectionConcept OtherRegion>
1727 if (other.empty()) {
1730 if (!other.isDegenerate()) {
1736 [
this](
const auto& carrier) {
1737 using Carrier = std::remove_cvref_t<
decltype(carrier)>;
1738 if constexpr (detail::is_point_v<Carrier>) {
1745 detail::degenerateRegionCarrier(other));
1748template <
class Po
intType,
class LabelType>
1749template <HalfplaneIntersectionConcept OtherRegion>
1751 if (other.empty()) {
1754 if (!other.isDegenerate()) {
1757 return detail::boundaryContainsDegenerateRegion(*
this, other);
1760template <
class Po
intType,
class LabelType,
class Storage>
1761template <HalfplaneIntersectionConcept OtherRegion>
1763 if (other.empty()) {
1766 if (!other.isDegenerate()) {
1769 return detail::boundaryContainsDegenerateRegion(*
this, other);
1772template <
class Po
intType,
class LabelType>
1773template <HalfplaneIntersectionConcept OtherRegion>
1775 if (other.empty()) {
1778 if (!other.isDegenerate()) {
1781 return detail::boundaryContainsDegenerateRegion(*
this, other);
1784template <
class Po
intType,
class LabelType>
1785template <HalfplaneIntersectionConcept OtherRegion>
1787 if (other.empty()) {
1790 if (!other.isDegenerate()) {
1793 return detail::boundaryContainsDegenerateRegion(*
this, other);
1800template <
class Po
intType,
class LabelType>
1801template <Po
intConcept OtherPo
int>
1803 if (outer_.boundaryContains(point)) {
1806 for (
const auto&
hole : holes_) {
1807 if (
hole.boundaryContains(point)) {
1814template <
class Po
intType,
class LabelType>
1815template <SegmentConcept OtherSegment>
1817 if (other.isDegenerate()) {
1827template <
class Po
intType,
class LabelType>
1828template <OrientedSegmentConcept OtherOrientedSegment>
1835template <
class Po
intType,
class LabelType>
1836template <LineConcept OtherLine>
1841template <
class Po
intType,
class LabelType>
1842template <OrientedLineConcept OtherOrientedLine>
1847template <
class Po
intType,
class LabelType>
1848template <RayConcept OtherRay>
1853template <
class Po
intType,
class LabelType>
1854template <HalfplaneConcept OtherHalfplane>
1863template <
class Po
intType,
class LabelType>
1864template <
class OtherArea>
1865constexpr bool PolygonWithHoles<PointType, LabelType>::areaBoundaryContains(
const OtherArea& other)
const {
1866 if (!other.isDegenerate()) {
1869 for (
const auto&
edge : other.edges()) {
1870 if (!boundaryContains(
edge)) {
1877template <
class Po
intType,
class LabelType>
1878template <RectangleConcept OtherRectangle>
1880 if (other.empty()) {
1885 return areaBoundaryContains(other);
1888template <
class Po
intType,
class LabelType>
1889template <TriangleConcept OtherTriangle>
1891 return areaBoundaryContains(other);
1894template <
class Po
intType,
class LabelType>
1895template <ConvexConcept OtherConvex>
1897 return areaBoundaryContains(other);
1900template <
class Po
intType,
class LabelType>
1901template <PolygonConcept OtherPolygon>
1903 return areaBoundaryContains(other);
1906template <
class Po
intType,
class LabelType>
1907template <PolygonWithHolesConcept OtherRegion>
1909 return areaBoundaryContains(other);
1914template <
class Po
intType,
class LabelType>
1915template <MonotoneChainConcept OtherChain>
1917 return chainRelation(other,
true,
1921template <
class Po
intType,
class LabelType>
1922template <PolylineConcept OtherPolyline>
1924 return chainRelation(other,
true,
1930template <
class Po
intType,
class LabelType>
1931template <DiskConcept OtherDisk>
1933 if (!other.isDegenerate()) {
1939template <
class Po
intType,
class LabelType>
1940template <HalfplaneIntersectionConcept OtherIntersection>
1942 if (other.empty()) {
1945 if (!other.isDegenerate()) {
1948 return degenerateIntersectionRelation(
1949 other, [
this](
const auto& carrier) {
return this->
boundaryContains(carrier); });
1972template <
class Shape2,
class HoledRegion>
1973constexpr bool boundaryContainsHoledRegion(
const Shape2& shape,
const HoledRegion& region) {
1974 if (!region.isDegenerate()) {
1977 return everyHoledRegionEdge(
1978 region, [&shape](
const auto&
edge) {
return shape.boundaryContains(
edge); });
1983template <
class Number,
class Label>
1984template <PolygonWithHolesConcept OtherRegion>
1986 return detail::boundaryContainsHoledRegion(*
this, other);
1989template <
class Po
intType,
class LabelType>
1990template <PolygonWithHolesConcept OtherRegion>
1992 return detail::boundaryContainsHoledRegion(*
this, other);
1995template <
class Po
intType,
class LabelType>
1996template <PolygonWithHolesConcept OtherRegion>
1998 return asSegment().boundaryContains(other);
2001template <
class Po
intType,
class LabelType>
2002template <PolygonWithHolesConcept OtherRegion>
2004 return detail::boundaryContainsHoledRegion(*
this, other);
2007template <
class Po
intType,
class LabelType>
2008template <PolygonWithHolesConcept OtherRegion>
2010 return asLine().boundaryContains(other);
2013template <
class Po
intType,
class LabelType>
2014template <PolygonWithHolesConcept OtherRegion>
2016 return detail::boundaryContainsHoledRegion(*
this, other);
2019template <
class Po
intType,
class LabelType>
2020template <PolygonWithHolesConcept OtherRegion>
2022 return detail::boundaryContainsHoledRegion(*
this, other);
2025template <
class Po
intType,
class LabelType>
2026template <PolygonWithHolesConcept OtherRegion>
2030 return detail::coversNoPoint(other);
2032 return detail::boundaryContainsHoledRegion(*
this, other);
2035template <
class Po
intType,
class LabelType>
2036template <PolygonWithHolesConcept OtherRegion>
2038 return detail::boundaryContainsHoledRegion(*
this, other);
2041template <
class Po
intType,
class LabelType>
2042template <PolygonWithHolesConcept OtherRegion>
2044 return detail::boundaryContainsHoledRegion(*
this, other);
2047template <
class Po
intType,
class LabelType>
2048template <PolygonWithHolesConcept OtherRegion>
2050 return detail::boundaryContainsHoledRegion(*
this, other);
2053template <
class Po
intType,
class LabelType,
class Storage>
2054template <PolygonWithHolesConcept OtherRegion>
2056 return detail::boundaryContainsHoledRegion(*
this, other);
2059template <
class Po
intType,
class LabelType>
2060template <PolygonWithHolesConcept OtherRegion>
2062 return detail::boundaryContainsHoledRegion(*
this, other);
2065template <
class Po
intType,
class LabelType>
2066template <PolygonWithHolesConcept OtherRegion>
2068 return detail::boundaryContainsHoledRegion(*
this, other);
2071template <
class Po
intType,
class LabelType>
2072template <PolygonWithHolesConcept OtherHoledRegion>
2074 return detail::boundaryContainsHoledRegion(*
this, other);
2081template <
class Po
intType,
class LabelType>
2082template <Po
intConcept OtherPo
int>
2085 [
this](
const auto& value) {
2102template <
class Po
intType,
class LabelType>
2103template <detail::SetOperandConcept OtherShape>
2124 return segmentIn(other,
true);
2132 return chainIn(other,
true);
2137 return detail::reduceDegenerate(
2138 other, [
this](
const auto& carrier) {
return this->
boundaryContains(carrier); });
2142template <
class Po
intType,
class LabelType>
2143template <PolygonSetConcept OtherSet>
2153template <
class Po
intType,
class LabelType>
2154template <Po
intConcept OtherPo
int>
2156 return std::visit([
this](
const auto& value) {
return this->
boundaryContains(value); },
Definition forward.hpp:312
Definition forward.hpp:309
Definition forward.hpp:320
Definition forward.hpp:310
Definition forward.hpp:308
Definition forward.hpp:306
Definition forward.hpp:321
Definition forward.hpp:311
Definition forward.hpp:307
Definition arrangement.hpp:67
constexpr std::partial_ordering inCircleSign(const Point< ANumber, ALabel > &a, const Point< BNumber, BLabel > &b, const Point< CNumber, CLabel > &c, const Point< DNumber, DLabel > &d)
Classifies a point with respect to the circumcircle of three others.
Definition orientation.hpp:894
@ edge
Definition bitmatrix.hpp:37
@ vertex
Definition bitmatrix.hpp:37
Line() -> Line< Point<>, NoLabel >
constexpr std::partial_ordering orientationSign(const Point< ANumber, ALabel > &a, const Point< BNumber, BLabel > &b, const Point< CNumber, CLabel > &c)
Classifies the orientation of three points.
Definition orientation.hpp:544
constexpr bool collinear(const Point< ANumber, ALabel > &a, const Point< BNumber, BLabel > &b, const Point< CNumber, CLabel > &c)
Tests whether three points are collinear.
Definition orientation.hpp:651
Small dispatch traits and geometry helpers reused by the implementations.
Public declaration of pgl::Segment.
constexpr const Rectangle< PointType > & bbox() const
Computes the bounding box of the convex polygon.
Definition bounding.hpp:374
constexpr PointType get(std::ptrdiff_t index) const
Cyclic access: same as operator[] but index is taken modulo size(); negative indices wrap from the en...
Definition convex.hpp:289
constexpr bool isDegenerate() const
Checks if the convex polygon is degenerate (has zero area).
Definition predicates.hpp:982
constexpr size_t maxIndex() const
Returns the index of the maximum vertex (rightmost and highest in case of ties).
Definition predicates.hpp:1022
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1135
constexpr std::optional< std::array< Segment< PointType >, 2 > > edgesAtX(OtherNumberType x) const
Returns two edges of the convex polygon that intersect with the vertical line at x.
Definition atxy.hpp:289
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:652
constexpr bool boundaryContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition disk.hpp:904
constexpr bool isDegenerate() const
Returns whether the three boundary points are collinear.
Definition disk.hpp:348
constexpr const PointType & c() const
Returns the third boundary point in canonical order.
Definition disk.hpp:244
constexpr bool contains(const OtherPoint &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1015
constexpr const PointType & a() const
Returns the first boundary point (lexicographically smallest).
Definition disk.hpp:228
constexpr const PointType & b() const
Returns the second boundary point in canonical order.
Definition disk.hpp:235
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2511
constexpr bool empty() const
Returns whether the region is the empty set.
Definition halfplaneintersection.hpp:649
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1376
constexpr std::variant< Segment< Point< ResultNumber, typename PointType::LabelType > >, Ray< Point< ResultNumber, typename PointType::LabelType > >, Line< Point< ResultNumber, typename PointType::LabelType > > > edge(std::size_t i) const
Returns the boundary contribution of half-plane i as a typed one-dimensional shape.
Definition halfplaneintersection.hpp:919
Closed half-plane defined by an oriented boundary line.
Definition halfplane.hpp:51
constexpr Halfplane opposite() const
Returns the complementary half-plane with reversed boundary orientation.
Definition halfplane.hpp:223
constexpr const PointType & target() const
Returns the target boundary point.
Definition halfplane.hpp:193
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:405
constexpr const PointType & source() const
Returns the source boundary point.
Definition halfplane.hpp:181
constexpr bool isDegenerate() const
Returns whether the defining points coincide.
Definition predicates.hpp:952
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:228
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1159
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:241
constexpr Line< PointType > asLine() const
Returns the line without orientation.
Definition orientedline.hpp:321
constexpr bool verticesContain(const OtherPoint &point) const
Returns whether one endpoint equals the given point.
Definition predicates.hpp:315
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:216
constexpr Segment< PointType > asSegment() const
Returns the segment without orientation.
Definition orientedsegment.hpp:322
Two-dimensional point with optional label payload.
Definition point.hpp:129
constexpr bool boundaryContains(const Shape< Point< TNumber, TLabel > > &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
bool intersects(const OtherShape &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:2234
constexpr const ComponentType & component(std::size_t index) const
Accesses a component by index.
Definition polygonset.hpp:271
bool isPinched() const
Tests whether two components touch each other anywhere.
Definition contains.hpp:3368
PolygonWithHoles< PointType > ComponentType
Definition polygonset.hpp:169
bool boundaryContains(const OtherShape &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:2104
constexpr bool interiorsIntersect(const OtherPoint &) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition polygonwithholes.hpp:1660
constexpr const PolygonType & hole(std::size_t index) const
Accesses a hole by index.
Definition polygonwithholes.hpp:196
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1802
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2945
constexpr bool boundaryContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition polygon.hpp:1532
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1296
constexpr auto edgesView() const
Returns a lazy view over the edges, materializing each Segment on the fly instead of allocating a vec...
Definition polygon.hpp:782
constexpr std::size_t size() const
Returns the number of vertices in the polygon.
Definition polygon.hpp:259
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1268
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:254
constexpr const PointType & source() const
Returns the source point of the ray.
Definition ray.hpp:181
constexpr const PointType & min() const
Returns the minimum corner (min x, min y).
Definition rectangle.hpp:347
constexpr bool empty() const
Returns whether the rectangle is the empty set of points.
Definition rectangle.hpp:290
constexpr Convex< PointType > asConvex() const
Returns the rectangle as a convex polygon.
Definition rectangle.hpp:690
constexpr bool boundaryContains(const Shape< PointType > &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1134
constexpr const PointType & max() const
Returns the maximum corner (max x, max y).
Definition rectangle.hpp:359
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:728
Unoriented closed segment between two endpoints plus optional segment label.
Definition segment.hpp:58
constexpr bool verticesContain(const OtherPoint &point) const
Returns whether one endpoint equals the given point.
Definition predicates.hpp:149
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:119
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:110
Runtime variant wrapper over the supported primitive shapes.
Definition shape.hpp:160
constexpr const Variant & variant() const
Returns the underlying variant.
Definition shape.hpp:264
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:123
constexpr Convex< PointType > asConvex() const
Returns the triangle as a convex polygon.
Definition triangle.hpp:490
constexpr std::array< Segment< PointType >, 3 > edges() const
Returns the three unoriented boundary edges.
Definition bounding.hpp:240