Pangolin
Header-only C++20 plane computational geometry library
Loading...
Searching...
No Matches
monotonechain.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "shape/convex.hpp"
4
5#include <algorithm>
6#include <vector>
7#include <cassert>
8#include <compare>
9#include <concepts>
10#include <cstddef>
11#include <functional>
12#include <iterator>
13#include <limits>
14#include <optional>
15#include <ostream>
16#include <ranges>
17#include <span>
18#include <type_traits>
19#include <utility>
20#include <variant>
21
22
23namespace pgl {
24
25template <class PointType = Point<>, class Label, class Storage>
26struct MonotoneChain;
27
28namespace detail {
38template <class Storage, class PointType>
39concept ownsChainStorage = requires(Storage& s, const PointType& p) {
40 s.push_back(p);
41};
42
52template <std::ranges::forward_range Range>
53constexpr bool allPointsEqual(const Range& points) {
54 auto first = std::ranges::begin(points);
55 const auto last = std::ranges::end(points);
56 if (first == last) {
57 return false;
58 }
59 return std::find_if(std::next(first), last,
60 [&](const auto& p) { return p != *first; }) == last;
61}
62
71template <std::ranges::forward_range Range>
72constexpr bool pointsSpanSegment(const Range& points) {
73 const auto first = std::ranges::begin(points);
74 const auto last = std::ranges::end(points);
75 if (first == last) {
76 return false;
77 }
78 // Anchor the line on the first point and the first one differing from it.
79 const auto second = std::find_if(std::next(first), last,
80 [&](const auto& p) { return p != *first; });
81 if (second == last) {
82 return false; // All equal: a point, not a segment.
83 }
84 return std::all_of(std::next(second), last,
85 [&](const auto& p) { return collinear(*first, *second, p); });
86}
87
94template <class SegmentType, std::ranges::forward_range Range>
95constexpr SegmentType spannedSegment(const Range& points) {
96 const auto [low, high] = std::ranges::minmax_element(points);
97 return SegmentType(*low, *high);
98}
99} // namespace detail
100
102
103template <std::ranges::input_range Range>
104requires detail::is_point_v<std::ranges::range_value_t<Range>>
106
107template <std::ranges::input_range Range>
108requires detail::is_point_v<std::ranges::range_value_t<Range>>
110
111template <class Number>
112requires (!detail::is_point_v<Number>)
113MonotoneChain(std::initializer_list<Number>) -> MonotoneChain<Point<Number>, NoLabel>;
114
115template <class Number>
116requires (!detail::is_point_v<Number>)
117MonotoneChain(std::initializer_list<Number>, bool) -> MonotoneChain<Point<Number>, NoLabel>;
118
119
145template <class PointType_, class TLabel, class Storage>
147 using PointType = PointType_;
149 using LabelType = TLabel;
150 using StorageType = Storage;
151 // The owning counterpart of this chain: the same vertex and label type
152 // backed by an owned vector. Value-returning transformations produce this
153 // type so that even a view (which cannot own vertices) yields a real chain.
155 static_assert(detail::is_point_v<PointType>, "MonotoneChain requires pgl::Point vertices");
156
157 template <bool Oriented>
158 using BoundaryType = std::conditional_t<Oriented, OrientedSegment<PointType>, Segment<PointType>>;
159
160 template <bool Oriented>
161 class BoundaryIterator;
162
163 using EdgeIterator = BoundaryIterator<false>;
164 using OrientedEdgeIterator = BoundaryIterator<true>;
165
169 constexpr MonotoneChain() = default;
170
182 template<std::ranges::input_range Range = std::initializer_list<PointType>>
183 requires std::ranges::common_range<Range> &&
184 std::convertible_to<std::ranges::range_value_t<Range>, PointType> &&
185 detail::ownsChainStorage<Storage, PointType>
186 constexpr explicit MonotoneChain(Range&& points, bool trusted = false) {
187 for (const auto& p : points) {
188 points_.push_back(p);
189 }
190 if (!trusted) {
191 normalize();
192 }
193 assert(std::is_sorted(points_.begin(), points_.end()) &&
194 std::adjacent_find(points_.begin(), points_.end()) == points_.end());
195 }
196
210 template<std::ranges::contiguous_range Range>
211 requires (!detail::ownsChainStorage<Storage, PointType>) &&
212 std::constructible_from<Storage, Range&&>
213 constexpr explicit MonotoneChain(Range&& points, bool /*trusted*/ = true)
214 : points_(std::forward<Range>(points)) {
215 assert(std::is_sorted(points_.begin(), points_.end()) &&
216 std::adjacent_find(points_.begin(), points_.end()) == points_.end());
217 }
218
230 constexpr explicit MonotoneChain(std::initializer_list<NumberType> coords, bool trusted = false)
231 requires detail::ownsChainStorage<Storage, PointType>
232 {
233 assert(coords.size() % 2 == 0);
234 points_.reserve(coords.size() / 2);
235 for (auto it = coords.begin(); it != coords.end(); ) {
236 NumberType x = *it++;
237 NumberType y = *it++;
238 points_.emplace_back(x, y);
239 }
240 if (!trusted) {
241 normalize();
242 }
243 assert(std::is_sorted(points_.begin(), points_.end()) &&
244 std::adjacent_find(points_.begin(), points_.end()) == points_.end());
245 }
246
256 template<PointConcept OtherPointType, class OtherLabelType, class OtherStorage>
257 requires(std::constructible_from<PointType, const OtherPointType&> &&
258 detail::ownsChainStorage<Storage, PointType>)
260 : points_(other.begin(), other.end()), label_(detail::copyLabel<LabelType>(other)) {}
261
270 template <class A = LabelType>
271 requires(detail::has_label_v<A>)
272 constexpr A& label() const {
273 return label_;
274 }
275
281 constexpr const PointType operator[](std::size_t index) const {
282 assert(index < size());
283 return points_[index] + translation_;
284 }
285
297 constexpr PointType get(std::ptrdiff_t index) const {
298 const std::ptrdiff_t n = static_cast<std::ptrdiff_t>(size());
299 return (*this)[static_cast<std::size_t>(((index % n) + n) % n)];
300 }
301
312 constexpr std::ptrdiff_t index(const PointType& point) const {
313 const PointType query = point - translation_;
314 const auto it = std::lower_bound(points_.begin(), points_.end(), query);
315 if (it != points_.end() && *it == query) {
316 return it - points_.begin();
317 }
318 return -1;
319 }
320
324 constexpr auto begin() const {
325 return Iterator(points_.begin(), translation_);
326 }
327
331 constexpr auto cbegin() const {
332 return Iterator(std::ranges::begin(points_), translation_);
333 }
334
338 constexpr auto end() const {
339 return Iterator(points_.end(), translation_);
340 }
341
345 constexpr auto cend() const {
346 return Iterator(std::ranges::end(points_), translation_);
347 }
348
356 template <class OtherStorage>
358 if (auto cmp = size() <=> other.size(); cmp != 0) {
359 return cmp;
360 }
361 for (std::size_t i = 0; i < size(); ++i) {
362 if (auto cmp = (*this)[i] <=> other[i]; cmp != 0) {
363 return cmp;
364 }
365 }
366 return std::strong_ordering::equal;
367 }
368
373 template <class OtherStorage>
375 if (size() != other.size()) {
376 return false;
377 }
378 for (std::size_t i = 0; i < size(); ++i) {
379 if ((*this)[i] != other[i]) {
380 return false;
381 }
382 }
383 return true;
384 }
385
387 template<AnyShapeConcept OtherShape>
388 [[nodiscard]] constexpr bool samePointSet(const OtherShape& other) const;
389
393 constexpr std::size_t size() const {
394 return points_.size();
395 }
396
400 constexpr bool empty() const {
401 return points_.empty();
402 }
403
408 constexpr bool isDegenerate() const {
409 return points_.size() < 2;
410 }
411
422 [[nodiscard]] constexpr bool isPoint() const {
423 return detail::allPointsEqual(points_);
424 }
425
433 [[nodiscard]] constexpr std::optional<PointType> getIfPoint() const {
434 if (!isPoint()) {
435 return std::nullopt;
436 }
437 return points_.front() + translation_;
438 }
439
450 [[nodiscard]] constexpr bool isSegment() const {
451 return detail::pointsSpanSegment(points_);
452 }
453
461 [[nodiscard]] constexpr std::optional<BoundaryType<false>> getIfSegment() const {
462 if (!isSegment()) {
463 return std::nullopt;
464 }
465 return detail::spannedSegment<BoundaryType<false>>(points_) + translation_;
466 }
467
478 [[nodiscard]] constexpr bool isUndefined() const {
479 return empty();
480 }
481
493 [[nodiscard]] constexpr bool isStrictlyMonotone() const {
494 for (std::size_t i = 1; i < points_.size(); ++i) {
495 if (points_[i - 1].x() == points_[i].x()) {
496 return false;
497 }
498 }
499 return true;
500 }
501
513 constexpr Segment<PointType> diameter() const {
515 }
516
520 constexpr Convex<PointType> convexHull() const {
521 return Convex<PointType>(vertices());
522 }
523
536 constexpr const Rectangle<PointType>& bbox() const;
537
553 template <class ResultNumber = grid_number_t<typename PointType_::NumberType>>
554 requires(detail::extended_integral<ResultNumber> || std::same_as<ResultNumber, BigInt>)
557
563 template <std::floating_point ResultNumber = double>
565
569 constexpr std::vector<PointType> vertices() const {
570 std::vector<PointType> ret(points_.begin(), points_.end());
571 for (auto& vertex : ret) {
572 vertex += translation_;
573 }
574 return ret;
575 }
576
587 [[nodiscard]] constexpr Polyline<PointType> asPolyline() const;
588
595 constexpr std::vector<Segment<PointType>> edges() const {
596 std::vector<Segment<PointType>> result;
597 const auto translatedVertices = vertices();
598 for (std::size_t i = 0; i + 1 < translatedVertices.size(); ++i) {
599 result.emplace_back(translatedVertices[i], translatedVertices[i + 1]);
600 }
601 return result;
602 }
603
608 constexpr std::vector<OrientedSegment<PointType>> orientedEdges() const {
609 std::vector<OrientedSegment<PointType>> result;
610 const auto translatedVertices = vertices();
611 for (std::size_t i = 0; i + 1 < translatedVertices.size(); ++i) {
612 result.emplace_back(translatedVertices[i], translatedVertices[i + 1]);
613 }
614 return result;
615 }
616
625 constexpr auto verticesView() const {
626 return std::ranges::subrange(begin(), end());
627 }
628
637 constexpr auto edgesView() const {
638 return std::ranges::subrange(edgesBegin(), edgesEnd());
639 }
640
645 constexpr auto orientedEdgesView() const {
646 return std::ranges::subrange(orientedEdgesBegin(), orientedEdgesEnd());
647 }
648
653 constexpr EdgeIterator edgesBegin() const {
654 return EdgeIterator(this, 0);
655 }
656
661 constexpr EdgeIterator edgesEnd() const {
662 return EdgeIterator(this, edgeCount());
663 }
664
670 return OrientedEdgeIterator(this, 0);
671 }
672
678 return OrientedEdgeIterator(this, edgeCount());
679 }
680
694 constexpr void insert(const PointType& point)
695 requires detail::ownsChainStorage<Storage, PointType>
696 {
697 const PointType query = point - translation_;
698 const auto it = std::lower_bound(points_.begin(), points_.end(), query);
699 if (it != points_.end() && *it == query) {
700 return;
701 }
702 points_.insert(it, query);
703 resetCache();
704 }
705
716 template<std::ranges::input_range Range>
717 requires std::ranges::common_range<Range> &&
718 std::convertible_to<std::ranges::range_value_t<Range>, PointType> &&
719 detail::ownsChainStorage<Storage, PointType>
720 constexpr void insert(Range&& points) {
721 const std::size_t oldSize = points_.size();
722 for (const auto& p : points) {
723 points_.push_back(PointType(p) - translation_);
724 }
725 if (points_.size() == oldSize) {
726 return;
727 }
728 std::sort(points_.begin() + static_cast<std::ptrdiff_t>(oldSize), points_.end());
729 std::inplace_merge(points_.begin(), points_.begin() + static_cast<std::ptrdiff_t>(oldSize), points_.end());
730 points_.erase(std::unique(points_.begin(), points_.end()), points_.end());
731 resetCache();
732 }
733
748 constexpr void erase(std::size_t index)
749 requires detail::ownsChainStorage<Storage, PointType>
750 {
751 assert(index < size());
752 points_.erase(points_.begin() + static_cast<std::ptrdiff_t>(index));
753 resetCache();
754 }
755
772 constexpr bool erase(const PointType& point)
773 requires detail::ownsChainStorage<Storage, PointType>
774 {
775 const PointType query = point - translation_;
776 const auto it = std::lower_bound(points_.begin(), points_.end(), query);
777 if (it == points_.end() || *it != query) {
778 return false;
779 }
780 points_.erase(it);
781 resetCache();
782 return true;
783 }
784
800 template <class OtherNumber>
801 [[nodiscard]] constexpr std::optional<std::size_t> indexAtX(const OtherNumber& x) const;
802
820 template <class ResultNumber = division_result_t<NumberType>, class OtherNumber>
821 [[nodiscard]] constexpr std::optional<ResultNumber> yAtX(const OtherNumber& x) const;
822
841 template <PointConcept OtherPoint>
842 [[nodiscard]] constexpr std::optional<std::size_t> isStrictlyBelow(const OtherPoint& point) const;
843
858 template <PointConcept OtherPoint>
859 [[nodiscard]] constexpr std::optional<std::size_t> isStrictlyAbove(const OtherPoint& point) const;
860
861
879 template <PointConcept OtherPoint>
880 [[nodiscard]] constexpr std::optional<std::size_t> isBelow(const OtherPoint& point) const;
881
895 template <PointConcept OtherPoint>
896 [[nodiscard]] constexpr std::optional<std::size_t> isAbove(const OtherPoint& point) const;
897
907 template<PointConcept OtherPoint>
908 [[nodiscard]] constexpr bool contains(const OtherPoint& point) const;
909
925 template<SegmentConcept OtherSegment>
926 [[nodiscard]] constexpr bool contains(const OtherSegment& other) const;
927
929 template<OrientedSegmentConcept OtherOrientedSegment>
930 [[nodiscard]] constexpr bool contains(const OtherOrientedSegment& other) const;
931
936 template<LineConcept OtherLine>
937 [[nodiscard]] constexpr bool contains(const OtherLine& other) const;
938
943 template<OrientedLineConcept OtherOrientedLine>
944 [[nodiscard]] constexpr bool contains(const OtherOrientedLine& other) const;
945
950 template<RayConcept OtherRay>
951 [[nodiscard]] constexpr bool contains(const OtherRay& other) const;
952
957 template<HalfplaneConcept OtherHalfplane>
958 [[nodiscard]] constexpr bool contains(const OtherHalfplane& other) const;
959
964 template<RectangleConcept OtherRectangle>
965 [[nodiscard]] constexpr bool contains(const OtherRectangle& other) const;
966
971 template<TriangleConcept OtherTriangle>
972 [[nodiscard]] constexpr bool contains(const OtherTriangle& other) const;
973
978 template<ConvexConcept OtherConvex>
979 [[nodiscard]] constexpr bool contains(const OtherConvex& other) const;
980
988 template<PolygonConcept OtherPolygon>
989 [[nodiscard]] constexpr bool contains(const OtherPolygon& other) const;
990
995 template<DiskConcept OtherDisk>
996 [[nodiscard]] constexpr bool contains(const OtherDisk& other) const;
997
999 template <class EmptyPoint>
1000 [[nodiscard]] constexpr bool contains(const EmptyShape<EmptyPoint>&) const {
1001 return true;
1002 }
1003
1013 template<MonotoneChainConcept OtherChain>
1014 [[nodiscard]] constexpr bool contains(const OtherChain& other) const;
1015
1017 template<PointConcept OtherPoint>
1018 [[nodiscard]] constexpr bool contains(const Shape<OtherPoint>& other) const;
1019
1032 template<PointConcept OtherPoint>
1033 [[nodiscard]] constexpr bool boundaryContains(const OtherPoint& point) const;
1034
1035 // The boundary of a chain is exactly its two extreme vertices, a finite
1036 // point set, so it contains no positive-length or two-dimensional shape.
1038 template<SegmentConcept OtherSegment>
1039 [[nodiscard]] constexpr bool boundaryContains(const OtherSegment& other) const {
1040 return detail::reduceDegenerateToPoint(
1041 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1042 }
1043
1044 template<OrientedSegmentConcept OtherOrientedSegment>
1045 [[nodiscard]] constexpr bool boundaryContains(const OtherOrientedSegment& other) const {
1046 return detail::reduceDegenerateToPoint(
1047 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1048 }
1049
1050 template<LineConcept OtherLine>
1051 [[nodiscard]] constexpr bool boundaryContains(const OtherLine&) const { return false; }
1053 template<OrientedLineConcept OtherOrientedLine>
1054 [[nodiscard]] constexpr bool boundaryContains(const OtherOrientedLine&) const { return false; }
1056 template<RayConcept OtherRay>
1057 [[nodiscard]] constexpr bool boundaryContains(const OtherRay&) const { return false; }
1059 template<HalfplaneConcept OtherHalfplane>
1060 [[nodiscard]] constexpr bool boundaryContains(const OtherHalfplane&) const { return false; }
1062 template<RectangleConcept OtherRectangle>
1063 [[nodiscard]] constexpr bool boundaryContains(const OtherRectangle& other) const {
1064 return detail::reduceDegenerateToPoint(
1065 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1066 }
1067
1068 template<TriangleConcept OtherTriangle>
1069 [[nodiscard]] constexpr bool boundaryContains(const OtherTriangle& other) const {
1070 return detail::reduceDegenerateToPoint(
1071 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1072 }
1073
1074 template<ConvexConcept OtherConvex>
1075 [[nodiscard]] constexpr bool boundaryContains(const OtherConvex& other) const {
1076 return detail::reduceDegenerateToPoint(
1077 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1078 }
1079
1080 template<PolygonConcept OtherPolygon>
1081 [[nodiscard]] constexpr bool boundaryContains(const OtherPolygon& other) const {
1082 return detail::reduceDegenerateToPoint(
1083 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1084 }
1085
1086 template<DiskConcept OtherDisk>
1087 [[nodiscard]] constexpr bool boundaryContains(const OtherDisk& other) const {
1088 return detail::reduceDegenerateToPoint(
1089 other, [this](const auto& vertex) { return this->boundaryContains(vertex); });
1090 }
1091
1092 template<MonotoneChainConcept OtherChain>
1093 [[nodiscard]] constexpr bool boundaryContains(const OtherChain& other) const {
1094 // The boundary is the two extreme vertices, so only a chain without an
1095 // edge fits inside it.
1096 return other.empty() || (other.size() == 1 && boundaryContains(other[0]));
1097 }
1098
1099 template <class EmptyPoint>
1100 [[nodiscard]] constexpr bool boundaryContains(const EmptyShape<EmptyPoint>&) const {
1101 return true;
1102 }
1103
1104 template<PointConcept OtherPoint>
1105 [[nodiscard]] constexpr bool boundaryContains(const Shape<OtherPoint>& other) const;
1106
1119 template<PointConcept OtherPoint>
1120 [[nodiscard]] constexpr bool interiorContains(const OtherPoint& point) const;
1121
1133 template<SegmentConcept OtherSegment>
1134 [[nodiscard]] constexpr bool interiorContains(const OtherSegment& other) const;
1135
1137 template<OrientedSegmentConcept OtherOrientedSegment>
1138 [[nodiscard]] constexpr bool interiorContains(const OtherOrientedSegment& other) const;
1139
1141 template<LineConcept OtherLine>
1142 [[nodiscard]] constexpr bool interiorContains(const OtherLine& other) const;
1143
1145 template<OrientedLineConcept OtherOrientedLine>
1146 [[nodiscard]] constexpr bool interiorContains(const OtherOrientedLine& other) const;
1147
1149 template<RayConcept OtherRay>
1150 [[nodiscard]] constexpr bool interiorContains(const OtherRay& other) const;
1151
1153 template<HalfplaneConcept OtherHalfplane>
1154 [[nodiscard]] constexpr bool interiorContains(const OtherHalfplane& other) const;
1155
1157 template<TriangleConcept OtherTriangle>
1158 [[nodiscard]] constexpr bool interiorContains(const OtherTriangle& other) const;
1159
1160 // A chain is one-dimensional: its relative interior cannot contain any
1161 // unbounded or two-dimensional shape.
1163 template<RectangleConcept OtherRectangle>
1164 [[nodiscard]] constexpr bool interiorContains(const OtherRectangle& other) const {
1165 return detail::reduceDegenerateGuarded(
1166 other, [this](const auto& carrier) { return this->interiorContains(carrier); });
1167 }
1168
1169 template<ConvexConcept OtherConvex>
1170 [[nodiscard]] constexpr bool interiorContains(const OtherConvex& other) const {
1171 return detail::reduceDegenerateGuarded(
1172 other, [this](const auto& carrier) { return this->interiorContains(carrier); });
1173 }
1174
1175 template<PolygonConcept OtherPolygon>
1176 [[nodiscard]] constexpr bool interiorContains(const OtherPolygon& other) const {
1177 return detail::reduceDegenerate(
1178 other, [this](const auto& carrier) { return this->interiorContains(carrier); });
1179 }
1180
1181 template<DiskConcept OtherDisk>
1182 [[nodiscard]] constexpr bool interiorContains(const OtherDisk& other) const {
1183 return detail::reduceDegenerate(
1184 other, [this](const auto& carrier) { return this->interiorContains(carrier); });
1185 }
1186
1187 template<MonotoneChainConcept OtherChain>
1188 [[nodiscard]] constexpr bool interiorContains(const OtherChain& other) const;
1190 template <class EmptyPoint>
1191 [[nodiscard]] constexpr bool interiorContains(const EmptyShape<EmptyPoint>&) const {
1192 return true;
1193 }
1194
1195 template<PointConcept OtherPoint>
1196 [[nodiscard]] constexpr bool interiorContains(const Shape<OtherPoint>& other) const;
1197
1203 template<PointConcept OtherPoint>
1204 [[nodiscard]] constexpr bool intersects(const OtherPoint& other) const;
1205
1219 template<SegmentConcept OtherSegment>
1220 [[nodiscard]] constexpr bool intersects(const OtherSegment& other) const;
1221
1223 template<OrientedSegmentConcept OtherOrientedSegment>
1224 [[nodiscard]] constexpr bool intersects(const OtherOrientedSegment& other) const;
1225
1239 template<MonotoneChainConcept OtherChain>
1240 [[nodiscard]] constexpr bool intersects(const OtherChain& other) const;
1241
1243 template<LineConcept OtherLine>
1244 [[nodiscard]] constexpr bool intersects(const OtherLine& other) const;
1246 template<OrientedLineConcept OtherOrientedLine>
1247 [[nodiscard]] constexpr bool intersects(const OtherOrientedLine& other) const;
1249 template<RayConcept OtherRay>
1250 [[nodiscard]] constexpr bool intersects(const OtherRay& other) const;
1252 template<HalfplaneConcept OtherHalfplane>
1253 [[nodiscard]] constexpr bool intersects(const OtherHalfplane& other) const;
1255 template<RectangleConcept OtherRectangle>
1256 [[nodiscard]] constexpr bool intersects(const OtherRectangle& other) const;
1258 template<TriangleConcept OtherTriangle>
1259 [[nodiscard]] constexpr bool intersects(const OtherTriangle& other) const;
1261 template<ConvexConcept OtherConvex>
1262 [[nodiscard]] constexpr bool intersects(const OtherConvex& other) const;
1264 template<DiskConcept OtherDisk>
1265 [[nodiscard]] constexpr bool intersects(const OtherDisk& other) const;
1266
1268 template <class EmptyPoint>
1269 [[nodiscard]] constexpr bool intersects(const EmptyShape<EmptyPoint>&) const {
1270 return false;
1271 }
1272
1274 template<PointConcept OtherPoint>
1275 [[nodiscard]] constexpr bool intersects(const Shape<OtherPoint>& other) const;
1276
1278 template<typename OtherShape>
1279 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1280 [[nodiscard]] constexpr bool intersects(const OtherShape& other) const {
1281 return other.intersects(*this);
1282 }
1283
1291 template<PointConcept OtherPoint>
1292 [[nodiscard]] constexpr bool interiorsIntersect(const OtherPoint& other) const;
1293
1309 template<SegmentConcept OtherSegment>
1310 [[nodiscard]] constexpr bool interiorsIntersect(const OtherSegment& other) const;
1311
1313 template<OrientedSegmentConcept OtherOrientedSegment>
1314 [[nodiscard]] constexpr bool interiorsIntersect(const OtherOrientedSegment& other) const;
1315
1317 template<LineConcept OtherLine>
1318 [[nodiscard]] constexpr bool interiorsIntersect(const OtherLine& other) const;
1320 template<OrientedLineConcept OtherOrientedLine>
1321 [[nodiscard]] constexpr bool interiorsIntersect(const OtherOrientedLine& other) const;
1323 template<RayConcept OtherRay>
1324 [[nodiscard]] constexpr bool interiorsIntersect(const OtherRay& other) const;
1326 template<HalfplaneConcept OtherHalfplane>
1327 [[nodiscard]] constexpr bool interiorsIntersect(const OtherHalfplane& other) const;
1329 template<RectangleConcept OtherRectangle>
1330 [[nodiscard]] constexpr bool interiorsIntersect(const OtherRectangle& other) const;
1332 template<TriangleConcept OtherTriangle>
1333 [[nodiscard]] constexpr bool interiorsIntersect(const OtherTriangle& other) const;
1335 template<ConvexConcept OtherConvex>
1336 [[nodiscard]] constexpr bool interiorsIntersect(const OtherConvex& other) const;
1338 template<DiskConcept OtherDisk>
1339 [[nodiscard]] constexpr bool interiorsIntersect(const OtherDisk& other) const;
1348 template<MonotoneChainConcept OtherChain>
1349 [[nodiscard]] constexpr bool interiorsIntersect(const OtherChain& other) const;
1350
1352 template <class EmptyPoint>
1353 [[nodiscard]] constexpr bool interiorsIntersect(const EmptyShape<EmptyPoint>&) const {
1354 return false;
1355 }
1356
1358 template<PointConcept OtherPoint>
1359 [[nodiscard]] constexpr bool interiorsIntersect(const Shape<OtherPoint>& other) const;
1360
1362 template<typename OtherShape>
1363 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1364 [[nodiscard]] constexpr bool interiorsIntersect(const OtherShape& other) const {
1365 return other.interiorsIntersect(*this);
1366 }
1367
1373 template<PointConcept OtherPoint>
1374 [[nodiscard]] constexpr bool separates(const OtherPoint&) const {
1375 return false;
1376 }
1377
1386 template<SegmentConcept OtherSegment>
1387 [[nodiscard]] constexpr bool separates(const OtherSegment& other) const;
1389 template<OrientedSegmentConcept OtherOrientedSegment>
1390 [[nodiscard]] constexpr bool separates(const OtherOrientedSegment& other) const;
1392 template<LineConcept OtherLine>
1393 [[nodiscard]] constexpr bool separates(const OtherLine& other) const;
1395 template<OrientedLineConcept OtherOrientedLine>
1396 [[nodiscard]] constexpr bool separates(const OtherOrientedLine& other) const;
1398 template<RayConcept OtherRay>
1399 [[nodiscard]] constexpr bool separates(const OtherRay& other) const;
1400
1401 // --- 2-dimensional targets: the crosscut scan of separatesTwoDimensional
1402 // (an edge disconnects the region by itself, or the chain runs
1403 // outside-interior-outside) ---
1411 template<HalfplaneConcept OtherHalfplane>
1412 [[nodiscard]] constexpr bool separates(const OtherHalfplane& other) const;
1414 template<RectangleConcept OtherRectangle>
1415 [[nodiscard]] constexpr bool separates(const OtherRectangle& other) const;
1417 template<TriangleConcept OtherTriangle>
1418 [[nodiscard]] constexpr bool separates(const OtherTriangle& other) const;
1420 template<DiskConcept OtherDisk>
1421 [[nodiscard]] constexpr bool separates(const OtherDisk& other) const;
1423 template<ConvexConcept OtherConvex>
1424 [[nodiscard]] constexpr bool separates(const OtherConvex& other) const;
1432 template<PolygonConcept OtherPolygon>
1433 [[nodiscard]] constexpr bool separates(const OtherPolygon& other) const;
1444 template<MonotoneChainConcept OtherChain>
1445 [[nodiscard]] constexpr bool separates(const OtherChain& other) const;
1446
1448 template<PolylineConcept OtherPolyline>
1449 [[nodiscard]] constexpr bool contains(const OtherPolyline& other) const;
1450
1452 template<PolylineConcept OtherPolyline>
1453 [[nodiscard]] constexpr bool boundaryContains(const OtherPolyline& other) const {
1454 // The boundary is the two extreme vertices, so only a polyline
1455 // covering at most one point fits inside it.
1456 return other.empty() || (other.isDegenerate() && boundaryContains(other[0]));
1457 }
1458
1460 template<PolylineConcept OtherPolyline>
1461 [[nodiscard]] constexpr bool interiorContains(const OtherPolyline& other) const;
1462
1469 template<PolylineConcept OtherPolyline>
1470 [[nodiscard]] constexpr bool separates(const OtherPolyline& other) const;
1471
1473 template<HalfplaneIntersectionConcept OtherRegion>
1474 [[nodiscard]] constexpr bool contains(const OtherRegion& other) const;
1475
1477 template<HalfplaneIntersectionConcept OtherRegion>
1478 [[nodiscard]] constexpr bool boundaryContains(const OtherRegion& other) const;
1479
1481 template<HalfplaneIntersectionConcept OtherRegion>
1482 [[nodiscard]] constexpr bool interiorContains(const OtherRegion& other) const;
1483
1485 template<HalfplaneIntersectionConcept OtherRegion>
1486 [[nodiscard]] constexpr bool separates(const OtherRegion& other) const;
1487
1495 template<PolygonWithHolesConcept OtherRegion>
1496 [[nodiscard]] constexpr bool contains(const OtherRegion& other) const;
1497
1504 template<PolygonWithHolesConcept OtherRegion>
1505 [[nodiscard]] constexpr bool boundaryContains(const OtherRegion& other) const;
1506
1508 template<PolygonWithHolesConcept OtherRegion>
1509 [[nodiscard]] constexpr bool interiorContains(const OtherRegion& other) const;
1510
1518 template<PolygonWithHolesConcept OtherRegion>
1519 [[nodiscard]] bool separates(const OtherRegion& other) const;
1520
1521 // -------------------------------------------------------------------------
1522 // A set of regions
1523 //
1524 // It outranks every other shape, so the symmetric relations reach it through
1525 // the rank-based forwarders and only the asymmetric ones are answered here.
1526 // A set is the union of its components, so it is contained exactly when
1527 // every component is — no matter what this shape is.
1528
1530 template<PolygonSetConcept OtherSet>
1531 [[nodiscard]] constexpr bool contains(const OtherSet& other) const {
1532 for (const auto& component : other) {
1533 if (!contains(component)) {
1534 return false;
1535 }
1536 }
1537 return true;
1538 }
1539
1541 template<PolygonSetConcept OtherSet>
1542 [[nodiscard]] constexpr bool boundaryContains(const OtherSet& other) const {
1543 for (const auto& component : other) {
1544 if (!boundaryContains(component)) {
1545 return false;
1546 }
1547 }
1548 return true;
1549 }
1550
1552 template<PolygonSetConcept OtherSet>
1553 [[nodiscard]] constexpr bool interiorContains(const OtherSet& other) const {
1554 for (const auto& component : other) {
1555 if (!interiorContains(component)) {
1556 return false;
1557 }
1558 }
1559 return true;
1560 }
1561
1570 template<PolygonSetConcept OtherSet>
1571 [[nodiscard]] bool separates(const OtherSet& other) const;
1572
1574 template <class EmptyPoint>
1575 [[nodiscard]] constexpr bool separates(const EmptyShape<EmptyPoint>&) const {
1576 return false;
1577 }
1578
1579 template<PointConcept OtherPoint>
1580 [[nodiscard]] constexpr bool separates(const Shape<OtherPoint>& other) const;
1581
1583 template<PointConcept OtherPoint>
1584 [[nodiscard]] constexpr bool crosses(const OtherPoint&) const {
1585 return false;
1586 }
1587
1588 template<SegmentConcept OtherSegment>
1589 [[nodiscard]] constexpr bool crosses(const OtherSegment& other) const;
1591 template<OrientedSegmentConcept OtherOrientedSegment>
1592 [[nodiscard]] constexpr bool crosses(const OtherOrientedSegment& other) const;
1594 template<LineConcept OtherLine>
1595 [[nodiscard]] constexpr bool crosses(const OtherLine& other) const;
1597 template<OrientedLineConcept OtherOrientedLine>
1598 [[nodiscard]] constexpr bool crosses(const OtherOrientedLine& other) const;
1600 template<RayConcept OtherRay>
1601 [[nodiscard]] constexpr bool crosses(const OtherRay& other) const;
1603 template<HalfplaneConcept OtherHalfplane>
1604 [[nodiscard]] constexpr bool crosses(const OtherHalfplane& other) const;
1606 template<RectangleConcept OtherRectangle>
1607 [[nodiscard]] constexpr bool crosses(const OtherRectangle& other) const;
1609 template<TriangleConcept OtherTriangle>
1610 [[nodiscard]] constexpr bool crosses(const OtherTriangle& other) const;
1612 template<DiskConcept OtherDisk>
1613 [[nodiscard]] constexpr bool crosses(const OtherDisk& other) const;
1615 template<ConvexConcept OtherConvex>
1616 [[nodiscard]] constexpr bool crosses(const OtherConvex& other) const;
1618 template<MonotoneChainConcept OtherChain>
1619 [[nodiscard]] constexpr bool crosses(const OtherChain& other) const;
1621 template <class EmptyPoint>
1622 [[nodiscard]] constexpr bool crosses(const EmptyShape<EmptyPoint>&) const {
1623 return false;
1624 }
1625
1626 template<PointConcept OtherPoint>
1627 [[nodiscard]] constexpr bool crosses(const Shape<OtherPoint>& other) const;
1629 template<typename OtherShape>
1630 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1631 [[nodiscard]] constexpr bool crosses(const OtherShape& other) const {
1632 return other.crosses(*this);
1633 }
1634
1648 template<MonotoneChainConcept OtherChain>
1649 [[nodiscard]] constexpr bool edgesCross(const OtherChain& other) const;
1650
1652 template <class ResultNumber = NumberType, PointConcept OtherPoint>
1653 [[nodiscard]] constexpr std::optional<Point<ResultNumber, typename PointType::LabelType>>
1654 intersection(const OtherPoint& other) const;
1655
1668 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1669 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1671 intersection(const OtherSegment& other) const;
1673 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1674 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1676 intersection(const OtherOrientedSegment& other) const;
1678 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1679 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1681 intersection(const OtherLine& other) const;
1683 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1684 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1686 intersection(const OtherOrientedLine& other) const;
1688 template <class ResultNumber = division_result_t<NumberType>, RayConcept OtherRay>
1689 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1691 intersection(const OtherRay& other) const;
1693 template <class ResultNumber = division_result_t<NumberType>, HalfplaneConcept OtherHalfplane>
1694 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1696 intersection(const OtherHalfplane& other) const;
1698 template <class ResultNumber = division_result_t<NumberType>, RectangleConcept OtherRectangle>
1699 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1701 intersection(const OtherRectangle& other) const;
1703 template <class ResultNumber = division_result_t<NumberType>, TriangleConcept OtherTriangle>
1704 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1706 intersection(const OtherTriangle& other) const;
1708 template <class ResultNumber = division_result_t<NumberType>, ConvexConcept OtherConvex>
1709 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1711 intersection(const OtherConvex& other) const;
1712
1714 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1715 requires (!PointConcept<OtherShape>
1716 && (detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1717 && requires(const OtherShape& o, const MonotoneChain& self) {
1718 o.template intersection<ResultNumber>(self);
1719 })
1720 [[nodiscard]] constexpr auto intersection(const OtherShape& other) const {
1721 return other.template intersection<ResultNumber>(*this);
1722 }
1723
1743 template <class ResultNumber = division_result_t<NumberType>, MonotoneChainConcept OtherChain>
1744 [[nodiscard]] constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
1746 intersection(const OtherChain& other) const;
1747
1749 template <class ResultNumber = NumberType, class EmptyPoint>
1750 [[nodiscard]] constexpr EmptyShape<EmptyPoint> intersection(const EmptyShape<EmptyPoint>&) const {
1751 return {};
1752 }
1753
1770 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1771 [[nodiscard]] constexpr auto squaredDistance(const OtherPoint& point) const;
1773 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1774 [[nodiscard]] constexpr auto squaredDistance(const OtherSegment& other) const;
1776 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1777 [[nodiscard]] constexpr auto squaredDistance(const OtherOrientedSegment& other) const;
1779 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1780 [[nodiscard]] constexpr auto squaredDistance(const OtherLine& other) const;
1782 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1783 [[nodiscard]] constexpr auto squaredDistance(const OtherOrientedLine& other) const;
1785 template <class ResultNumber = division_result_t<NumberType>, RayConcept OtherRay>
1786 [[nodiscard]] constexpr auto squaredDistance(const OtherRay& other) const;
1788 template <class ResultNumber = division_result_t<NumberType>, HalfplaneConcept OtherHalfplane>
1789 [[nodiscard]] constexpr auto squaredDistance(const OtherHalfplane& other) const;
1791 template <class ResultNumber = division_result_t<NumberType>, RectangleConcept OtherRectangle>
1792 [[nodiscard]] constexpr auto squaredDistance(const OtherRectangle& other) const;
1794 template <class ResultNumber = division_result_t<NumberType>, TriangleConcept OtherTriangle>
1795 [[nodiscard]] constexpr auto squaredDistance(const OtherTriangle& other) const;
1797 template <class ResultNumber = division_result_t<NumberType>, ConvexConcept OtherConvex>
1798 [[nodiscard]] constexpr auto squaredDistance(const OtherConvex& other) const;
1800 template <class ResultNumber = division_result_t<NumberType>, MonotoneChainConcept OtherChain>
1801 [[nodiscard]] constexpr auto squaredDistance(const OtherChain& other) const;
1802
1810 template <class ResultNumber = double, class DiskPointType, class DiskLabel>
1811 [[nodiscard]] detail::floating_result_t<ResultNumber> squaredDistance(
1812 const Disk<DiskPointType, DiskLabel>& disk) const;
1813
1820 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1821 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1822 && requires(const OtherShape& o, const MonotoneChain& self) {
1823 o.template squaredDistance<ResultNumber>(self);
1824 })
1825 [[nodiscard]] constexpr auto squaredDistance(const OtherShape& other) const {
1826 return other.template squaredDistance<ResultNumber>(*this);
1827 }
1828
1841 template <class ResultNumber = NumberType, BoundedPolygonalConcept OtherShape>
1842 requires detail::ClosestPairConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape>
1843 [[nodiscard]] constexpr auto closestSegments(const OtherShape& other) const;
1844
1861 template <class ResultNumber = division_result_t<NumberType>, class OtherShape>
1862 requires detail::ClosestPointsPairConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape>
1863 [[nodiscard]] constexpr auto closestPoints(const OtherShape& other) const;
1864
1875 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1876 [[nodiscard]] constexpr auto distanceL1(const OtherPoint& point) const;
1878 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1879 [[nodiscard]] constexpr auto distanceL1(const OtherSegment& other) const;
1881 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1882 [[nodiscard]] constexpr auto distanceL1(const OtherOrientedSegment& other) const;
1884 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1885 [[nodiscard]] constexpr auto distanceL1(const OtherLine& other) const;
1887 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1888 [[nodiscard]] constexpr auto distanceL1(const OtherOrientedLine& other) const;
1890 template <class ResultNumber = division_result_t<NumberType>, RayConcept OtherRay>
1891 [[nodiscard]] constexpr auto distanceL1(const OtherRay& other) const;
1893 template <class ResultNumber = division_result_t<NumberType>, HalfplaneConcept OtherHalfplane>
1894 [[nodiscard]] constexpr auto distanceL1(const OtherHalfplane& other) const;
1896 template <class ResultNumber = division_result_t<NumberType>, RectangleConcept OtherRectangle>
1897 [[nodiscard]] constexpr auto distanceL1(const OtherRectangle& other) const;
1899 template <class ResultNumber = division_result_t<NumberType>, TriangleConcept OtherTriangle>
1900 [[nodiscard]] constexpr auto distanceL1(const OtherTriangle& other) const;
1902 template <class ResultNumber = division_result_t<NumberType>, ConvexConcept OtherConvex>
1903 [[nodiscard]] constexpr auto distanceL1(const OtherConvex& other) const;
1905 template <class ResultNumber = division_result_t<NumberType>, MonotoneChainConcept OtherChain>
1906 [[nodiscard]] constexpr auto distanceL1(const OtherChain& other) const;
1907
1914 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1915 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
1916 && requires(const OtherShape& o, const MonotoneChain& self) {
1917 o.template distanceL1<ResultNumber>(self);
1918 })
1919 [[nodiscard]] constexpr auto distanceL1(const OtherShape& other) const {
1920 return other.template distanceL1<ResultNumber>(*this);
1921 }
1922
1938 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1939 [[nodiscard]] constexpr auto intersection(const Shape<OtherPoint>& other) const {
1940 return other.template intersection<ResultNumber>(*this);
1941 }
1942
1947 template <class ResultNumber = double, PointConcept OtherPoint>
1948 [[nodiscard]] constexpr auto distanceL1(const Shape<OtherPoint>& other) const {
1949 return other.template distanceL1<ResultNumber>(*this);
1950 }
1951
1962 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1963 [[nodiscard]] constexpr auto distanceLInf(const OtherPoint& point) const;
1965 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1966 [[nodiscard]] constexpr auto distanceLInf(const OtherSegment& other) const;
1968 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1969 [[nodiscard]] constexpr auto distanceLInf(const OtherOrientedSegment& other) const;
1971 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1972 [[nodiscard]] constexpr auto distanceLInf(const OtherLine& other) const;
1974 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1975 [[nodiscard]] constexpr auto distanceLInf(const OtherOrientedLine& other) const;
1977 template <class ResultNumber = division_result_t<NumberType>, RayConcept OtherRay>
1978 [[nodiscard]] constexpr auto distanceLInf(const OtherRay& other) const;
1980 template <class ResultNumber = division_result_t<NumberType>, HalfplaneConcept OtherHalfplane>
1981 [[nodiscard]] constexpr auto distanceLInf(const OtherHalfplane& other) const;
1983 template <class ResultNumber = division_result_t<NumberType>, RectangleConcept OtherRectangle>
1984 [[nodiscard]] constexpr auto distanceLInf(const OtherRectangle& other) const;
1986 template <class ResultNumber = division_result_t<NumberType>, TriangleConcept OtherTriangle>
1987 [[nodiscard]] constexpr auto distanceLInf(const OtherTriangle& other) const;
1989 template <class ResultNumber = division_result_t<NumberType>, ConvexConcept OtherConvex>
1990 [[nodiscard]] constexpr auto distanceLInf(const OtherConvex& other) const;
1992 template <class ResultNumber = division_result_t<NumberType>, MonotoneChainConcept OtherChain>
1993 [[nodiscard]] constexpr auto distanceLInf(const OtherChain& other) const;
1994
2001 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
2002 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<MonotoneChain>)
2003 && requires(const OtherShape& o, const MonotoneChain& self) {
2004 o.template distanceLInf<ResultNumber>(self);
2005 })
2006 [[nodiscard]] constexpr auto distanceLInf(const OtherShape& other) const {
2007 return other.template distanceLInf<ResultNumber>(*this);
2008 }
2009
2014 template <class ResultNumber = double, PointConcept OtherPoint>
2015 [[nodiscard]] constexpr auto distanceLInf(const Shape<OtherPoint>& other) const {
2016 return other.template distanceLInf<ResultNumber>(*this);
2017 }
2018
2023 template <class ApproximateNumber = double>
2024 ApproximateNumber length() const;
2025
2027 constexpr auto lengthL1() const;
2028
2030 constexpr auto lengthLInf() const;
2031
2041 template <class ResultNumber = division_result_t<NumberType>>
2042 [[nodiscard]] constexpr Point<ResultNumber> pointInside() const;
2043
2052 template <class OtherShape>
2053 [[nodiscard]] constexpr bool pointInsideInteriorContainedIn(const OtherShape& shape) const;
2054
2066 [[nodiscard]] constexpr OwningChain rotated90(int k = 1) const;
2067
2073 constexpr void rotate90(int k = 1)
2074 requires detail::ownsChainStorage<Storage, PointType>;
2075
2077 template <class OtherNumber>
2078 [[nodiscard]] constexpr OwningChain scaledUpX(const OtherNumber scalar) const;
2079
2081 template <class OtherNumber>
2082 constexpr void scaleUpX(const OtherNumber scalar)
2083 requires detail::ownsChainStorage<Storage, PointType>;
2084
2086 template <class OtherNumber>
2087 [[nodiscard]] constexpr OwningChain scaledUpY(const OtherNumber scalar) const;
2088
2090 template <class OtherNumber>
2091 constexpr void scaleUpY(const OtherNumber scalar)
2092 requires detail::ownsChainStorage<Storage, PointType>;
2093
2095 template <class OtherNumber>
2096 [[nodiscard]] constexpr OwningChain scaledDownX(const OtherNumber scalar) const;
2097
2099 template <class OtherNumber>
2100 constexpr void scaleDownX(const OtherNumber scalar)
2101 requires detail::ownsChainStorage<Storage, PointType>;
2102
2104 template <class OtherNumber>
2105 [[nodiscard]] constexpr OwningChain scaledDownY(const OtherNumber scalar) const;
2106
2108 template <class OtherNumber>
2109 constexpr void scaleDownY(const OtherNumber scalar)
2110 requires detail::ownsChainStorage<Storage, PointType>;
2111
2125 template <class OtherShape>
2126 requires MinkowskiSummableConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape>
2127 [[nodiscard]] constexpr auto minkowskiSum(const OtherShape& other) const;
2128
2151 template <class OtherShape>
2152 requires MinkowskiSummableConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape>
2153 [[nodiscard]] constexpr auto minkowskiErosion(const OtherShape& other) const;
2154
2186 template <class ResultNumber = division_result_t<NumberType>, class OtherShape>
2187 requires (!MinkowskiSummableConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape> &&
2188 BoundedPolygonalConcept<OtherShape>)
2189 [[nodiscard]] PolygonSet<Point<ResultNumber, typename PointType_::LabelType>>
2190 minkowskiErosion(const OtherShape& other) const;
2191
2238 template <class ResultNumber = division_result_t<NumberType>, ConvexConcept OtherConvex>
2239 [[nodiscard]] Polygon<Point<ResultNumber, typename PointType::LabelType>>
2240 minkowskiSum(const OtherConvex& other) const;
2241
2243 template <class ResultNumber = division_result_t<NumberType>, TriangleConcept OtherTriangle>
2244 [[nodiscard]] Polygon<Point<ResultNumber, typename PointType::LabelType>>
2245 minkowskiSum(const OtherTriangle& other) const;
2246
2248 template <class ResultNumber = division_result_t<NumberType>, RectangleConcept OtherRectangle>
2249 [[nodiscard]] Polygon<Point<ResultNumber, typename PointType::LabelType>>
2250 minkowskiSum(const OtherRectangle& other) const;
2251
2278 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
2279 [[nodiscard]] PolygonSet<Point<ResultNumber, typename PointType::LabelType>>
2280 minkowskiSum(const OtherSegment& other) const;
2281
2288 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOriented>
2289 [[nodiscard]] PolygonSet<Point<ResultNumber, typename PointType::LabelType>>
2290 minkowskiSum(const OtherOriented& other) const;
2291
2307 template <class ResultNumber = division_result_t<NumberType>, MonotoneChainConcept OtherChain>
2308 [[nodiscard]] PolygonSet<Point<ResultNumber, typename PointType::LabelType>>
2309 minkowskiSum(const OtherChain& other) const;
2310
2321 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
2322 requires(!MinkowskiSummableConcept<MonotoneChain<PointType_, TLabel, Storage>, OtherShape>
2323 && (detail::shapeRank<OtherShape> >
2324 detail::shapeRank<MonotoneChain<PointType_, TLabel, Storage>>)
2325 && requires(const OtherShape& o, const MonotoneChain& self) {
2326 o.template minkowskiSum<ResultNumber>(self);
2327 })
2328 [[nodiscard]] auto minkowskiSum(const OtherShape& other) const {
2329 return other.template minkowskiSum<ResultNumber>(*this);
2330 }
2331
2337 template<PointConcept OtherPoint>
2338 constexpr MonotoneChain& operator+=(const OtherPoint& translation) {
2339 translation_ += translation;
2340 // A pure translation merely shifts the bounding box, so update the
2341 // cached bbox in place rather than discarding it. The hash, however,
2342 // depends on the absolute vertex positions, so it must be invalidated.
2343 if (!bbox_.empty()) {
2344 bbox_ += translation;
2345 }
2346 hash_ = hashUnset_;
2347 return *this;
2348 }
2349
2355 template<PointConcept OtherPoint>
2356 constexpr MonotoneChain& operator-=(const OtherPoint& translation) {
2357 translation_ -= translation;
2358 if (!bbox_.empty()) {
2359 bbox_ -= translation;
2360 }
2361 hash_ = hashUnset_;
2362 return *this;
2363 }
2364
2372 template <class Scalar>
2373 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar> &&
2374 detail::ownsChainStorage<Storage, PointType>)
2375 constexpr MonotoneChain& operator*=(const Scalar& scalar) {
2376 for (auto& vertex : points_) {
2377 vertex *= scalar;
2378 }
2379 translation_ *= scalar;
2380 normalize();
2381 resetCache();
2382 return *this;
2383 }
2384
2390 template <class Scalar>
2391 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar> &&
2392 detail::ownsChainStorage<Storage, PointType>)
2393 constexpr MonotoneChain& operator/=(const Scalar& scalar) {
2394 for (auto& vertex : points_) {
2395 vertex /= scalar;
2396 }
2397 translation_ /= scalar;
2398 normalize();
2399 resetCache();
2400 return *this;
2401 }
2402
2409 template <bool Oriented>
2411 public:
2412 using iterator_category = std::forward_iterator_tag;
2413 using iterator_concept = std::forward_iterator_tag;
2415 using difference_type = std::ptrdiff_t;
2417
2418 constexpr BoundaryIterator() = default;
2419
2420 constexpr value_type operator*() const {
2421 assert(chain != nullptr);
2422 return chain->template boundaryAt<Oriented>(index);
2423 }
2424
2426 ++index;
2427 return *this;
2428 }
2429
2431 BoundaryIterator copy(*this);
2432 ++(*this);
2433 return copy;
2434 }
2435
2436 constexpr bool operator==(const BoundaryIterator& other) const = default;
2437
2438 private:
2439 friend struct MonotoneChain;
2440
2441 constexpr BoundaryIterator(const MonotoneChain* chain_arg, std::size_t index_arg)
2442 : chain(chain_arg), index(index_arg) {}
2443
2444 const MonotoneChain* chain = nullptr;
2445 std::size_t index = 0;
2446 };
2447
2448 private:
2449 Storage points_{};
2450 [[no_unique_address]] mutable LabelType label_{};
2451 PointType translation_{};
2452 // Lazily computed bounding box, invalidated by resetCache() on every
2453 // mutation. The empty rectangle doubles as "not computed yet": a shape
2454 // whose box is genuinely empty has no vertices, so bbox() re-derives it
2455 // with one size check rather than any real work.
2456 mutable Rectangle<PointType> bbox_{};
2457
2458 // Memoized hash, computed lazily by std::hash<MonotoneChain>. hashUnset_
2459 // means "not yet computed"; SIZE_MAX is chosen as the sentinel because it
2460 // is a rare hash output, and the one true hash that would collide with it
2461 // is remapped to hashUnset_ - 1 so the sentinel is never stored as a real
2462 // value. Unlike the bbox, the hash is not translation-invariant, so
2463 // operator+=/-= reset it.
2464 static constexpr std::size_t hashUnset_ = pgl::detail::numeric_limits<std::size_t>::max();
2465 mutable std::size_t hash_ = hashUnset_;
2466 friend struct std::hash<MonotoneChain>;
2467
2468 // Drops the memoized caches; call after any operation that mutates the
2469 // chain's vertices. A pure translation does not need to drop bbox_ (it
2470 // shifts in place, see operator+=), but it must still reset hash_, which
2471 // depends on the absolute vertex positions.
2472 constexpr void resetCache() const {
2473 bbox_ = {};
2474 hash_ = hashUnset_;
2475 }
2476
2477 constexpr std::size_t edgeCount() const {
2478 return points_.empty() ? 0 : points_.size() - 1;
2479 }
2480
2491 template <class LowNumber, class HighNumber>
2492 [[nodiscard]] constexpr std::optional<std::pair<std::size_t, std::size_t>>
2493 edgeWindow(const LowNumber& xlo, const HighNumber& xhi) const;
2494
2504 template <class ResultNumber, class OtherShape>
2505 constexpr ResultNumber edgeMinSquaredDistance(const OtherShape& other) const;
2506
2508 template <class ResultNumber, class OtherShape>
2509 constexpr ResultNumber edgeMinDistanceL1(const OtherShape& other) const;
2510
2512 template <class ResultNumber, class OtherShape>
2513 constexpr ResultNumber edgeMinDistanceLInf(const OtherShape& other) const;
2514
2519 template <class ResultNumber, class OtherShape>
2520 constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
2522 edgeFoldIntersection(const OtherShape& other) const;
2523
2529 template <class ResultNumber>
2530 static constexpr std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
2532 coalescePieces(std::vector<std::variant<Point<ResultNumber, typename PointType::LabelType>,
2534
2543 template <class OtherShape, class TouchesBoundary>
2544 constexpr bool separatesOneDimensional(const OtherShape& other, TouchesBoundary touchesBoundary) const;
2545
2555 template <bool OtherIsConvex = true, class OtherShape>
2556 constexpr bool separatesTwoDimensional(const OtherShape& other) const;
2557
2558 template <bool Oriented>
2559 constexpr BoundaryType<Oriented> boundaryAt(std::size_t index) const {
2560 assert(index + 1 < size());
2561 return BoundaryType<Oriented>((*this)[index], (*this)[index + 1]);
2562 }
2563
2568 constexpr void normalize() {
2569 std::sort(points_.begin(), points_.end());
2570 points_.erase(std::unique(points_.begin(), points_.end()), points_.end());
2571 }
2572
2573 class Iterator {
2574 private:
2575 using BaseIterator = std::ranges::iterator_t<const Storage>;
2576 BaseIterator it;
2577 PointType x;
2578
2579 public:
2580 using iterator_category = std::random_access_iterator_tag;
2581 using difference_type = std::ptrdiff_t;
2582 using value_type = PointType;
2583 using pointer = PointType*;
2584 using reference = PointType&;
2585
2586 Iterator() = default;
2587 Iterator(BaseIterator it, PointType x) : it(it), x(x) {}
2588
2589 // Dereference returns value + x
2590 PointType operator*() const {
2591 return *it + x;
2592 }
2593
2594 // Pre-increment
2595 Iterator& operator++() {
2596 ++it;
2597 return *this;
2598 }
2599
2600 // Post-increment
2601 Iterator operator++(int) {
2602 Iterator tmp = *this;
2603 ++it;
2604 return tmp;
2605 }
2606
2607 // Pre-decrement
2608 Iterator& operator--() {
2609 --it;
2610 return *this;
2611 }
2612
2613 // Post-decrement
2614 Iterator operator--(int) {
2615 Iterator tmp = *this;
2616 --it;
2617 return tmp;
2618 }
2619
2620 // Equality comparison
2621 bool operator==(const Iterator& other) const {
2622 return it == other.it;
2623 }
2624
2625 // Other comparisons
2626 std::strong_ordering operator<=>(const Iterator& other) const {
2627 if (it < other.it) {
2628 return std::strong_ordering::less;
2629 }
2630 if (it > other.it) {
2631 return std::strong_ordering::greater;
2632 }
2633 return std::strong_ordering::equal;
2634 }
2635
2636 // Addition
2637 Iterator operator+(difference_type n) const {
2638 return Iterator(it + n, x);
2639 }
2640
2641 // Subtraction
2642 Iterator operator-(difference_type n) const {
2643 return Iterator(it - n, x);
2644 }
2645
2646 // Difference
2647 difference_type operator-(const Iterator& other) const {
2648 return it - other.it;
2649 }
2650
2651 // Array subscript operator
2652 PointType operator[](difference_type n) const {
2653 return *(it + n) + x;
2654 }
2655 };
2656}; // struct MonotoneChain
2657
2669template <class PointType = Point<>, class Label = NoLabel>
2671
2672template <class PointType, class LabelType, class Storage, class TranslationNumber, class TranslationLabel>
2674 return chain + (-translation);
2675}
2676
2677template <class PointType, class LabelType, class Storage, class Scalar>
2678 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
2679constexpr auto operator*(const MonotoneChain<PointType, LabelType, Storage>& chain, const Scalar& scalar) {
2680 using ResultPointType = Point<decltype(std::declval<PointType>().x() * scalar), typename PointType::LabelType>;
2682 result *= scalar;
2683 if constexpr (detail::has_label_v<LabelType>) {
2684 result.label() = LabelType{};
2685 }
2686 return result;
2687}
2688
2689template <class Scalar, class PointType, class LabelType, class Storage>
2690 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
2691constexpr auto operator*(const Scalar& scalar, const MonotoneChain<PointType, LabelType, Storage>& chain) {
2692 return chain * scalar;
2693}
2694
2695template <class PointType, class LabelType, class Storage, class Scalar>
2696 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
2697constexpr auto operator/(const MonotoneChain<PointType, LabelType, Storage>& chain, const Scalar& scalar) {
2698 using ResultPointType = Point<decltype(std::declval<PointType>().x() / scalar), typename PointType::LabelType>;
2700 result /= scalar;
2701 if constexpr (detail::has_label_v<LabelType>) {
2702 result.label() = LabelType{};
2703 }
2704 return result;
2705}
2706
2707template <class PointType, class LabelType, class Storage>
2708std::ostream& operator<<(std::ostream& stream, const MonotoneChain<PointType, LabelType, Storage>& chain);
2709
2710} // namespace pgl
friend struct MonotoneChain
Definition monotonechain.hpp:2439
constexpr value_type operator*() const
Definition monotonechain.hpp:2420
std::ptrdiff_t difference_type
Definition monotonechain.hpp:2415
std::forward_iterator_tag iterator_concept
Definition monotonechain.hpp:2413
constexpr bool operator==(const BoundaryIterator &other) const =default
std::forward_iterator_tag iterator_category
Definition monotonechain.hpp:2412
value_type reference
Definition monotonechain.hpp:2416
BoundaryType< Oriented > value_type
Definition monotonechain.hpp:2414
constexpr BoundaryIterator & operator++()
Definition monotonechain.hpp:2425
constexpr BoundaryIterator()=default
constexpr BoundaryIterator operator++(int)
Definition monotonechain.hpp:2430
Bounded polygonal primitives, convex or not.
Definition forward.hpp:373
Definition forward.hpp:315
Shape pairs whose Minkowski sum Pangolin can represent.
Definition forward.hpp:476
Definition forward.hpp:320
Definition forward.hpp:308
Definition forward.hpp:306
Definition forward.hpp:313
Definition forward.hpp:307
Definition forward.hpp:324
Definition forward.hpp:314
Definition arrangement.hpp:67
@ y
Definition intervaltree.hpp:24
@ x
Definition intervaltree.hpp:24
@ vertex
Definition bitmatrix.hpp:37
typename DivisionResult< Number >::type division_result_t
Convenience alias for DivisionResult.
Definition rational.hpp:1175
Point() -> Point< int >
constexpr auto operator-(const Point< LeftNumber, LeftLabel > &left, const Point< RightNumber, RightLabel > &right)
Translates a point by the opposite of another point.
Definition transformations.hpp:130
MonotoneChain< PointType, Label, std::span< const PointType > > MonotoneChainView
A non-owning MonotoneChain that views an external, already canonical (sorted, duplicate-free) contigu...
Definition monotonechain.hpp:2670
MonotoneChain() -> MonotoneChain< Point<>, NoLabel >
Definition monotonechain.hpp:2439
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
std::ostream & operator<<(std::ostream &stream, const Point< Number, Label > &point)
Streams a point as (x,y) or label:(x,y).
Definition io.hpp:27
Segment() -> Segment< Point<>, NoLabel >
Closed convex polygon stored by its vertices.
Definition convex.hpp:170
constexpr Segment< PointType > diameter() const
Returns a segment realizing the diameter (the farthest vertex pair).
Definition measures.hpp:696
Closed Euclidean disk stored by boundary points plus optional disk label.
Definition disk.hpp:66
The empty set of points in the plane.
Definition emptyshape.hpp:33
Weakly x-monotone polyline stored by lexicographically sorted vertices.
Definition monotonechain.hpp:146
constexpr bool separates(const OtherHalfplane &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3010
constexpr bool interiorsIntersect(const OtherChain &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1771
constexpr bool separates(const OtherSegment &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:2974
constexpr bool boundaryContains(const OtherPolyline &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1453
constexpr bool contains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition monotonechain.hpp:1000
constexpr bool boundaryContains(const OtherConvex &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1075
constexpr bool contains(const OtherLine &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1863
constexpr bool separates(const OtherPolygon &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3069
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1141
constexpr bool intersects(const OtherLine &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1386
constexpr bool interiorContains(const OtherTriangle &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1416
constexpr bool boundaryContains(const OtherOrientedSegment &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1045
constexpr bool contains(const OtherTriangle &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1904
constexpr bool intersects(const OtherOrientedSegment &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1380
constexpr bool separates(const OtherRegion &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:4676
constexpr void scaleUpX(const OtherNumber scalar)
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherRay &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2648
constexpr bool crosses(const OtherDisk &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:865
constexpr bool separates(const EmptyShape< EmptyPoint > &) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition monotonechain.hpp:1575
constexpr bool contains(const OtherRectangle &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1887
constexpr bool boundaryContains(const OtherRectangle &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1063
constexpr auto squaredDistance(const OtherShape &other) const
Returns the squared Euclidean distance to the given shape.
Definition monotonechain.hpp:1825
constexpr bool separates(const OtherDisk &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3048
constexpr bool separates(const OtherOrientedSegment &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:2982
constexpr bool separates(const Shape< OtherPoint > &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3132
constexpr auto distanceL1(const OtherRectangle &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1216
constexpr std::optional< std::size_t > isStrictlyAbove(const OtherPoint &point) const
Tests whether the whole chain lies strictly above a point at its x.
Definition atxy.hpp:435
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherOrientedLine &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2640
constexpr bool separates(const OtherRay &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3002
constexpr Rectangle< Point< ResultNumber > > fbox() const
Computes the floating-point bounding box of the chain.
Definition bounding.hpp:507
constexpr bool interiorContains(const OtherOrientedLine &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1398
constexpr auto distanceL1(const OtherShape &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition monotonechain.hpp:1919
constexpr Segment< PointType > diameter() const
Returns a segment realizing the diameter (the farthest vertex pair).
Definition monotonechain.hpp:513
constexpr OrientedEdgeIterator orientedEdgesBegin() const
Returns an iterator to the first oriented edge.
Definition monotonechain.hpp:669
constexpr bool boundaryContains(const OtherRay &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1057
constexpr Polyline< PointType > asPolyline() const
Returns the chain as a polyline traversing its vertices in lexicographic order.
Definition polyline.hpp:2602
constexpr bool contains(const OtherPolyline &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2472
Storage StorageType
Definition monotonechain.hpp:150
constexpr auto distanceLInf(const OtherOrientedSegment &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1159
TLabel LabelType
Definition monotonechain.hpp:149
constexpr auto distanceLInf(const OtherConvex &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1222
constexpr auto distanceLInf(const OtherShape &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition monotonechain.hpp:2006
constexpr auto edgesView() const
Returns a lazy view over the edges, materializing each Segment on the fly instead of allocating a vec...
Definition monotonechain.hpp:637
constexpr auto squaredDistance(const OtherRectangle &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1540
constexpr bool intersects(const OtherShape &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition monotonechain.hpp:1280
constexpr auto distanceLInf(const Shape< OtherPoint > &other) const
Returns the distance to the given shape, using symmetry to re-dispatch through the wrapper's own dist...
Definition monotonechain.hpp:2015
constexpr auto distanceLInf(const OtherChain &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1231
constexpr auto orientedEdgesView() const
Lazy view counterpart of orientedEdges(); see edgesView().
Definition monotonechain.hpp:645
constexpr bool erase(const PointType &point)
Removes the given point from the chain's vertices.
Definition monotonechain.hpp:772
bool separates(const OtherSet &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:5996
constexpr void erase(std::size_t index)
Removes the vertex at the given index (in lexicographic order).
Definition monotonechain.hpp:748
constexpr std::optional< std::size_t > indexAtX(const OtherNumber &x) const
Locates the vertex or edge of the chain at a given x-coordinate.
Definition atxy.hpp:346
constexpr bool separates(const OtherOrientedLine &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:2996
constexpr auto intersection(const Shape< OtherPoint > &other) const
Returns the intersection of the two shapes (A ∩ B), re-dispatching through the wrapper's own intersec...
Definition monotonechain.hpp:1939
constexpr bool interiorContains(const Shape< OtherPoint > &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1440
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1353
constexpr auto distanceLInf(const OtherOrientedLine &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1177
constexpr MonotoneChain(Range &&points, bool trusted=false)
Creates a chain from a range of points.
Definition monotonechain.hpp:186
constexpr bool interiorsIntersect(const OtherHalfplane &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1737
constexpr auto distanceLInf(const OtherRay &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1186
constexpr bool intersects(const OtherSegment &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1359
constexpr bool interiorContains(const OtherRectangle &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1164
MonotoneChain< EPoint, TLabel, std::vector< EPoint > > OwningChain
Definition monotonechain.hpp:154
constexpr bool edgesCross(const OtherChain &other) const
Tests whether the two chains have edges that cross.
Definition crosses.hpp:893
constexpr auto distanceL1(const Shape< OtherPoint > &other) const
Returns the distance to the given shape, using symmetry to re-dispatch through the wrapper's own dist...
Definition monotonechain.hpp:1948
PointType::NumberType NumberType
Definition monotonechain.hpp:148
constexpr EdgeIterator edgesBegin() const
Returns an iterator to the first unoriented edge.
Definition monotonechain.hpp:653
constexpr std::optional< std::size_t > isBelow(const OtherPoint &point) const
Tests whether the chain passes weakly below a point.
Definition atxy.hpp:462
EPoint PointType
Definition monotonechain.hpp:147
constexpr auto distanceL1(const OtherTriangle &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1225
constexpr bool operator==(const MonotoneChain< PointType_, TLabel, OtherStorage > &other) const
Checks equality of two chains.
Definition monotonechain.hpp:374
constexpr auto squaredDistance(const OtherSegment &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1486
constexpr bool interiorContains(const OtherLine &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1392
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherConvex &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2680
constexpr bool interiorsIntersect(const OtherPoint &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1649
constexpr void scaleDownX(const OtherNumber scalar)
constexpr bool isSegment() const
Checks whether the chain covers exactly one segment of positive length.
Definition monotonechain.hpp:450
constexpr bool interiorsIntersect(const OtherLine &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1719
constexpr bool crosses(const OtherOrientedLine &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:831
constexpr bool contains(const OtherRegion &other) const
Tests whether this shape contains the other shape (A ⊇ B).
constexpr std::ptrdiff_t index(const PointType &point) const
Definition monotonechain.hpp:312
constexpr bool interiorsIntersect(const Shape< OtherPoint > &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1823
constexpr bool crosses(const EmptyShape< EmptyPoint > &) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition monotonechain.hpp:1622
constexpr auto distanceL1(const OtherConvex &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1234
constexpr bool contains(const OtherSet &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition monotonechain.hpp:1531
constexpr auto distanceLInf(const OtherLine &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1168
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherOrientedSegment &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2624
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1159
constexpr EmptyShape< EmptyPoint > intersection(const EmptyShape< EmptyPoint > &) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition monotonechain.hpp:1750
constexpr bool pointInsideInteriorContainedIn(const OtherShape &shape) const
Tests whether some point in this shape's relative interior lies in the strict interior of shape.
Definition measures.hpp:1296
BoundaryIterator< false > EdgeIterator
Definition monotonechain.hpp:163
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1822
constexpr void insert(const PointType &point)
Extends the chain to contain the given point as a vertex.
Definition monotonechain.hpp:694
constexpr bool interiorsIntersect(const OtherConvex &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1759
constexpr auto squaredDistance(const OtherOrientedLine &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1513
constexpr auto squaredDistance(const OtherPoint &point) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1477
constexpr std::size_t size() const
Returns the number of vertices in the chain.
Definition monotonechain.hpp:393
constexpr bool separates(const OtherPoint &) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition monotonechain.hpp:1374
constexpr auto minkowskiErosion(const OtherShape &other) const
constexpr bool interiorContains(const OtherPolyline &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1783
constexpr bool empty() const
Checks whether the chain has no vertex.
Definition monotonechain.hpp:400
constexpr OwningChain scaledUpY(const OtherNumber scalar) const
constexpr auto lengthLInf() const
Computes the Chebyshev (LInf) length of the chain.
Definition measures.hpp:1233
constexpr bool interiorContains(const OtherPoint &point) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1371
constexpr bool separates(const OtherTriangle &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3036
BoundaryIterator< true > OrientedEdgeIterator
Definition monotonechain.hpp:164
constexpr bool isPoint() const
Checks whether the chain covers exactly one point.
Definition monotonechain.hpp:422
constexpr bool boundaryContains(const OtherPolygon &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1081
constexpr auto distanceL1(const OtherChain &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1243
detail::floating_result_t< ResultNumber > squaredDistance(const Disk< DiskPointType, DiskLabel > &disk) const
Returns the squared Euclidean distance to a disk.
Definition distance.hpp:1576
constexpr void scaleDownY(const OtherNumber scalar)
constexpr auto distanceLInf(const OtherTriangle &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1213
constexpr bool contains(const OtherPolygon &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1931
constexpr bool interiorContains(const OtherRegion &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
constexpr bool interiorsIntersect(const OtherShape &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition monotonechain.hpp:1364
constexpr auto squaredDistance(const OtherTriangle &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1549
constexpr bool intersects(const OtherConvex &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1498
constexpr bool intersects(const Shape< OtherPoint > &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1532
constexpr auto verticesView() const
Returns a lazy view over the vertices, translating each on the fly instead of allocating a vector.
Definition monotonechain.hpp:625
constexpr bool contains(const Shape< OtherPoint > &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1980
constexpr auto distanceL1(const OtherOrientedLine &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1189
constexpr auto distanceLInf(const OtherSegment &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1150
constexpr auto intersection(const OtherShape &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition monotonechain.hpp:1720
constexpr MonotoneChain & operator-=(const OtherPoint &translation)
Translates the chain by the negation of the given point.
Definition monotonechain.hpp:2356
constexpr bool crosses(const OtherLine &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:825
constexpr bool interiorContains(const OtherHalfplane &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1410
constexpr bool isDegenerate() const
Checks if the chain is degenerate (fewer than two vertices, so it has no edge).
Definition monotonechain.hpp:408
constexpr OrientedEdgeIterator orientedEdgesEnd() const
Returns an iterator past the last oriented edge.
Definition monotonechain.hpp:677
constexpr auto distanceLInf(const OtherRectangle &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1204
constexpr bool boundaryContains(const OtherRegion &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1762
constexpr auto distanceL1(const OtherHalfplane &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1207
constexpr bool interiorContains(const OtherChain &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1428
constexpr OwningChain scaledDownX(const OtherNumber scalar) const
constexpr MonotoneChain(const MonotoneChain< OtherPointType, OtherLabelType, OtherStorage > &other)
Converts a chain with compatible vertex type.
Definition monotonechain.hpp:259
constexpr std::vector< PointType > vertices() const
Returns the vertices of the chain (translation applied).
Definition monotonechain.hpp:569
constexpr bool crosses(const OtherRectangle &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:849
constexpr MonotoneChain & operator+=(const OtherPoint &translation)
Translates the chain by the given point.
Definition monotonechain.hpp:2338
constexpr auto cend() const
Returns a constant iterator past the last vertex.
Definition monotonechain.hpp:345
constexpr bool crosses(const OtherTriangle &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:859
constexpr auto operator<=>(const MonotoneChain< PointType_, TLabel, OtherStorage > &other) const
Compares two chains by their canonical vertex sequences.
Definition monotonechain.hpp:357
constexpr const Rectangle< PointType > & bbox() const
Computes the bounding box of the chain.
Definition bounding.hpp:495
constexpr bool boundaryContains(const OtherChain &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1093
constexpr bool intersects(const OtherRectangle &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1454
constexpr bool boundaryContains(const OtherSegment &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1039
auto minkowskiSum(const OtherShape &other) const
Returns the regularized Minkowski sum of the two shapes (A ⊕ B).
Definition monotonechain.hpp:2328
constexpr bool interiorContains(const OtherOrientedSegment &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1386
constexpr std::vector< Segment< PointType > > edges() const
Returns the edges of the chain.
Definition monotonechain.hpp:595
constexpr OwningChain scaledDownY(const OtherNumber scalar) const
constexpr bool intersects(const OtherChain &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1542
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherLine &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2632
constexpr bool contains(const OtherRegion &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2874
constexpr Point< ResultNumber > pointInside() const
Returns a point inside the chain.
Definition measures.hpp:1243
constexpr bool interiorContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1191
constexpr bool crosses(const Shape< OtherPoint > &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:883
constexpr bool intersects(const EmptyShape< EmptyPoint > &) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition monotonechain.hpp:1269
constexpr auto closestSegments(const OtherShape &other) const
Returns the pair of elements realizing the distance, nothing when the shapes meet.
Definition closest.hpp:384
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1153
constexpr bool intersects(const OtherDisk &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1515
constexpr MonotoneChain()=default
Creates a chain with no vertex.
constexpr std::optional< std::size_t > isAbove(const OtherPoint &point) const
Tests whether the chain passes weakly above a point.
Definition atxy.hpp:489
constexpr auto squaredDistance(const OtherConvex &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1558
constexpr std::optional< ResultNumber > yAtX(const OtherNumber &x) const
Evaluates the y-coordinate of the chain at a given x-coordinate.
Definition atxy.hpp:378
constexpr bool interiorsIntersect(const EmptyShape< EmptyPoint > &) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition monotonechain.hpp:1353
constexpr bool interiorContains(const OtherDisk &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1182
constexpr bool samePointSet(const OtherShape &other) const
Tests whether another shape defines exactly the same point set.
Definition samepointset.hpp:2007
constexpr auto squaredDistance(const OtherRay &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1522
constexpr void insert(Range &&points)
Extends the chain to contain all the given points as vertices.
Definition monotonechain.hpp:720
constexpr bool crosses(const OtherConvex &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:871
constexpr bool interiorsIntersect(const OtherOrientedSegment &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1685
constexpr void rotate90(int k=1)
Rotates the chain by 90k degrees around the origin in place.
Definition transformations.hpp:1898
constexpr bool interiorsIntersect(const OtherDisk &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1765
constexpr bool intersects(const OtherRay &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1420
constexpr bool interiorContains(const OtherRay &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1404
constexpr auto distanceL1(const OtherLine &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1180
constexpr auto distanceL1(const OtherRay &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1198
constexpr MonotoneChain(Range &&points, bool=true)
Creates a non-owning chain viewing an external contiguous range of vertices (view instantiations only...
Definition monotonechain.hpp:213
std::conditional_t< Oriented, OrientedSegment< PointType >, Segment< PointType > > BoundaryType
Definition monotonechain.hpp:158
constexpr bool separates(const OtherConvex &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3057
constexpr bool contains(const OtherSegment &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1831
constexpr bool boundaryContains(const OtherHalfplane &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1060
constexpr std::optional< std::size_t > isStrictlyBelow(const OtherPoint &point) const
Tests whether the whole chain lies strictly below a point at its x.
Definition atxy.hpp:398
bool separates(const OtherRegion &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:5741
constexpr bool crosses(const OtherChain &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:877
constexpr bool intersects(const OtherHalfplane &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1437
constexpr bool separates(const OtherLine &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:2988
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherTriangle &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2672
constexpr auto squaredDistance(const OtherHalfplane &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1531
constexpr bool contains(const OtherHalfplane &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1881
constexpr bool interiorsIntersect(const OtherTriangle &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1753
constexpr bool contains(const OtherChain &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1961
constexpr bool interiorContains(const OtherPolygon &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1176
constexpr bool separates(const OtherPolyline &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:4018
constexpr bool interiorContains(const OtherConvex &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1170
constexpr auto distanceLInf(const OtherHalfplane &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1195
constexpr OwningChain rotated90(int k=1) const
Returns the chain rotated by 90k degrees around the origin.
Definition transformations.hpp:1888
constexpr bool interiorsIntersect(const OtherOrientedLine &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1725
constexpr bool intersects(const OtherTriangle &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1481
constexpr bool boundaryContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1100
constexpr bool contains(const OtherRay &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1875
constexpr std::optional< BoundaryType< false > > getIfSegment() const
Returns the segment the chain collapses to, if it does.
Definition monotonechain.hpp:461
constexpr auto end() const
Returns a constant iterator past the last vertex.
Definition monotonechain.hpp:338
constexpr bool crosses(const OtherPoint &) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition monotonechain.hpp:1584
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherHalfplane &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2656
constexpr EdgeIterator edgesEnd() const
Returns an iterator past the last unoriented edge.
Definition monotonechain.hpp:661
constexpr bool boundaryContains(const OtherTriangle &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1069
constexpr auto squaredDistance(const OtherLine &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1504
constexpr bool boundaryContains(const OtherLine &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1051
constexpr bool interiorsIntersect(const OtherRectangle &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1743
constexpr A & label() const
Returns the chain label.
Definition monotonechain.hpp:272
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherRectangle &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2664
constexpr std::optional< Point< ResultNumber, typename PointType::LabelType > > intersection(const OtherPoint &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition intersection.hpp:2566
constexpr std::vector< OrientedSegment< PointType > > orientedEdges() const
Returns the oriented edges of the chain, each directed from the lexicographically smaller to the larg...
Definition monotonechain.hpp:608
constexpr bool interiorContains(const OtherSet &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition monotonechain.hpp:1553
constexpr auto distanceL1(const OtherOrientedSegment &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1171
constexpr auto squaredDistance(const OtherChain &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1567
constexpr const PointType operator[](std::size_t index) const
Accesses a vertex by index (in lexicographic order).
Definition monotonechain.hpp:281
constexpr bool isStrictlyMonotone() const
Tests whether the chain is strictly x-monotone.
Definition monotonechain.hpp:493
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherSegment &other) const
Returns the intersection with a one-dimensional or convex shape (A ∩ B), a sequence of points and seg...
Definition intersection.hpp:2616
constexpr bool interiorContains(const OtherRegion &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:2170
constexpr auto begin() const
Returns a constant iterator to the first vertex.
Definition monotonechain.hpp:324
constexpr MonotoneChain(std::initializer_list< NumberType > coords, bool trusted=false)
Creates a chain from a flat list of coordinates.
Definition monotonechain.hpp:230
constexpr bool contains(const OtherOrientedSegment &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1857
constexpr PointType get(std::ptrdiff_t index) const
Accesses a vertex by index modulo the vertex count.
Definition monotonechain.hpp:297
constexpr bool separates(const OtherChain &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3083
std::vector< Point< ResultNumber, typename PointType::LabelType > > latticePoints() const
Returns the integer points the chain contains.
Definition lattice.hpp:523
constexpr bool crosses(const OtherShape &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition monotonechain.hpp:1631
constexpr bool intersects(const OtherOrientedLine &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1403
constexpr Convex< PointType > convexHull() const
Returns the convex hull of the chain's vertices.
Definition monotonechain.hpp:520
constexpr bool crosses(const OtherHalfplane &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:843
constexpr bool boundaryContains(const OtherRegion &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
constexpr std::vector< std::variant< Point< ResultNumber, typename PointType::LabelType >, Segment< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherChain &other) const
Returns the intersection of the two chains (A ∩ B), a sequence of points and segments sorted by lexic...
Definition intersection.hpp:2435
constexpr bool crosses(const OtherSegment &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:813
constexpr bool boundaryContains(const OtherSet &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1542
constexpr std::optional< PointType > getIfPoint() const
Returns the point the chain collapses to, if it does.
Definition monotonechain.hpp:433
constexpr bool interiorsIntersect(const OtherSegment &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1656
constexpr bool contains(const OtherConvex &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1916
constexpr bool contains(const OtherOrientedLine &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1869
constexpr bool crosses(const OtherRay &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:837
ApproximateNumber length() const
Computes the Euclidean length of the chain (the sum of its edge lengths).
Definition measures.hpp:1215
constexpr bool interiorContains(const OtherSegment &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1377
constexpr bool boundaryContains(const OtherOrientedLine &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1054
constexpr void scaleUpY(const OtherNumber scalar)
constexpr auto minkowskiSum(const OtherShape &other) const
constexpr auto cbegin() const
Returns a constant iterator to the first vertex.
Definition monotonechain.hpp:331
constexpr auto squaredDistance(const OtherOrientedSegment &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:1495
constexpr bool isUndefined() const
Checks whether the chain is degenerate without covering a point or a segment.
Definition monotonechain.hpp:478
constexpr auto distanceL1(const OtherSegment &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1162
constexpr bool contains(const OtherDisk &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1955
constexpr bool boundaryContains(const OtherDisk &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition monotonechain.hpp:1087
constexpr bool separates(const OtherRectangle &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3020
constexpr OwningChain scaledUpX(const OtherNumber scalar) const
constexpr bool interiorsIntersect(const OtherRay &other) const
Tests whether the interiors of the shapes intersect (A° ∩ B° ≠ ∅).
Definition interiorsintersect.hpp:1731
constexpr auto lengthL1() const
Computes the Manhattan (L1) length of the chain.
Definition measures.hpp:1224
constexpr bool crosses(const OtherOrientedSegment &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:819
constexpr auto closestPoints(const OtherShape &other) const
Returns the pair of points realizing the distance, nothing when the shapes meet.
Definition closest.hpp:391
constexpr bool boundaryContains(const Shape< OtherPoint > &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1168
Sentinel type used when a point carries no extra label.
Definition point.hpp:31
Two-dimensional point with optional label payload.
Definition point.hpp:129
ERational NumberType
Definition point.hpp:131
Set of closed regions with pairwise disjoint interiors.
Definition polygonset.hpp:165
Closed simple polygon stored by its vertices.
Definition polygon.hpp:59
Open polygonal chain stored in traversal order; may self-intersect.
Definition polyline.hpp:69
Axis-aligned rectangle stored by minimum and maximum corners.
Definition rectangle.hpp:75
Unoriented closed segment between two endpoints plus optional segment label.
Definition segment.hpp:58
Runtime variant wrapper over the supported primitive shapes.
Definition shape.hpp:160