Pangolin
Header-only C++20 plane computational geometry library
Loading...
Searching...
No Matches
orientedline.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "shape/line.hpp"
4
12
13#include <array>
14#include <cassert>
15#include <cmath>
16#include <concepts>
17#include <cstddef>
18#include <functional>
19#include <optional>
20#include <ostream>
21#include <type_traits>
22#include <utility>
23#include <variant>
24
25
26
27namespace pgl {
28
29template <class PointType = Point<>, class Label>
30struct OrientedLine;
31
33
34template <class PointType>
36
37template <class PointType, class A>
39
40template <class Number>
41OrientedLine(Number, Number, Number, Number) -> OrientedLine<Point<Number>, NoLabel>;
42
52template <class PointType_, class TLabel>
54 using PointType = PointType_;
55 using NumberType = PointType::NumberType;
56 using LabelType = TLabel;
57 using CoordinateType = detail::promoted_number_t<NumberType>;
58
59 static_assert(detail::is_point_v<PointType>, "OrientedLine requires pgl::Point defining points");
60
64 constexpr OrientedLine() = default;
65
75 : points_{std::move(source), std::move(target)} {}
76
86 : OrientedLine(PointType(x1, y1), PointType(x2, y2)) {}
87
95 template <class A>
96 requires(detail::has_label_v<LabelType> && std::constructible_from<LabelType, A&&>)
98 : points_{std::move(source), std::move(target)}, label_(std::forward<A>(label)) {}
99
101 template <class A>
102 requires(detail::has_label_v<LabelType> && std::constructible_from<LabelType, A&&>)
104 : OrientedLine(PointType(x1, y1), PointType(x2, y2), std::forward<A>(label)) {}
105
112 template<PointConcept OtherPointType, class OtherLabelType>
113 requires(std::constructible_from<PointType, const OtherPointType&>)
115 : OrientedLine(PointType(other.source()), PointType(other.target())) {
116 label_ = detail::copyLabel<LabelType>(other);
117 }
118
120 template<PointConcept OtherPointType, class OtherLabelType>
121 requires(std::constructible_from<PointType, const OtherPointType&>)
123 points_[0] = PointType(other.source());
124 points_[1] = PointType(other.target());
125 label_ = detail::copyLabel<LabelType>(other);
126 return *this;
127 }
128
135 constexpr const PointType& operator[](std::size_t index) const {
136 assert(index < size());
137 return points_[index];
138 }
139
140 constexpr PointType& operator[](std::size_t index) {
141 assert(index < size());
142 return points_[index];
143 }
144
148 static constexpr std::size_t size() {
149 return 2;
150 }
151
156 constexpr const PointType& get(std::ptrdiff_t index) const {
157 const std::ptrdiff_t n = static_cast<std::ptrdiff_t>(size());
158 return (*this)[static_cast<std::size_t>(((index % n) + n) % n)];
159 }
160 constexpr PointType& get(std::ptrdiff_t index) {
161 const std::ptrdiff_t n = static_cast<std::ptrdiff_t>(size());
162 return (*this)[static_cast<std::size_t>(((index % n) + n) % n)];
163 }
164
169 constexpr std::ptrdiff_t index(const PointType& point) const {
170 for (std::ptrdiff_t i = 0; i < static_cast<std::ptrdiff_t>(size()); ++i) {
171 if ((*this)[static_cast<std::size_t>(i)] == point) {
172 return i;
173 }
174 }
175 return -1;
176 }
177
183 constexpr const PointType& source() const {
184 return points_[0];
185 }
186 constexpr PointType& source() {
187 return points_[0];
188 }
189
195 constexpr const PointType& target() const {
196 return points_[1];
197 }
198 constexpr PointType& target() {
199 return points_[1];
200 }
201
207 constexpr const PointType& min() const {
208 return target() < source() ? target() : source();
209 }
210
216 constexpr const PointType& max() const {
217 return source() < target() ? target() : source();
218 }
219
225 constexpr OrientedLine opposite() const {
226 return OrientedLine(target(), source());
227 }
228
234 constexpr auto begin() const {
235 return points_.cbegin();
236 }
237 constexpr auto begin() {
238 return points_.begin();
239 }
240
246 constexpr auto cbegin() const {
247 return points_.cbegin();
248 }
249
255 constexpr auto end() const {
256 return points_.cend();
257 }
258 constexpr auto end() {
259 return points_.end();
260 }
261
267 constexpr auto cend() const {
268 return points_.cend();
269 }
270
280 [[nodiscard]] constexpr bool operator==(const OrientedLine& other) const;
281
283 template<AnyShapeConcept OtherShape>
284 [[nodiscard]] constexpr bool samePointSet(const OtherShape& other) const;
285
293 [[nodiscard]] constexpr auto operator<=>(const OrientedLine& other) const;
294
303 template <class A = LabelType>
304 requires(detail::has_label_v<A>)
305 constexpr A& label() const {
306 return label_;
307 }
308
314 [[nodiscard]] constexpr explicit operator Line<PointType>() const;
315
321 [[nodiscard]] constexpr Line<PointType> asLine() const {
322 return static_cast<Line<PointType>>(*this);
323 }
324
366 template <class ResultNumber = rational_int_t<NumberType>>
368 && (detail::extended_integral<ResultNumber> || std::same_as<ResultNumber, BigInt>))
369 // Spelled with the raw template parameters, not the PointType/LabelType
370 // member aliases, and matched token for token by the out-of-class
371 // definition in transformations.hpp: MSVC matches a definition whose return
372 // type reaches through a parameter for a nested type by spelling rather
373 // than by parameter position, and rejects any other name with C2244.
374 [[nodiscard]] std::optional<OrientedLine<Point<ResultNumber, typename PointType_::LabelType>, TLabel>>
376
387 template<PointConcept OtherPoint>
388 [[nodiscard]] constexpr OrientedSegment<PointType> asOrientedSegmentFor(const Rectangle<OtherPoint> &rect) const {
389 if (!rect.intersects(*this)) {
391 }
392
393 const NumberType minX = rect.min().x();
394 const NumberType minY = rect.min().y();
395 const NumberType maxX = rect.max().x();
396 const NumberType maxY = rect.max().y();
397
398 if (isHorizontal()) {
399 if (source().x() < target().x()) {
400 return OrientedSegment<PointType>(PointType(minX - 1, source().y()), PointType(maxX + 1, target().y()));
401 }
402 return OrientedSegment<PointType>(PointType(maxX + 1, source().y()), PointType(minX - 1, target().y()));
403 }
404 if (isVertical()) {
405 if (source().y() < target().y()) {
406 return OrientedSegment<PointType>(PointType(source().x(), minY - 1), PointType(target().x(), maxY + 1));
407 }
408 return OrientedSegment<PointType>(PointType(source().x(), maxY + 1), PointType(target().x(), minY - 1));
409 }
410
411 // The supporting line is neither vertical nor horizontal, so v = target - source
412 // has nonzero components and meets the rectangle either at a single corner or in
413 // a chord crossing two edges. P(t) = source + t * v parametrizes the line.
414 const NumberType sx = source().x();
415 const NumberType sy = source().y();
416 const NumberType dx = target().x() - sx; // v.x() != 0
417 const NumberType dy = target().y() - sy; // v.y() != 0
418
419 // Clip the line to the rectangle's two slabs in parameter space and round each
420 // end outward, so the endpoints land just outside the crossed edges while the
421 // segment still covers the whole chord. Outward rounding (floor for the entry
422 // parameter, ceil for the exit) is what makes this robust to integer division:
423 // truncation could otherwise leave an endpoint inside the rectangle. A line that
424 // only grazes a corner is the degenerate chord where the two slabs meet at a
425 // single parameter; the same clip yields a segment touching just that corner.
426 const auto floorDiv = [](NumberType n, NumberType d) -> NumberType {
427 if (d < NumberType(0)) { n = -n; d = -d; }
428 NumberType q = n / d;
429 if (n - q * d != NumberType(0) && n < NumberType(0)) { --q; }
430 return q;
431 };
432 const auto ceilDiv = [](NumberType n, NumberType d) -> NumberType {
433 if (d < NumberType(0)) { n = -n; d = -d; }
434 NumberType q = n / d;
435 if (n - q * d != NumberType(0) && n > NumberType(0)) { ++q; }
436 return q;
437 };
438
439 // Entry/exit parameters of each axis slab (entry <= exit within the slab).
440 const NumberType xEntry = (dx > NumberType(0)) ? (minX - sx) : (maxX - sx);
441 const NumberType xExit = (dx > NumberType(0)) ? (maxX - sx) : (minX - sx);
442 const NumberType yEntry = (dy > NumberType(0)) ? (minY - sy) : (maxY - sy);
443 const NumberType yExit = (dy > NumberType(0)) ? (maxY - sy) : (minY - sy);
444
445 // floor(t_enter) = max over slabs of floor(entry); ceil(t_exit) = min of ceil(exit).
446 const NumberType aX = floorDiv(xEntry, dx);
447 const NumberType aY = floorDiv(yEntry, dy);
448 const NumberType bX = ceilDiv(xExit, dx);
449 const NumberType bY = ceilDiv(yExit, dy);
450
451 NumberType a = aX > aY ? aX : aY;
452 NumberType b = bX < bY ? bX : bY;
453
454 // floor/ceil may land an endpoint exactly on a rectangle edge when the
455 // crossing parameter is integral. Stepping it one further out makes the
456 // parameter strictly past the entry/exit, hence strictly outside, so a single
457 // step always suffices and both endpoints end up strictly outside.
458 const auto onOrInside = [&](const NumberType& px, const NumberType& py) {
459 return px >= minX && px <= maxX && py >= minY && py <= maxY;
460 };
461 if (onOrInside(sx + a * dx, sy + a * dy)) { --a; }
462 if (onOrInside(sx + b * dx, sy + b * dy)) { ++b; }
463
465 PointType(sx + a * dx, sy + a * dy),
466 PointType(sx + b * dx, sy + b * dy));
467 }
468
475 [[nodiscard]] constexpr OrientedLine rotated90(int k = 1) const;
476
482 constexpr void rotate90(int k = 1);
483
485 template <class OtherNumber>
486 [[nodiscard]] constexpr OrientedLine scaledUpX(const OtherNumber scalar) const;
487
489 template <class OtherNumber>
490 constexpr void scaleUpX(const OtherNumber scalar);
491
493 template <class OtherNumber>
494 [[nodiscard]] constexpr OrientedLine scaledUpY(const OtherNumber scalar) const;
495
497 template <class OtherNumber>
498 constexpr void scaleUpY(const OtherNumber scalar);
499
501 template <class OtherNumber>
502 [[nodiscard]] constexpr OrientedLine scaledDownX(const OtherNumber scalar) const;
503
505 template <class OtherNumber>
506 constexpr void scaleDownX(const OtherNumber scalar);
507
509 template <class OtherNumber>
510 [[nodiscard]] constexpr OrientedLine scaledDownY(const OtherNumber scalar) const;
511
513 template <class OtherNumber>
514 constexpr void scaleDownY(const OtherNumber scalar);
515
524 template <class ResultNumber = NumberType>
525 [[nodiscard]] constexpr ResultNumber area() const;
526
534 [[nodiscard]] constexpr NumberType twiceArea() const;
535
541 [[nodiscard]] constexpr bool isDegenerate() const;
542
554 [[nodiscard]] constexpr bool isUndefined() const;
555
561 [[nodiscard]] constexpr bool isVertical() const;
562
568 [[nodiscard]] constexpr bool isHorizontal() const;
569
571 template<PointConcept OtherPoint>
572 [[nodiscard]] constexpr bool verticesContain(const OtherPoint& point) const;
573
575 template<PointConcept OtherPoint>
576 [[nodiscard]] constexpr bool boundaryContains(const OtherPoint& point) const;
577
578 // An oriented line has empty boundary, so it boundary-contains no non-point shape.
580 template<SegmentConcept OtherSegment>
581 [[nodiscard]] constexpr bool boundaryContains(const OtherSegment&) const { return false; }
583 template<OrientedSegmentConcept OtherOrientedSegment>
584 [[nodiscard]] constexpr bool boundaryContains(const OtherOrientedSegment&) const { return false; }
586 template<LineConcept OtherLine>
587 [[nodiscard]] constexpr bool boundaryContains(const OtherLine&) const { return false; }
589 template<OrientedLineConcept OtherOrientedLine>
590 [[nodiscard]] constexpr bool boundaryContains(const OtherOrientedLine&) const { return false; }
592 template<RayConcept OtherRay>
593 [[nodiscard]] constexpr bool boundaryContains(const OtherRay&) const { return false; }
595 template<HalfplaneConcept OtherHalfplane>
596 [[nodiscard]] constexpr bool boundaryContains(const OtherHalfplane&) const { return false; }
598 template<RectangleConcept OtherRectangle>
599 [[nodiscard]] constexpr bool boundaryContains(const OtherRectangle&) const { return false; }
601 template<TriangleConcept OtherTriangle>
602 [[nodiscard]] constexpr bool boundaryContains(const OtherTriangle&) const { return false; }
604 template<ConvexConcept OtherConvex>
605 [[nodiscard]] constexpr bool boundaryContains(const OtherConvex&) const { return false; }
607 template<PolygonConcept OtherPolygon>
608 [[nodiscard]] constexpr bool boundaryContains(const OtherPolygon&) const { return false; }
610 template<DiskConcept OtherDisk>
611 [[nodiscard]] constexpr bool boundaryContains(const OtherDisk&) const { return false; }
612
614 template<PointConcept OtherPoint>
615 [[nodiscard]] constexpr bool contains(const OtherPoint& point) const;
616
618 template<LineConcept OtherLine>
619 [[nodiscard]] constexpr bool contains(const OtherLine& other) const;
620
622 template<OrientedLineConcept OtherOrientedLine>
623 [[nodiscard]] constexpr bool contains(const OtherOrientedLine& other) const;
624
626 template<SegmentConcept OtherSegment>
627 [[nodiscard]] constexpr bool contains(const OtherSegment& other) const;
628
630 template<OrientedSegmentConcept OtherOrientedSegment>
631 [[nodiscard]] constexpr bool contains(const OtherOrientedSegment& other) const;
632
634 template<RayConcept OtherRay>
635 [[nodiscard]] constexpr bool contains(const OtherRay& other) const;
636
638 template<HalfplaneConcept OtherHalfplane>
639 [[nodiscard]] constexpr bool contains(const OtherHalfplane& other) const;
640
642 template<RectangleConcept OtherRectangle>
643 [[nodiscard]] constexpr bool contains(const OtherRectangle& other) const;
644
646 template<TriangleConcept OtherTriangle>
647 [[nodiscard]] constexpr bool contains(const OtherTriangle& other) const;
648
650 template<ConvexConcept OtherConvex>
651 [[nodiscard]] constexpr bool contains(const OtherConvex& other) const;
652
654 template<PolygonConcept OtherPolygon>
655 [[nodiscard]] constexpr bool contains(const OtherPolygon& other) const;
656
658 template<DiskConcept OtherDisk>
659 [[nodiscard]] constexpr bool contains(const OtherDisk& other) const;
660
662 [[nodiscard]] constexpr bool contains(const Shape<PointType>& other) const;
663
665 [[nodiscard]] constexpr bool boundaryContains(const Shape<PointType>& other) const;
666
667 // The empty set is a subset of every shape (contained in all of them) and
668 // disjoint from all of them, so containment is true while separation is
669 // false. These overloads let an EmptyShape flow through Shape's variant
670 // dispatch without special-casing.
672 template <class EmptyPoint>
673 [[nodiscard]] constexpr bool contains(const EmptyShape<EmptyPoint>&) const {
674 return true;
675 }
676
677 template <class EmptyPoint>
678 [[nodiscard]] constexpr bool boundaryContains(const EmptyShape<EmptyPoint>&) const {
679 return true;
680 }
681
682 template <class EmptyPoint>
683 [[nodiscard]] constexpr bool interiorContains(const EmptyShape<EmptyPoint>&) const {
684 return true;
685 }
686
687 template <class EmptyPoint>
688 [[nodiscard]] constexpr bool separates(const EmptyShape<EmptyPoint>&) const {
689 return false;
690 }
691
693 template<PointConcept OtherPoint>
694 [[nodiscard]] constexpr bool interiorContains(const OtherPoint& point) const;
695
697 template<LineConcept OtherLine>
698 [[nodiscard]] constexpr bool interiorContains(const OtherLine& other) const;
699
701 template<OrientedLineConcept OtherOrientedLine>
702 [[nodiscard]] constexpr bool interiorContains(const OtherOrientedLine& other) const;
703
705 template<SegmentConcept OtherSegment>
706 [[nodiscard]] constexpr bool interiorContains(const OtherSegment& other) const;
707
709 template<OrientedSegmentConcept OtherOrientedSegment>
710 [[nodiscard]] constexpr bool interiorContains(const OtherOrientedSegment& other) const;
711
713 template<RayConcept OtherRay>
714 [[nodiscard]] constexpr bool interiorContains(const OtherRay& other) const;
715
717 template<HalfplaneConcept OtherHalfplane>
718 [[nodiscard]] constexpr bool interiorContains(const OtherHalfplane& other) const;
719
721 template<RectangleConcept OtherRectangle>
722 [[nodiscard]] constexpr bool interiorContains(const OtherRectangle& other) const;
723
725 template<TriangleConcept OtherTriangle>
726 [[nodiscard]] constexpr bool interiorContains(const OtherTriangle& other) const;
727
729 template<PointConcept OtherPoint>
730 [[nodiscard]] constexpr bool collinear(const OtherPoint& point) const;
731
733 template<LineConcept OtherLine>
734 [[nodiscard]] constexpr bool collinear(const OtherLine& other) const;
735
737 template<OrientedLineConcept OtherOrientedLine>
738 [[nodiscard]] constexpr bool collinear(const OtherOrientedLine& other) const;
739
741 template<SegmentConcept OtherSegment>
742 [[nodiscard]] constexpr bool collinear(const OtherSegment& other) const;
743
745 template<OrientedSegmentConcept OtherOrientedSegment>
746 [[nodiscard]] constexpr bool collinear(const OtherOrientedSegment& other) const;
747
749 template<RayConcept OtherRay>
750 [[nodiscard]] constexpr bool collinear(const OtherRay& other) const;
751
763 template<PointConcept OtherPoint>
764 [[nodiscard]] constexpr std::partial_ordering orientation(const OtherPoint& point) const;
765
774 template <class ResultNumber = division_result_t<NumberType>>
775 [[nodiscard]] constexpr ResultNumber slope() const;
776
789 template <class ResultNumber = division_result_t<NumberType>, class OtherNumber>
790 [[nodiscard]] constexpr std::optional<ResultNumber> yAtX(const OtherNumber& x) const;
791
804 template <class ResultNumber = division_result_t<NumberType>, class OtherNumber>
805 [[nodiscard]] constexpr std::optional<ResultNumber> xAtY(const OtherNumber& y) const;
806
815 [[nodiscard]] constexpr Halfplane<PointType> halfplaneAbove() const;
816
825 [[nodiscard]] constexpr Halfplane<PointType> halfplaneBelow() const;
826
832 [[nodiscard]] constexpr Halfplane<PointType> rightHalfplane() const;
833
839 [[nodiscard]] constexpr Halfplane<PointType> leftHalfplane() const;
840
842 template<LineConcept OtherLine>
843 [[nodiscard]] constexpr bool parallel(const OtherLine& other) const;
844
846 template<OrientedLineConcept OtherOrientedLine>
847 [[nodiscard]] constexpr bool parallel(const OtherOrientedLine& other) const;
848
850 template<SegmentConcept OtherSegment>
851 [[nodiscard]] constexpr bool parallel(const OtherSegment& other) const;
852
854 template<OrientedSegmentConcept OtherOrientedSegment>
855 [[nodiscard]] constexpr bool parallel(const OtherOrientedSegment& other) const;
856
858 template<RayConcept OtherRay>
859 [[nodiscard]] constexpr bool parallel(const OtherRay& other) const;
860
862 template<PointConcept OtherPoint>
863 [[nodiscard]] constexpr bool intersects(const OtherPoint& other) const;
864
866 template<LineConcept OtherLine>
867 [[nodiscard]] constexpr bool intersects(const OtherLine& other) const;
868
870 template<OrientedLineConcept OtherOrientedLine>
871 [[nodiscard]] constexpr bool intersects(const OtherOrientedLine& other) const;
872
874 template<SegmentConcept OtherSegment>
875 [[nodiscard]] constexpr bool intersects(const OtherSegment& other) const;
876
878 template<OrientedSegmentConcept OtherOrientedSegment>
879 [[nodiscard]] constexpr bool intersects(const OtherOrientedSegment& other) const;
880
882 [[nodiscard]] constexpr bool intersects(const Shape<PointType>& other) const;
883
885 template<typename OtherShape>
886 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
887 [[nodiscard]] constexpr bool intersects(const OtherShape& other) const {
888 return other.intersects(*this);
889 }
890
892 template <class EmptyPoint>
893 [[nodiscard]] constexpr bool intersects(const EmptyShape<EmptyPoint>&) const {
894 return false;
895 }
896
898 template<PointConcept OtherPoint>
899 [[nodiscard]] constexpr bool interiorsIntersect(const OtherPoint& other) const;
900
902 template<LineConcept OtherLine>
903 [[nodiscard]] constexpr bool interiorsIntersect(const OtherLine& other) const;
904
906 template<OrientedLineConcept OtherOrientedLine>
907 [[nodiscard]] constexpr bool interiorsIntersect(const OtherOrientedLine& other) const;
908
910 template<SegmentConcept OtherSegment>
911 [[nodiscard]] constexpr bool interiorsIntersect(const OtherSegment& other) const;
912
914 template<OrientedSegmentConcept OtherOrientedSegment>
915 [[nodiscard]] constexpr bool interiorsIntersect(const OtherOrientedSegment& other) const;
916
918 template<typename OtherShape>
919 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
920 [[nodiscard]] constexpr bool interiorsIntersect(const OtherShape& other) const {
921 return other.interiorsIntersect(*this);
922 }
923
925 template <class EmptyPoint>
926 [[nodiscard]] constexpr bool interiorsIntersect(const EmptyShape<EmptyPoint>&) const {
927 return false;
928 }
929
931 [[nodiscard]] constexpr bool interiorsIntersect(const Shape<PointType>& other) const;
932
934 template<LineConcept OtherLine>
935 [[nodiscard]] constexpr bool crosses(const OtherLine& other) const;
936
938 template<OrientedLineConcept OtherOrientedLine>
939 [[nodiscard]] constexpr bool crosses(const OtherOrientedLine& other) const;
940
942 template<PointConcept OtherPoint>
943 [[nodiscard]] constexpr bool crosses(const OtherPoint& other) const;
944
946 template<SegmentConcept OtherSegment>
947 [[nodiscard]] constexpr bool crosses(const OtherSegment& other) const;
948
950 template<OrientedSegmentConcept OtherOrientedSegment>
951 [[nodiscard]] constexpr bool crosses(const OtherOrientedSegment& other) const;
952
954 template<typename OtherShape>
955 requires (!PointConcept<OtherShape> && detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
956 [[nodiscard]] constexpr bool crosses(const OtherShape& other) const {
957 return other.crosses(*this);
958 }
959
961 template <class EmptyPoint>
962 [[nodiscard]] constexpr bool crosses(const EmptyShape<EmptyPoint>&) const {
963 return false;
964 }
965
967 [[nodiscard]] constexpr bool crosses(const Shape<PointType>& other) const;
968
979 template<LineConcept OtherLine>
980 [[nodiscard]] constexpr std::partial_ordering
981 crossingOrder(const OtherLine& first, const OtherLine& second) const;
982
984 template<PointConcept OtherPoint>
985 [[nodiscard]] constexpr bool separates(const OtherPoint& other) const;
986
988 template<SegmentConcept OtherSegment>
989 [[nodiscard]] constexpr bool separates(const OtherSegment& other) const;
990
992 template<OrientedSegmentConcept OtherOrientedSegment>
993 [[nodiscard]] constexpr bool separates(const OtherOrientedSegment& other) const;
994
996 template<LineConcept OtherLine>
997 [[nodiscard]] constexpr bool separates(const OtherLine& other) const;
998
1000 template<OrientedLineConcept OtherOrientedLine>
1001 [[nodiscard]] constexpr bool separates(const OtherOrientedLine& other) const;
1002
1004 template<RayConcept OtherRay>
1005 [[nodiscard]] constexpr bool separates(const OtherRay& other) const;
1006
1008 template<RectangleConcept OtherRectangle>
1009 [[nodiscard]] constexpr bool separates(const OtherRectangle& other) const;
1010
1012 template<TriangleConcept OtherTriangle>
1013 [[nodiscard]] constexpr bool separates(const OtherTriangle& other) const;
1014
1016 template<HalfplaneConcept OtherHalfplane>
1017 [[nodiscard]] constexpr bool separates(const OtherHalfplane& other) const;
1018
1020 template<ConvexConcept OtherConvex>
1021 [[nodiscard]] constexpr bool separates(const OtherConvex& other) const;
1022
1024 template<DiskConcept OtherDisk>
1025 [[nodiscard]] constexpr bool separates(const OtherDisk& other) const;
1026
1028 template<PolygonConcept OtherPolygon>
1029 [[nodiscard]] constexpr bool separates(const OtherPolygon& other) const;
1030
1032 template<MonotoneChainConcept OtherChain>
1033 [[nodiscard]] constexpr bool contains(const OtherChain& other) const;
1034
1036 template<MonotoneChainConcept OtherChain>
1037 [[nodiscard]] constexpr bool boundaryContains(const OtherChain&) const { return false; }
1038
1040 template<MonotoneChainConcept OtherChain>
1041 [[nodiscard]] constexpr bool interiorContains(const OtherChain& other) const;
1042
1044 template<MonotoneChainConcept OtherChain>
1045 [[nodiscard]] constexpr bool separates(const OtherChain& other) const;
1046
1048 template<PolylineConcept OtherPolyline>
1049 [[nodiscard]] constexpr bool contains(const OtherPolyline& other) const;
1050
1052 template<PolylineConcept OtherPolyline>
1053 [[nodiscard]] constexpr bool boundaryContains(const OtherPolyline&) const { return false; }
1054
1056 template<PolylineConcept OtherPolyline>
1057 [[nodiscard]] constexpr bool interiorContains(const OtherPolyline& other) const;
1058
1060 template<PolylineConcept OtherPolyline>
1061 [[nodiscard]] constexpr bool separates(const OtherPolyline& other) const;
1062
1064 template<HalfplaneIntersectionConcept OtherRegion>
1065 [[nodiscard]] constexpr bool contains(const OtherRegion& other) const;
1066
1068 template<HalfplaneIntersectionConcept OtherRegion>
1069 [[nodiscard]] constexpr bool boundaryContains(const OtherRegion& other) const;
1070
1072 template<HalfplaneIntersectionConcept OtherRegion>
1073 [[nodiscard]] constexpr bool interiorContains(const OtherRegion& other) const;
1074
1076 template<HalfplaneIntersectionConcept OtherRegion>
1077 [[nodiscard]] constexpr bool separates(const OtherRegion& other) const;
1078
1086 template<PolygonWithHolesConcept OtherRegion>
1087 [[nodiscard]] constexpr bool contains(const OtherRegion& other) const;
1088
1095 template<PolygonWithHolesConcept OtherRegion>
1096 [[nodiscard]] constexpr bool boundaryContains(const OtherRegion& other) const;
1097
1099 template<PolygonWithHolesConcept OtherRegion>
1100 [[nodiscard]] constexpr bool interiorContains(const OtherRegion& other) const;
1101
1109 template<PolygonWithHolesConcept OtherRegion>
1110 [[nodiscard]] bool separates(const OtherRegion& other) const;
1111
1112 // -------------------------------------------------------------------------
1113 // A set of regions
1114 //
1115 // It outranks every other shape, so the symmetric relations reach it through
1116 // the rank-based forwarders and only the asymmetric ones are answered here.
1117 // A set is the union of its components, so it is contained exactly when
1118 // every component is — no matter what this shape is.
1119
1121 template<PolygonSetConcept OtherSet>
1122 [[nodiscard]] constexpr bool contains(const OtherSet& other) const {
1123 for (const auto& component : other) {
1124 if (!contains(component)) {
1125 return false;
1126 }
1127 }
1128 return true;
1129 }
1130
1132 template<PolygonSetConcept OtherSet>
1133 [[nodiscard]] constexpr bool boundaryContains(const OtherSet& other) const {
1134 for (const auto& component : other) {
1135 if (!boundaryContains(component)) {
1136 return false;
1137 }
1138 }
1139 return true;
1140 }
1141
1143 template<PolygonSetConcept OtherSet>
1144 [[nodiscard]] constexpr bool interiorContains(const OtherSet& other) const {
1145 for (const auto& component : other) {
1146 if (!interiorContains(component)) {
1147 return false;
1148 }
1149 }
1150 return true;
1151 }
1152
1161 template<PolygonSetConcept OtherSet>
1162 [[nodiscard]] bool separates(const OtherSet& other) const;
1163
1165 [[nodiscard]] constexpr bool separates(const Shape<PointType>& other) const;
1166
1167 // --- not-yet-implemented predicate pairs (throw); see implementation ---
1169 template<DiskConcept OtherDisk>
1170 [[nodiscard]] constexpr bool interiorContains(const OtherDisk& other) const;
1171
1173 template<ConvexConcept OtherConvex>
1174 [[nodiscard]] constexpr bool interiorContains(const OtherConvex& other) const;
1175
1177 template<PolygonConcept OtherPolygon>
1178 [[nodiscard]] constexpr bool interiorContains(const OtherPolygon& other) const;
1179
1180
1182 template <class ResultNumber = NumberType, PointConcept OtherPoint>
1183 [[nodiscard]] constexpr std::optional<Point<ResultNumber, typename PointType::LabelType>>
1184 intersection(const OtherPoint& other) const;
1185
1187 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1188 [[nodiscard]] constexpr std::optional<std::variant<Point<ResultNumber, typename PointType::LabelType>, Line<Point<ResultNumber, typename PointType::LabelType>>>>
1189 intersection(const OtherLine& other) const;
1190
1192 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1193 [[nodiscard]] constexpr std::optional<std::variant<Point<ResultNumber, typename PointType::LabelType>, Line<Point<ResultNumber, typename PointType::LabelType>>>>
1194 intersection(const OtherOrientedLine& other) const;
1195
1197 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1198 [[nodiscard]] constexpr auto intersection(const OtherSegment& other) const;
1199
1201 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1202 [[nodiscard]] constexpr auto intersection(const OtherOrientedSegment& other) const;
1203
1205 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1206 requires (!PointConcept<OtherShape>
1207 && (detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
1208 && requires(const OtherShape& o, const OrientedLine& self) {
1209 o.template intersection<ResultNumber>(self);
1210 })
1211 [[nodiscard]] constexpr auto intersection(const OtherShape& other) const {
1212 return other.template intersection<ResultNumber>(*this);
1213 }
1214
1216 template <class ResultNumber = NumberType, class EmptyPoint>
1217 [[nodiscard]] constexpr EmptyShape<EmptyPoint> intersection(const EmptyShape<EmptyPoint>&) const {
1218 return {};
1219 }
1220
1232 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1233 [[nodiscard]] constexpr auto squaredDistance(const OtherPoint& point) const;
1234
1236 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1237 [[nodiscard]] constexpr auto squaredDistance(const OtherLine& other) const;
1238
1240 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1241 [[nodiscard]] constexpr auto squaredDistance(const OtherOrientedLine& other) const;
1242
1244 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1245 [[nodiscard]] constexpr auto squaredDistance(const OtherSegment& other) const;
1246
1248 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1249 [[nodiscard]] constexpr auto squaredDistance(const OtherOrientedSegment& other) const;
1250
1257 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1258 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
1259 && requires(const OtherShape& o, const OrientedLine& self) {
1260 o.template squaredDistance<ResultNumber>(self);
1261 })
1262 [[nodiscard]] constexpr auto squaredDistance(const OtherShape& other) const {
1263 return other.template squaredDistance<ResultNumber>(*this);
1264 }
1265
1273 template <class ResultNumber = double, class DiskPointType, class DiskLabel>
1274 [[nodiscard]] detail::floating_result_t<ResultNumber> squaredDistance(const Disk<DiskPointType, DiskLabel>& disk) const {
1275 return disk.template squaredDistance<ResultNumber>(*this);
1276 }
1277
1293 template <class ResultNumber = division_result_t<NumberType>, class OtherShape>
1294 requires detail::ClosestPointsPairConcept<OrientedLine<PointType_, TLabel>, OtherShape>
1295 [[nodiscard]] constexpr auto closestPoints(const OtherShape& other) const;
1296
1298 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1299 [[nodiscard]] constexpr auto distanceL1(const OtherPoint& point) const;
1300
1302 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1303 [[nodiscard]] constexpr auto distanceL1(const OtherLine& other) const;
1304
1306 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1307 [[nodiscard]] constexpr auto distanceL1(const OtherOrientedLine& other) const;
1308
1310 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1311 [[nodiscard]] constexpr auto distanceL1(const OtherSegment& other) const;
1312
1314 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1315 [[nodiscard]] constexpr auto distanceL1(const OtherOrientedSegment& other) const;
1316
1323 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1324 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
1325 && requires(const OtherShape& o, const OrientedLine& self) {
1326 o.template distanceL1<ResultNumber>(self);
1327 })
1328 [[nodiscard]] constexpr auto distanceL1(const OtherShape& other) const {
1329 return other.template distanceL1<ResultNumber>(*this);
1330 }
1331
1347 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1348 [[nodiscard]] constexpr auto intersection(const Shape<OtherPoint>& other) const {
1349 return other.template intersection<ResultNumber>(*this);
1350 }
1351
1360 template <class ResultNumber = double, PointConcept OtherPoint>
1361 [[nodiscard]] constexpr auto distanceL1(const Shape<OtherPoint>& other) const {
1362 return other.template distanceL1<ResultNumber>(*this);
1363 }
1364
1366 template <class ResultNumber = division_result_t<NumberType>, PointConcept OtherPoint>
1367 [[nodiscard]] constexpr auto distanceLInf(const OtherPoint& point) const;
1368
1370 template <class ResultNumber = division_result_t<NumberType>, LineConcept OtherLine>
1371 [[nodiscard]] constexpr auto distanceLInf(const OtherLine& other) const;
1372
1374 template <class ResultNumber = division_result_t<NumberType>, OrientedLineConcept OtherOrientedLine>
1375 [[nodiscard]] constexpr auto distanceLInf(const OtherOrientedLine& other) const;
1376
1378 template <class ResultNumber = division_result_t<NumberType>, SegmentConcept OtherSegment>
1379 [[nodiscard]] constexpr auto distanceLInf(const OtherSegment& other) const;
1380
1382 template <class ResultNumber = division_result_t<NumberType>, OrientedSegmentConcept OtherOrientedSegment>
1383 [[nodiscard]] constexpr auto distanceLInf(const OtherOrientedSegment& other) const;
1384
1391 template <class ResultNumber = division_result_t<NumberType>, typename OtherShape>
1392 requires ((detail::shapeRank<OtherShape> > detail::shapeRank<OrientedLine>)
1393 && requires(const OtherShape& o, const OrientedLine& self) {
1394 o.template distanceLInf<ResultNumber>(self);
1395 })
1396 [[nodiscard]] constexpr auto distanceLInf(const OtherShape& other) const {
1397 return other.template distanceLInf<ResultNumber>(*this);
1398 }
1399
1408 template <class ResultNumber = double, PointConcept OtherPoint>
1409 [[nodiscard]] constexpr auto distanceLInf(const Shape<OtherPoint>& other) const {
1410 return other.template distanceLInf<ResultNumber>(*this);
1411 }
1412
1429 template <class OtherShape>
1431 [[nodiscard]] constexpr auto minkowskiSum(const OtherShape& other) const;
1432
1456 template <class OtherShape>
1458 [[nodiscard]] constexpr auto minkowskiErosion(const OtherShape& other) const;
1459
1461 template<PointConcept OtherPoint>
1462 constexpr OrientedLine& operator+=(const OtherPoint& translation);
1463
1465 template<PointConcept OtherPoint>
1466 constexpr OrientedLine& operator-=(const OtherPoint& translation);
1467
1469 template <class Scalar>
1470 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
1471 constexpr OrientedLine& operator*=(const Scalar& scalar);
1472
1474 template <class Scalar>
1475 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
1476 constexpr OrientedLine& operator/=(const Scalar& scalar);
1477
1485 template <class ResultNumber = NumberType>
1486 [[nodiscard]] constexpr Point<ResultNumber> pointInside() const;
1487
1495 template <class OtherShape>
1496 [[nodiscard]] constexpr bool pointInsideInteriorContainedIn(const OtherShape& shape) const;
1497
1498 private:
1499 template <class OtherNumber>
1500 using promoted_number_t = std::common_type_t<CoordinateType, detail::promoted_number_t<OtherNumber>>;
1501
1502 std::array<PointType, 2> points_{};
1503 [[no_unique_address]] mutable LabelType label_{};
1504};
1505
1506template <class PointType, class LabelType, class TranslationNumber, class TranslationLabel>
1508
1509template <class PointType, class LabelType, class Scalar>
1510 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
1511constexpr auto operator*(const OrientedLine<PointType, LabelType>& line, const Scalar& scalar);
1512
1513template <class Scalar, class PointType, class LabelType>
1514 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
1515constexpr auto operator*(const Scalar& scalar, const OrientedLine<PointType, LabelType>& line);
1516
1517template <class PointType, class LabelType, class Scalar>
1518 requires(!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
1519constexpr auto operator/(const OrientedLine<PointType, LabelType>& line, const Scalar& scalar);
1520
1521template <class PointType, class LabelType>
1522std::ostream& operator<<(std::ostream& stream, const OrientedLine<PointType, LabelType>& line);
1523
1524} // namespace pgl
Shape pairs whose Minkowski sum Pangolin can represent.
Definition forward.hpp:476
Definition forward.hpp:306
Definition forward.hpp:324
Public declaration of pgl::Line.
Definition arrangement.hpp:67
@ y
Definition intervaltree.hpp:24
@ x
Definition intervaltree.hpp:24
constexpr bool is_Rational_v
Definition rational.hpp:37
Line() -> Line< Point<>, NoLabel >
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
OrientedSegment() -> OrientedSegment< Point<>, NoLabel >
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
OrientedLine() -> OrientedLine< Point<>, NoLabel >
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
Closed half-plane defined by an oriented boundary line.
Definition halfplane.hpp:51
Unoriented infinite line.
Definition line.hpp:52
Sentinel type used when a point carries no extra label.
Definition point.hpp:31
Directed infinite line with left/right side semantics plus optional line label.
Definition orientedline.hpp:53
constexpr bool contains(const OtherChain &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2032
constexpr bool interiorsIntersect(const EmptyShape< EmptyPoint > &) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition orientedline.hpp:926
constexpr bool crosses(const OtherLine &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:253
constexpr bool separates(const OtherPolygon &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:2003
constexpr bool contains(const OtherRegion &other) const
Tests whether this shape contains the other shape (A ⊇ B).
constexpr std::optional< std::variant< Point< ResultNumber, typename PointType::LabelType >, Line< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherOrientedLine &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition intersection.hpp:300
constexpr bool boundaryContains(const OtherPolyline &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:1053
constexpr bool collinear(const OtherLine &other) const
Returns whether the given line is collinear with the oriented line.
Definition predicates.hpp:622
constexpr bool separates(const OtherOrientedLine &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:926
constexpr auto squaredDistance(const OtherOrientedLine &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:279
constexpr bool interiorsIntersect(const OtherShape &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition orientedline.hpp:920
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:531
constexpr bool intersects(const EmptyShape< EmptyPoint > &) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition orientedline.hpp:893
constexpr auto intersection(const OtherShape &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition orientedline.hpp:1211
constexpr bool separates(const OtherOrientedSegment &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:914
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 orientedline.hpp:1409
constexpr bool interiorContains(const OtherPolyline &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1705
constexpr bool operator==(const OrientedLine &other) const
Tests equality of the represented oriented line.
Definition predicates.hpp:565
constexpr bool separates(const EmptyShape< EmptyPoint > &) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition orientedline.hpp:688
constexpr OrientedLine scaledUpY(const OtherNumber scalar) const
Returns the line with its y-coordinates multiplied by a factor.
constexpr bool boundaryContains(const OtherRegion &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1668
constexpr bool boundaryContains(const OtherPoint &point) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:241
constexpr bool interiorContains(const OtherRegion &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
constexpr bool separates(const OtherDisk &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:966
constexpr ResultNumber slope() const
Returns the slope of the line.
Definition measures.hpp:224
constexpr void scaleUpY(const OtherNumber scalar)
Multiplies the line's y-coordinates by a factor in place.
Definition transformations.hpp:685
constexpr bool boundaryContains(const Shape< PointType > &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition boundarycontains.hpp:1107
constexpr bool crosses(const Shape< PointType > &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:282
constexpr auto intersection(const OtherSegment &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition intersection.hpp:307
constexpr OrientedLine & operator-=(const OtherPoint &translation)
Translates the oriented line by the negation of the given point in place.
constexpr bool crosses(const OtherSegment &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:271
constexpr Point< ResultNumber > pointInside() const
Returns a point inside the oriented line.
Definition measures.hpp:232
constexpr Halfplane< PointType > leftHalfplane() const
Returns the half-plane on the left of the oriented line.
Definition predicates.hpp:702
constexpr auto end()
Definition orientedline.hpp:258
constexpr bool interiorsIntersect(const Shape< PointType > &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:410
constexpr NumberType twiceArea() const
Returns twice the area of the line.
Definition measures.hpp:218
constexpr bool interiorContains(const OtherSegment &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:413
constexpr bool interiorContains(const OtherSet &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition orientedline.hpp:1144
bool separates(const OtherRegion &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:5677
PointType PointType
Definition orientedline.hpp:54
constexpr auto distanceLInf(const OtherOrientedSegment &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:318
constexpr bool boundaryContains(const OtherTriangle &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:602
constexpr PointType & target()
Definition orientedline.hpp:198
constexpr bool separates(const OtherSegment &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:908
constexpr bool separates(const OtherLine &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:920
constexpr const PointType & operator[](std::size_t index) const
Returns defining point 0 for the source and 1 for the target.
Definition orientedline.hpp:135
constexpr const PointType & target() const
Definition orientedline.hpp:195
constexpr PointType & get(std::ptrdiff_t index)
Definition orientedline.hpp:160
constexpr bool interiorContains(const OtherPolygon &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1259
constexpr bool intersects(const OtherShape &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition orientedline.hpp:887
constexpr bool parallel(const OtherSegment &other) const
Returns whether the given segment is parallel to the oriented line.
Definition predicates.hpp:670
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:280
constexpr OrientedLine(const OrientedLine< OtherPointType, OtherLabelType > &other)
Converts an oriented line with a different point and/or label type.
Definition orientedline.hpp:114
constexpr Halfplane< PointType > rightHalfplane() const
Returns the half-plane on the right of the oriented line.
Definition predicates.hpp:697
constexpr auto operator<=>(const OrientedLine &other) const
Provides an ordering compatible with oriented-line equality.
Definition predicates.hpp:570
constexpr bool intersects(const Shape< PointType > &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:393
constexpr OrientedLine scaledDownX(const OtherNumber scalar) const
Returns the line with its x-coordinates divided by a divisor.
constexpr bool crosses(const OtherPoint &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:265
constexpr bool interiorContains(const OtherRay &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:425
constexpr bool collinear(const OtherPoint &point) const
Returns whether the given point is collinear with the oriented line.
Definition predicates.hpp:616
constexpr std::partial_ordering crossingOrder(const OtherLine &first, const OtherLine &second) const
Orders two lines by where they cross this oriented line.
Definition crosses.hpp:293
constexpr bool interiorContains(const OtherTriangle &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:448
constexpr bool contains(const OtherPolygon &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1734
constexpr auto squaredDistance(const OtherSegment &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:285
constexpr bool interiorsIntersect(const OtherOrientedLine &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:393
constexpr bool boundaryContains(const OtherHalfplane &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:596
constexpr void rotate90(int k=1)
Rotates the oriented line by 90k degrees around the origin in place.
Definition transformations.hpp:659
constexpr auto distanceLInf(const OtherLine &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:300
constexpr auto intersection(const OtherOrientedSegment &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition intersection.hpp:313
constexpr bool crosses(const OtherOrientedLine &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:259
constexpr bool boundaryContains(const OtherRectangle &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:599
constexpr bool interiorContains(const OtherOrientedLine &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:407
constexpr bool interiorContains(const OtherLine &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:401
constexpr bool contains(const OtherOrientedLine &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:543
constexpr bool contains(const OtherOrientedSegment &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:555
static constexpr std::size_t size()
Returns the number of defining points (always 2).
Definition orientedline.hpp:148
constexpr bool verticesContain(const OtherPoint &point) const
Returns whether the given point is one of the stored defining points.
Definition predicates.hpp:610
constexpr A & label() const
Definition orientedline.hpp:305
constexpr bool collinear(const OtherOrientedLine &other) const
Returns whether another oriented line is collinear with this oriented line.
Definition predicates.hpp:628
constexpr auto squaredDistance(const OtherPoint &point) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:267
constexpr bool boundaryContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:678
constexpr bool contains(const OtherLine &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:537
constexpr auto squaredDistance(const OtherShape &other) const
Returns the squared Euclidean distance to the given shape.
Definition orientedline.hpp:1262
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:238
constexpr bool contains(const OtherTriangle &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:584
constexpr auto begin() const
Returns an iterator to the source defining point.
Definition orientedline.hpp:234
constexpr auto minkowskiSum(const OtherShape &other) const
Returns the Minkowski sum of this shape and another (A ⊕ B).
Definition minkowski.hpp:797
constexpr std::optional< ResultNumber > xAtY(const OtherNumber &y) const
Returns the x-coordinate of the supporting line at a given y-coordinate, if defined.
Definition atxy.hpp:226
constexpr auto distanceLInf(const OtherSegment &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:312
constexpr bool contains(const OtherRay &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:561
constexpr bool separates(const OtherRectangle &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:938
constexpr bool parallel(const OtherRay &other) const
Returns whether the given ray is parallel to the oriented line.
Definition predicates.hpp:682
constexpr bool collinear(const OtherRay &other) const
Returns whether the given ray is collinear with the oriented line.
Definition predicates.hpp:646
constexpr OrientedLine(PointType source, PointType target)
Creates an oriented line from two defining points.
Definition orientedline.hpp:74
constexpr auto distanceL1(const OtherOrientedSegment &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:330
constexpr const PointType & max() const
Returns the lexicographically largest defining point.
Definition orientedline.hpp:216
std::optional< OrientedLine< Point< ResultNumber, typename PointType_::LabelType >, TLabel > > integralLine() const
Returns an equal oriented line whose defining points have integer coordinates, when one exists.
Definition transformations.hpp:840
detail::floating_result_t< ResultNumber > squaredDistance(const Disk< DiskPointType, DiskLabel > &disk) const
Returns the squared Euclidean distance to a disk.
Definition orientedline.hpp:1274
constexpr bool boundaryContains(const OtherOrientedLine &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:590
constexpr bool interiorContains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition orientedline.hpp:683
constexpr OrientedLine opposite() const
Returns the opposite orientation of the same geometric line.
Definition orientedline.hpp:225
constexpr bool interiorContains(const OtherHalfplane &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:431
constexpr auto distanceL1(const OtherShape &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition orientedline.hpp:1328
constexpr bool contains(const OtherPolyline &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2394
constexpr auto cend() const
Returns an iterator past the target defining point.
Definition orientedline.hpp:267
constexpr OrientedLine scaledDownY(const OtherNumber scalar) const
Returns the line with its y-coordinates divided by a divisor.
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 orientedline.hpp:1348
constexpr bool contains(const OtherDisk &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:604
constexpr bool interiorsIntersect(const OtherLine &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:387
constexpr ResultNumber area() const
Returns the area of the line.
Definition measures.hpp:213
constexpr OrientedLine & operator+=(const OtherPoint &translation)
Translates the oriented line by the given point in place.
constexpr bool boundaryContains(const OtherLine &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:587
bool separates(const OtherSet &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:5936
constexpr bool contains(const OtherHalfplane &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:567
constexpr bool separates(const OtherPoint &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:902
constexpr bool parallel(const OtherOrientedLine &other) const
Returns whether another oriented line is parallel to this oriented line.
Definition predicates.hpp:664
constexpr OrientedLine scaledUpX(const OtherNumber scalar) const
Returns the line with its x-coordinates multiplied by a factor.
constexpr OrientedLine()=default
Creates the degenerate oriented line (0,0)--(0,0).
constexpr bool contains(const OtherSet &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition orientedline.hpp:1122
constexpr bool boundaryContains(const OtherSegment &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:581
constexpr EmptyShape< EmptyPoint > intersection(const EmptyShape< EmptyPoint > &) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition orientedline.hpp:1217
constexpr bool separates(const OtherTriangle &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:948
constexpr std::partial_ordering orientation(const OtherPoint &point) const
Returns the orientation sign of a point with respect to the line.
Definition predicates.hpp:652
constexpr bool separates(const OtherHalfplane &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:954
constexpr std::optional< std::variant< Point< ResultNumber, typename PointType::LabelType >, Line< Point< ResultNumber, typename PointType::LabelType > > > > intersection(const OtherLine &other) const
Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
Definition intersection.hpp:290
constexpr bool intersects(const OtherOrientedSegment &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:388
constexpr bool isDegenerate() const
Returns whether the defining points coincide.
Definition predicates.hpp:583
constexpr bool samePointSet(const OtherShape &other) const
Tests whether another shape defines exactly the same point set.
Definition samepointset.hpp:1965
constexpr auto cbegin() const
Returns an iterator to the source defining point.
Definition orientedline.hpp:246
constexpr bool contains(const EmptyShape< EmptyPoint > &) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition orientedline.hpp:673
constexpr bool contains(const OtherConvex &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:590
constexpr bool separates(const OtherConvex &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:960
constexpr auto closestPoints(const OtherShape &other) const
Returns the pair of points realizing the distance, nothing when the shapes meet.
Definition closest.hpp:461
constexpr bool boundaryContains(const OtherDisk &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:611
constexpr std::ptrdiff_t index(const PointType &point) const
Definition orientedline.hpp:169
constexpr bool contains(const OtherSegment &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:549
constexpr bool contains(const Shape< PointType > &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:609
constexpr Line< PointType > asLine() const
Returns the line without orientation.
Definition orientedline.hpp:321
constexpr bool crosses(const OtherOrientedSegment &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition crosses.hpp:277
constexpr bool separates(const OtherRay &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:932
constexpr OrientedLine rotated90(int k=1) const
Returns the oriented line rotated by 90k degrees around the origin.
Definition transformations.hpp:654
constexpr PointType & operator[](std::size_t index)
Returns defining point 0 for the source and 1 for the target.
Definition orientedline.hpp:140
constexpr bool interiorContains(const OtherDisk &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1253
constexpr bool interiorsIntersect(const OtherOrientedSegment &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:405
constexpr bool interiorContains(const OtherChain &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:1482
constexpr bool interiorsIntersect(const OtherPoint &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:381
constexpr bool boundaryContains(const OtherChain &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:1037
constexpr void scaleDownX(const OtherNumber scalar)
Divides the line's x-coordinates by a divisor in place.
Definition transformations.hpp:698
constexpr void scaleDownY(const OtherNumber scalar)
Divides the line's y-coordinates by a divisor in place.
Definition transformations.hpp:711
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:294
constexpr auto distanceL1(const OtherOrientedLine &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:318
constexpr bool interiorContains(const OtherOrientedSegment &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:419
PointType::NumberType NumberType
Definition orientedline.hpp:55
TLabel LabelType
Definition orientedline.hpp:56
constexpr bool boundaryContains(const OtherPolygon &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:608
constexpr bool interiorContains(const OtherConvex &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:454
constexpr const PointType & source() const
Definition orientedline.hpp:183
constexpr bool interiorsIntersect(const OtherSegment &other) const
Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
Definition interiorsintersect.hpp:399
constexpr bool separates(const OtherPolyline &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3972
constexpr bool interiorContains(const OtherPoint &point) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:395
constexpr bool boundaryContains(const OtherConvex &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:605
constexpr auto distanceL1(const OtherLine &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:312
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:306
constexpr OrientedLine(NumberType x1, NumberType y1, NumberType x2, NumberType y2, A &&label)
Same as the four-coordinate constructor, and stores a label.
Definition orientedline.hpp:103
constexpr Halfplane< PointType > halfplaneBelow() const
Returns the half-plane geometrically below the supporting line.
Definition predicates.hpp:692
constexpr bool collinear(const OtherSegment &other) const
Returns whether the given segment is collinear with the oriented line.
Definition predicates.hpp:634
constexpr bool isUndefined() const
Returns whether the line is degenerate without collapsing to a point or to a segment.
Definition predicates.hpp:588
constexpr void scaleUpX(const OtherNumber scalar)
Multiplies the line's x-coordinates by a factor in place.
Definition transformations.hpp:672
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:364
constexpr std::optional< ResultNumber > yAtX(const OtherNumber &x) const
Returns the y-coordinate of the supporting line at a given x-coordinate, if defined.
Definition atxy.hpp:208
constexpr bool crosses(const EmptyShape< EmptyPoint > &) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition orientedline.hpp:962
constexpr bool boundaryContains(const OtherSet &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:1133
constexpr bool intersects(const OtherSegment &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:382
constexpr auto distanceLInf(const OtherShape &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition orientedline.hpp:1396
constexpr bool isVertical() const
Returns whether the line is vertical.
Definition predicates.hpp:593
constexpr bool contains(const OtherRegion &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:2765
constexpr const PointType & min() const
Returns the lexicographically smallest defining point.
Definition orientedline.hpp:207
constexpr OrientedLine(PointType source, PointType target, A &&label)
Creates an oriented line from two defining points and stores a label.
Definition orientedline.hpp:97
constexpr bool separates(const OtherRegion &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:4606
constexpr OrientedLine(NumberType x1, NumberType y1, NumberType x2, NumberType y2)
Creates an oriented line from four coordinates.
Definition orientedline.hpp:85
constexpr auto distanceL1(const OtherSegment &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:324
constexpr auto minkowskiErosion(const OtherShape &other) const
Returns the Minkowski erosion of this shape by another (A ⊖ B).
Definition minkowskierosion.hpp:630
constexpr bool boundaryContains(const OtherRay &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:593
constexpr bool separates(const OtherChain &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:3167
constexpr bool boundaryContains(const OtherRegion &other) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
constexpr bool parallel(const OtherOrientedSegment &other) const
Returns whether the given oriented segment is parallel to the oriented line.
Definition predicates.hpp:676
constexpr auto begin()
Definition orientedline.hpp:237
constexpr bool contains(const OtherRectangle &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:573
constexpr bool isHorizontal() const
Returns whether the line is horizontal.
Definition predicates.hpp:598
constexpr Halfplane< PointType > halfplaneAbove() const
Returns the half-plane geometrically above the supporting line.
Definition predicates.hpp:687
constexpr bool collinear(const OtherOrientedSegment &other) const
Returns whether the given oriented segment is collinear with the oriented line.
Definition predicates.hpp:640
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 orientedline.hpp:1361
constexpr auto end() const
Returns an iterator past the target defining point.
Definition orientedline.hpp:255
constexpr bool interiorContains(const OtherRectangle &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:437
detail::promoted_number_t< NumberType > CoordinateType
Definition orientedline.hpp:57
constexpr bool parallel(const OtherLine &other) const
Returns whether the given line is parallel to the oriented line.
Definition predicates.hpp:658
constexpr bool boundaryContains(const OtherOrientedSegment &) const
Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
Definition orientedline.hpp:584
constexpr bool crosses(const OtherShape &other) const
Tests whether the two shapes mutually separate each other (each disconnects the other).
Definition orientedline.hpp:956
constexpr PointType & source()
Definition orientedline.hpp:186
constexpr OrientedSegment< PointType > asOrientedSegmentFor(const Rectangle< OtherPoint > &rect) const
Returns the oriented segment that intersects r the same way as this oriented line.
Definition orientedline.hpp:388
constexpr auto squaredDistance(const OtherOrientedSegment &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:291
constexpr const PointType & get(std::ptrdiff_t index) const
Cyclic access: same as operator[] but index is taken modulo size(); negative indices wrap from the en...
Definition orientedline.hpp:156
constexpr bool separates(const Shape< PointType > &other) const
Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
Definition separates.hpp:971
constexpr bool intersects(const OtherOrientedLine &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:376
constexpr bool interiorContains(const OtherRegion &other) const
Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
Definition interiorcontains.hpp:2070
constexpr bool intersects(const OtherLine &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:370
constexpr auto distanceLInf(const OtherOrientedLine &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:306
constexpr auto squaredDistance(const OtherLine &other) const
Returns the squared Euclidean distance to the given shape.
Definition distance.hpp:273
Directed segment preserving source-to-target order plus optional segment label.
Definition orientedsegment.hpp:44
Two-dimensional point with optional label payload.
Definition point.hpp:129
Axis-aligned rectangle stored by minimum and maximum corners.
Definition rectangle.hpp:75
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:502
constexpr const PointType & min() const
Returns the minimum corner (min x, min y).
Definition rectangle.hpp:347
constexpr const PointType & max() const
Returns the maximum corner (max x, max y).
Definition rectangle.hpp:359
Runtime variant wrapper over the supported primitive shapes.
Definition shape.hpp:160