47template <
class ResultNumber>
50 const ResultNumber dx = b.x() - a.x();
51 const ResultNumber dy = b.y() - a.y();
52 const ResultNumber px = q.x() - a.x();
53 const ResultNumber py = q.y() - a.y();
55 if (dx == 0 && dy == 0) {
56 return pgl::detail::abs(px) + pgl::detail::abs(py);
59 bool haveBest =
false;
61 const auto consider = [&](
const ResultNumber& value) {
62 if (!haveBest || value < best) {
69 consider(pgl::detail::abs(px) + pgl::detail::abs(py));
72 consider(pgl::detail::abs(px - dx) + pgl::detail::abs(py - dy));
75 const ResultNumber cross = dx * py - dy * px;
76 const auto considerCrossing = [&](
const ResultNumber& n,
const ResultNumber& d) {
86 if (boundedLow && (d > 0 ? n < 0 : n > 0)) {
89 if (boundedHigh && n * d > d * d) {
92 consider(pgl::detail::abs(cross) / pgl::detail::abs(d));
94 considerCrossing(px, dx);
95 considerCrossing(py, dy);
112template <
class ResultNumber,
class Self,
class OtherShape>
113constexpr ResultNumber maxVertexDistanceL1(
const Self& self,
const OtherShape& other) {
114 const auto self_vertices = self.vertices();
115 const auto distanceToVertex = [&other](
const auto&
vertex) -> ResultNumber {
116 return other.template distanceL1<ResultNumber>(
vertex);
118 ResultNumber worst = distanceToVertex(self_vertices[0]);
119 for (std::size_t index = 1; index < self_vertices.size(); ++index) {
120 const ResultNumber current = distanceToVertex(self_vertices[index]);
121 if (worst < current) {
142template <
class Float =
double>
143Float diskPointDistanceL1(Float a, Float b, Float r) {
144 const auto h = [&](Float theta) {
145 return std::abs(a + r * std::cos(theta)) + std::abs(b + r * std::sin(theta));
148 constexpr int coarseSteps = 720;
150 Float bestValue = h(Float{0});
151 for (
int i = 1; i < coarseSteps; ++i) {
152 const Float theta = Float{2} * std::numbers::pi_v<Float> * i / coarseSteps;
153 const Float value = h(theta);
154 if (value < bestValue) {
160 const Float step = Float{2} * std::numbers::pi_v<Float> / coarseSteps;
161 Float lo = bestTheta - step;
162 Float hi = bestTheta + step;
163 constexpr Float invPhi = 0.6180339887498949;
164 Float c1 = hi - invPhi * (hi - lo);
165 Float c2 = lo + invPhi * (hi - lo);
168 for (
int i = 0; i < 100; ++i) {
173 c1 = hi - invPhi * (hi - lo);
179 c2 = lo + invPhi * (hi - lo);
184 return std::min({bestValue, hc1, hc2});
192template <
class Number,
class Label>
193template <
class ResultNumber, Po
intConcept OtherPo
int>
201template <
class Po
intType_,
class TLabel>
202template <
class ResultNumber, Po
intConcept OtherPo
int>
204 const OtherPoint& point)
const {
205 using Float = detail::floating_result_t<ResultNumber>;
209 const Float
a =
center<Float>().x() -
static_cast<Float
>(point.x());
210 const Float
b =
center<Float>().y() -
static_cast<Float
>(point.y());
217template <
class Po
intType,
class LabelType>
218template <
class ResultNumber, Po
intConcept OtherPo
int>
220 return detail::segmentLikeDistanceL1<ResultNumber>(
224template <
class Po
intType,
class LabelType>
225template <
class ResultNumber, SegmentConcept OtherSegment>
228 return ResultNumber{};
236 const auto best_from_this = this_min_to_other < this_max_to_other ? this_min_to_other : this_max_to_other;
237 const auto best_from_other = other_min_to_this < other_max_to_this ? other_min_to_this : other_max_to_this;
239 return best_from_this < best_from_other ? best_from_this : best_from_other;
245template <
class Po
intType,
class LabelType>
246template <
class ResultNumber, Po
intConcept OtherPo
int>
251template <
class Po
intType,
class LabelType>
252template <
class ResultNumber, SegmentConcept OtherSegment>
257template <
class Po
intType,
class LabelType>
258template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
267template <
class Po
intType,
class LabelType>
268template <
class ResultNumber, Po
intConcept OtherPo
int>
270 return detail::segmentLikeDistanceL1<ResultNumber>(
274template <
class Po
intType,
class LabelType>
275template <
class ResultNumber, LineConcept OtherLine>
278 return ResultNumber{};
283template <
class Po
intType,
class LabelType>
284template <
class ResultNumber, SegmentConcept OtherSegment>
287 return ResultNumber{};
292 return source_distance < target_distance ? source_distance : target_distance;
295template <
class Po
intType,
class LabelType>
296template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
304template <
class Po
intType,
class LabelType>
305template <
class ResultNumber, Po
intConcept OtherPo
int>
310template <
class Po
intType,
class LabelType>
311template <
class ResultNumber, LineConcept OtherLine>
316template <
class Po
intType,
class LabelType>
317template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
322template <
class Po
intType,
class LabelType>
323template <
class ResultNumber, SegmentConcept OtherSegment>
328template <
class Po
intType,
class LabelType>
329template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
337template <
class Po
intType,
class LabelType>
338template <
class ResultNumber, Po
intConcept OtherPo
int>
340 return detail::segmentLikeDistanceL1<ResultNumber>(
344template <
class Po
intType,
class LabelType>
345template <
class ResultNumber, LineConcept OtherLine>
348 return ResultNumber{};
353template <
class Po
intType,
class LabelType>
354template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
357 return ResultNumber{};
362template <
class Po
intType,
class LabelType>
363template <
class ResultNumber, SegmentConcept OtherSegment>
366 return ResultNumber{};
372 const auto best_from_segment = other_min_to_this < other_max_to_this ? other_min_to_this : other_max_to_this;
373 return source_to_other < best_from_segment ? source_to_other : best_from_segment;
376template <
class Po
intType,
class LabelType>
377template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
380 return ResultNumber{};
386 const auto best_from_segment = other_source_to_this < other_target_to_this ? other_source_to_this : other_target_to_this;
387 return source_to_other < best_from_segment ? source_to_other : best_from_segment;
390template <
class Po
intType,
class LabelType>
391template <
class ResultNumber, RayConcept OtherRay>
394 return ResultNumber{};
399 return this_source_to_other < other_source_to_this ? this_source_to_other : other_source_to_this;
405template <
class Po
intType,
class LabelType>
406template <
class ResultNumber, Po
intConcept OtherPo
int>
409 return ResultNumber{};
414template <
class Po
intType,
class LabelType>
415template <
class ResultNumber, SegmentConcept OtherSegment>
418 return ResultNumber{};
423template <
class Po
intType,
class LabelType>
424template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
427 return ResultNumber{};
432template <
class Po
intType,
class LabelType>
433template <
class ResultNumber, LineConcept OtherLine>
436 return ResultNumber{};
441template <
class Po
intType,
class LabelType>
442template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
445 return ResultNumber{};
450template <
class Po
intType,
class LabelType>
451template <
class ResultNumber, RayConcept OtherRay>
454 return ResultNumber{};
459template <
class Po
intType,
class LabelType>
460template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
463 return ResultNumber{};
471template <
class Po
intType,
class LabelType>
472template <
class ResultNumber, Po
intConcept OtherPo
int>
477 const ResultNumber dx =
static_cast<ResultNumber
>(axisDistance(
min().
x(),
max().
x(), point.x(), point.x()));
478 const ResultNumber dy =
static_cast<ResultNumber
>(axisDistance(
min().
y(),
max().
y(), point.y(), point.y()));
482template <
class Po
intType,
class LabelType>
483template <
class ResultNumber, LineConcept OtherLine>
489 return ResultNumber{};
492 const auto rectangle_vertices =
vertices();
494 for (std::size_t
index = 1;
index < rectangle_vertices.size(); ++
index) {
496 if (current_distance < best_distance) {
497 best_distance = current_distance;
501 return best_distance;
504template <
class Po
intType,
class LabelType>
505template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
513template <
class Po
intType,
class LabelType>
514template <
class ResultNumber, SegmentConcept OtherSegment>
520 return ResultNumber{};
525 if (other_max_distance < best_distance) {
526 best_distance = other_max_distance;
529 const auto rectangle_edges =
edges();
530 for (
const auto&
edge : rectangle_edges) {
532 if (current_distance < best_distance) {
533 best_distance = current_distance;
537 return best_distance;
540template <
class Po
intType,
class LabelType>
541template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
549template <
class Po
intType,
class LabelType>
550template <
class ResultNumber, RayConcept OtherRay>
556 return ResultNumber{};
560 const auto rectangle_edges =
edges();
561 for (
const auto&
edge : rectangle_edges) {
563 if (current_distance < best_distance) {
564 best_distance = current_distance;
568 return best_distance;
571template <
class Po
intType,
class LabelType>
572template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
578 return ResultNumber{};
583template <
class Po
intType,
class LabelType>
584template <
class ResultNumber, RectangleConcept OtherRectangle>
589 const ResultNumber dx =
static_cast<ResultNumber
>(axisDistance(
min().
x(),
max().
x(), other.min().x(), other.max().x()));
590 const ResultNumber dy =
static_cast<ResultNumber
>(axisDistance(
min().
y(),
max().
y(), other.min().y(), other.max().y()));
597template <
class Po
intType,
class LabelType>
598template <
class ResultNumber,
class OtherShape>
599constexpr ResultNumber Triangle<PointType, LabelType>::edgeMinDistanceL1(
const OtherShape& other)
const {
600 const auto triangle_edges = edges();
601 auto best = triangle_edges[0].template distanceL1<ResultNumber>(other);
602 for (std::size_t index = 1; index < triangle_edges.size(); ++index) {
603 const auto current = triangle_edges[index].template distanceL1<ResultNumber>(other);
604 if (current < best) {
611template <
class Po
intType,
class LabelType>
612template <
class ResultNumber,
class OtherShape>
613constexpr ResultNumber Triangle<PointType, LabelType>::vertexMinDistanceL1(
const OtherShape& other)
const {
614 const auto triangle_vertices = vertices();
615 auto best = other.template distanceL1<ResultNumber>(triangle_vertices[0]);
616 for (std::size_t index = 1; index < triangle_vertices.size(); ++index) {
617 const auto current = other.template distanceL1<ResultNumber>(triangle_vertices[index]);
618 if (current < best) {
625template <
class Po
intType,
class LabelType>
626template <
class ResultNumber, Po
intConcept OtherPo
int>
629 return ResultNumber{};
631 return this->
template edgeMinDistanceL1<ResultNumber>(point);
634template <
class Po
intType,
class LabelType>
635template <
class ResultNumber, SegmentConcept OtherSegment>
638 return ResultNumber{};
640 return this->
template edgeMinDistanceL1<ResultNumber>(other);
643template <
class Po
intType,
class LabelType>
644template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
647 return ResultNumber{};
649 return this->
template edgeMinDistanceL1<ResultNumber>(other);
652template <
class Po
intType,
class LabelType>
653template <
class ResultNumber, LineConcept OtherLine>
656 return ResultNumber{};
658 return this->
template vertexMinDistanceL1<ResultNumber>(other);
661template <
class Po
intType,
class LabelType>
662template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
665 return ResultNumber{};
667 return this->
template vertexMinDistanceL1<ResultNumber>(other);
670template <
class Po
intType,
class LabelType>
671template <
class ResultNumber, RayConcept OtherRay>
674 return ResultNumber{};
676 return this->
template edgeMinDistanceL1<ResultNumber>(other);
679template <
class Po
intType,
class LabelType>
680template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
683 return ResultNumber{};
688template <
class Po
intType,
class LabelType>
689template <
class ResultNumber, RectangleConcept OtherRectangle>
692 return ResultNumber{};
694 return this->
template edgeMinDistanceL1<ResultNumber>(other);
697template <
class Po
intType,
class LabelType>
698template <
class ResultNumber, TriangleConcept OtherTriangle>
701 return ResultNumber{};
703 return this->
template edgeMinDistanceL1<ResultNumber>(other);
713template <
class Po
intType_,
class LabelType>
714template <
class ResultNumber, Po
intConcept OtherPo
int>
717 return ResultNumber{};
719 auto edgeVector =
edges();
721 for (
auto& e : edgeVector) {
723 if (current < best) {
730template <
class Po
intType_,
class LabelType>
731template <
class ResultNumber, SegmentConcept OtherSegment>
734 return ResultNumber{};
736 auto edgeVector =
edges();
738 for (
auto& e : edgeVector) {
740 if (current < best) {
747template <
class Po
intType_,
class LabelType>
748template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
754template <
class Po
intType_,
class LabelType>
755template <
class ResultNumber, ConvexConcept OtherConvex>
758 return ResultNumber{};
761 const auto minOverEdges = [](
const auto& source,
const auto& target) {
762 const auto edgeVector = source.edges();
764 for (
const auto&
edge : edgeVector) {
766 if (current < best) {
773 if (
size() <= other.size()) {
774 return minOverEdges(*
this, other);
776 return minOverEdges(other, *
this);
779template <
class Po
intType_,
class LabelType>
780template <
class ResultNumber, TriangleConcept OtherTriangle>
785template <
class Po
intType_,
class LabelType>
786template <
class ResultNumber, RectangleConcept OtherRectangle>
791template <
class Po
intType_,
class LabelType>
792template <
class ResultNumber, LineConcept OtherLine>
795 return ResultNumber{};
798 for (std::ptrdiff_t i = 1; i < static_cast<std::ptrdiff_t>(
size()); ++i) {
800 if (current < best) {
807template <
class Po
intType_,
class LabelType>
808template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
813template <
class Po
intType_,
class LabelType>
814template <
class ResultNumber, RayConcept OtherRay>
817 return ResultNumber{};
819 auto edgeVector =
edges();
821 for (
const auto& e : edgeVector) {
823 if (current < best) {
830template <
class Po
intType_,
class LabelType>
831template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
834 return ResultNumber{};
842template <
class Po
intType_,
class TLabel>
843template <
class ResultNumber,
class OtherShape>
844constexpr ResultNumber Polygon<PointType_, TLabel>::edgeMinDistanceL1(
const OtherShape& other)
const {
845 const auto boundaryEdges = edges();
846 ResultNumber best = boundaryEdges[0].template distanceL1<ResultNumber>(other);
847 for (std::size_t index = 1; index < boundaryEdges.size(); ++index) {
848 const ResultNumber current = boundaryEdges[index].template distanceL1<ResultNumber>(other);
849 if (current < best) {
856template <
class Po
intType_,
class TLabel>
857template <
class ResultNumber, Po
intConcept OtherPo
int>
860 return ResultNumber{};
862 return this->
template edgeMinDistanceL1<ResultNumber>(point);
865template <
class Po
intType_,
class TLabel>
866template <
class ResultNumber, SegmentConcept OtherSegment>
869 return ResultNumber{};
871 return this->
template edgeMinDistanceL1<ResultNumber>(other);
874template <
class Po
intType_,
class TLabel>
875template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
878 return ResultNumber{};
880 return this->
template edgeMinDistanceL1<ResultNumber>(other);
883template <
class Po
intType_,
class TLabel>
884template <
class ResultNumber, LineConcept OtherLine>
887 return ResultNumber{};
889 return this->
template edgeMinDistanceL1<ResultNumber>(other);
892template <
class Po
intType_,
class TLabel>
893template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
896 return ResultNumber{};
898 return this->
template edgeMinDistanceL1<ResultNumber>(other);
901template <
class Po
intType_,
class TLabel>
902template <
class ResultNumber, RayConcept OtherRay>
905 return ResultNumber{};
907 return this->
template edgeMinDistanceL1<ResultNumber>(other);
910template <
class Po
intType_,
class TLabel>
911template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
914 return ResultNumber{};
916 return this->
template edgeMinDistanceL1<ResultNumber>(other);
919template <
class Po
intType_,
class TLabel>
920template <
class ResultNumber, RectangleConcept OtherRectangle>
923 return ResultNumber{};
925 return this->
template edgeMinDistanceL1<ResultNumber>(other);
928template <
class Po
intType_,
class TLabel>
929template <
class ResultNumber, TriangleConcept OtherTriangle>
932 return ResultNumber{};
934 return this->
template edgeMinDistanceL1<ResultNumber>(other);
937template <
class Po
intType_,
class TLabel>
938template <
class ResultNumber, ConvexConcept OtherConvex>
941 return ResultNumber{};
943 return this->
template edgeMinDistanceL1<ResultNumber>(other);
946template <
class Po
intType_,
class TLabel>
947template <
class ResultNumber, PolygonConcept OtherPolygon>
950 return ResultNumber{};
952 return this->
template edgeMinDistanceL1<ResultNumber>(other);
959template <
class Po
intType,
class LabelType>
960template <
class ResultNumber, SegmentConcept OtherSegment>
962 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
963 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
964 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
967template <
class Po
intType,
class LabelType>
968template <
class ResultNumber, Po
intConcept OtherPo
int>
970 return detail::maxVertexDistanceL1<ResultNumber>(*
this, point);
973template <
class Po
intType,
class LabelType>
974template <
class ResultNumber, SegmentConcept OtherSegment>
979template <
class Po
intType,
class LabelType>
980template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
986template <
class Po
intType,
class LabelType>
987template <
class ResultNumber, Po
intConcept OtherPo
int>
992template <
class Po
intType,
class LabelType>
993template <
class ResultNumber, RectangleConcept OtherRectangle>
998 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
999 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1000 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1003template <
class Po
intType,
class LabelType>
1004template <
class ResultNumber, Po
intConcept OtherPo
int>
1009 return detail::maxVertexDistanceL1<ResultNumber>(*
this, point);
1012template <
class Po
intType,
class LabelType>
1013template <
class ResultNumber, SegmentConcept OtherSegment>
1018 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1019 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1020 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1023template <
class Po
intType,
class LabelType>
1024template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1029 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1030 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1031 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1034template <
class Po
intType,
class LabelType>
1035template <
class ResultNumber, Po
intConcept OtherPo
int>
1037 return detail::maxVertexDistanceL1<ResultNumber>(*
this, point);
1040template <
class Po
intType,
class LabelType>
1041template <
class ResultNumber, SegmentConcept OtherSegment>
1043 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1044 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1045 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1048template <
class Po
intType,
class LabelType>
1049template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1051 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1052 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1053 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1056template <
class Po
intType,
class LabelType>
1057template <
class ResultNumber, RectangleConcept OtherRectangle>
1059 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1060 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1061 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1064template <
class Po
intType,
class LabelType>
1065template <
class ResultNumber, TriangleConcept OtherTriangle>
1067 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1068 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1069 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1072template <
class Po
intType_,
class LabelType>
1073template <
class ResultNumber, Po
intConcept OtherPo
int>
1075 return detail::maxVertexDistanceL1<ResultNumber>(*
this, point);
1078template <
class Po
intType_,
class LabelType>
1079template <
class ResultNumber, SegmentConcept OtherSegment>
1081 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1082 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1083 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1086template <
class Po
intType_,
class LabelType>
1087template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1089 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1090 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1091 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1094template <
class Po
intType_,
class LabelType>
1095template <
class ResultNumber, RectangleConcept OtherRectangle>
1097 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1098 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1099 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1102template <
class Po
intType_,
class LabelType>
1103template <
class ResultNumber, TriangleConcept OtherTriangle>
1105 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1106 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1107 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1110template <
class Po
intType_,
class LabelType>
1111template <
class ResultNumber, ConvexConcept OtherConvex>
1113 const auto worst_from_this = detail::maxVertexDistanceL1<ResultNumber>(*
this, other);
1114 const auto worst_from_other = detail::maxVertexDistanceL1<ResultNumber>(other, *
this);
1115 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1119template <
class Po
intType_,
class TLabel>
1120template <
class ResultNumber, MonotoneChainConcept OtherChain>
1123 return ResultNumber{};
1125 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1131template <
class Po
intType,
class LabelType,
class Storage>
1132template <
class ResultNumber,
class OtherShape>
1133constexpr ResultNumber MonotoneChain<PointType, LabelType, Storage>::edgeMinDistanceL1(
const OtherShape& other)
const {
1134 assert(size() >= 1);
1138 return (*
this)[0].template distanceL1<ResultNumber>(other);
1140 ResultNumber best = this->
template boundaryAt<false>(0).template distanceL1<ResultNumber>(other);
1141 for (std::size_t index = 1; index + 1 < size(); ++index) {
1142 const ResultNumber current =
1143 this->
template boundaryAt<false>(index).template distanceL1<ResultNumber>(other);
1144 if (current < best) {
1151template <
class Po
intType,
class LabelType,
class Storage>
1152template <
class ResultNumber, Po
intConcept OtherPo
int>
1155 return ResultNumber{};
1157 return this->
template edgeMinDistanceL1<ResultNumber>(point);
1160template <
class Po
intType,
class LabelType,
class Storage>
1161template <
class ResultNumber, SegmentConcept OtherSegment>
1164 return ResultNumber{};
1166 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1169template <
class Po
intType,
class LabelType,
class Storage>
1170template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1173 return ResultNumber{};
1175 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1178template <
class Po
intType,
class LabelType,
class Storage>
1179template <
class ResultNumber, LineConcept OtherLine>
1182 return ResultNumber{};
1184 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1187template <
class Po
intType,
class LabelType,
class Storage>
1188template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1191 return ResultNumber{};
1193 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1196template <
class Po
intType,
class LabelType,
class Storage>
1197template <
class ResultNumber, RayConcept OtherRay>
1200 return ResultNumber{};
1202 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1205template <
class Po
intType,
class LabelType,
class Storage>
1206template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1209 return ResultNumber{};
1211 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1214template <
class Po
intType,
class LabelType,
class Storage>
1215template <
class ResultNumber, RectangleConcept OtherRectangle>
1218 return ResultNumber{};
1220 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1223template <
class Po
intType,
class LabelType,
class Storage>
1224template <
class ResultNumber, TriangleConcept OtherTriangle>
1227 return ResultNumber{};
1229 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1232template <
class Po
intType,
class LabelType,
class Storage>
1233template <
class ResultNumber, ConvexConcept OtherConvex>
1236 return ResultNumber{};
1238 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1241template <
class Po
intType,
class LabelType,
class Storage>
1242template <
class ResultNumber, MonotoneChainConcept OtherChain>
1245 return ResultNumber{};
1247 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1253template <
class Po
intType,
class LabelType>
1254template <
class ResultNumber,
class OtherShape>
1255constexpr ResultNumber Polyline<PointType, LabelType>::edgeMinDistanceL1(
const OtherShape& other)
const {
1256 assert(size() >= 1);
1260 return (*
this)[0].template distanceL1<ResultNumber>(other);
1262 ResultNumber best = this->
template boundaryAt<false>(0).template distanceL1<ResultNumber>(other);
1263 for (std::size_t index = 1; index + 1 < size(); ++index) {
1264 const ResultNumber current =
1265 this->
template boundaryAt<false>(index).template distanceL1<ResultNumber>(other);
1266 if (current < best) {
1273template <
class Po
intType,
class LabelType>
1274template <
class ResultNumber, Po
intConcept OtherPo
int>
1277 return ResultNumber{};
1279 return this->
template edgeMinDistanceL1<ResultNumber>(point);
1282template <
class Po
intType,
class LabelType>
1283template <
class ResultNumber, SegmentConcept OtherSegment>
1286 return ResultNumber{};
1288 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1291template <
class Po
intType,
class LabelType>
1292template <
class ResultNumber, PolylineConcept OtherPolyline>
1295 return ResultNumber{};
1297 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1301template <
class Po
intType,
class LabelType>
1302template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1305 return ResultNumber{};
1307 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1310template <
class Po
intType,
class LabelType>
1311template <
class ResultNumber, LineConcept OtherLine>
1314 return ResultNumber{};
1316 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1319template <
class Po
intType,
class LabelType>
1320template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1323 return ResultNumber{};
1325 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1328template <
class Po
intType,
class LabelType>
1329template <
class ResultNumber, RayConcept OtherRay>
1332 return ResultNumber{};
1334 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1337template <
class Po
intType,
class LabelType>
1338template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1341 return ResultNumber{};
1343 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1346template <
class Po
intType,
class LabelType>
1347template <
class ResultNumber, RectangleConcept OtherRectangle>
1350 return ResultNumber{};
1352 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1355template <
class Po
intType,
class LabelType>
1356template <
class ResultNumber, TriangleConcept OtherTriangle>
1359 return ResultNumber{};
1361 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1364template <
class Po
intType,
class LabelType>
1365template <
class ResultNumber, ConvexConcept OtherConvex>
1368 return ResultNumber{};
1370 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1373template <
class Po
intType,
class LabelType>
1374template <
class ResultNumber, MonotoneChainConcept OtherChain>
1377 return ResultNumber{};
1379 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1382template <
class Po
intType_,
class TLabel>
1383template <
class ResultNumber, PolylineConcept OtherPolyline>
1386 return ResultNumber{};
1388 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1401template <
class ResultNumber,
class Region,
class Other>
1402constexpr ResultNumber regionEdgesDistanceL1(
const Region& region,
const Other& other) {
1403 ResultNumber best{};
1405 for (std::size_t i = 0; i < region.size(); ++i) {
1406 const ResultNumber current = std::visit(
1407 [&other](
const auto& piece) {
1408 return static_cast<ResultNumber
>(piece.template distanceL1<ResultNumber>(other));
1411 if (!has || current < best) {
1421#define PGL_HPI_DISTANCE_L1(ConceptName, ArgType) \
1422 template <class PointType, class LabelType> \
1423 template <class ResultNumber, ConceptName ArgType> \
1424 constexpr auto HalfplaneIntersection<PointType, LabelType>::distanceL1( \
1425 const ArgType& other) const { \
1426 if (intersects(other)) { \
1427 return ResultNumber{}; \
1429 return detail::regionEdgesDistanceL1<ResultNumber>(*this, other); \
1446#undef PGL_HPI_DISTANCE_L1
1448template <
class Po
intType,
class LabelType>
1449template <
class ResultNumber, HalfplaneIntersectionConcept OtherRegion>
1454 return ResultNumber{};
1456 return detail::regionEdgesDistanceL1<ResultNumber>(*
this, other);
1466template <
class Po
intType,
class LabelType>
1467template <
class ResultNumber,
class OtherShape>
1468constexpr ResultNumber PolygonWithHoles<PointType, LabelType>::edgeMinDistanceL1(
const OtherShape& other)
const {
1469 ResultNumber best{};
1470 bool seeded =
false;
1471 anyBoundaryEdge([&](
const auto&
edge) {
1472 const ResultNumber current =
edge.template distanceL1<ResultNumber>(other);
1473 if (!seeded || current < best) {
1482template <
class Po
intType,
class LabelType>
1483template <
class ResultNumber, Po
intConcept OtherPo
int>
1486 return ResultNumber{};
1488 return this->
template edgeMinDistanceL1<ResultNumber>(point);
1491template <
class Po
intType,
class LabelType>
1492template <
class ResultNumber, SegmentConcept OtherSegment>
1495 return ResultNumber{};
1497 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1500template <
class Po
intType,
class LabelType>
1501template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1504 return ResultNumber{};
1506 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1509template <
class Po
intType,
class LabelType>
1510template <
class ResultNumber, LineConcept OtherLine>
1513 return ResultNumber{};
1515 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1518template <
class Po
intType,
class LabelType>
1519template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1522 return ResultNumber{};
1524 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1527template <
class Po
intType,
class LabelType>
1528template <
class ResultNumber, RayConcept OtherRay>
1531 return ResultNumber{};
1533 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1536template <
class Po
intType,
class LabelType>
1537template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1540 return ResultNumber{};
1542 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1545template <
class Po
intType,
class LabelType>
1546template <
class ResultNumber, RectangleConcept OtherRectangle>
1549 return ResultNumber{};
1551 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1554template <
class Po
intType,
class LabelType>
1555template <
class ResultNumber, TriangleConcept OtherTriangle>
1558 return ResultNumber{};
1560 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1563template <
class Po
intType,
class LabelType>
1564template <
class ResultNumber, ConvexConcept OtherConvex>
1567 return ResultNumber{};
1569 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1572template <
class Po
intType,
class LabelType>
1573template <
class ResultNumber, PolygonConcept OtherPolygon>
1576 return ResultNumber{};
1578 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1581template <
class Po
intType,
class LabelType>
1582template <
class ResultNumber, PolygonWithHolesConcept OtherRegion>
1585 return ResultNumber{};
1587 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1590template <
class Po
intType,
class LabelType>
1591template <
class ResultNumber, MonotoneChainConcept OtherChain>
1594 return ResultNumber{};
1596 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1599template <
class Po
intType,
class LabelType>
1600template <
class ResultNumber, PolylineConcept OtherPolyline>
1603 return ResultNumber{};
1605 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1608template <
class Po
intType,
class LabelType>
1609template <
class ResultNumber, HalfplaneIntersectionConcept OtherIntersection>
1612 return ResultNumber{};
1614 return this->
template edgeMinDistanceL1<ResultNumber>(other);
1628template <
class Po
intType,
class LabelType>
1629template <
class ResultNumber, detail::SetOperandConcept OtherShape>
1630 requires detail::ComponentDistanceL1Concept<ResultNumber, PolygonWithHoles<PointType>, OtherShape>
1637template <
class Po
intType,
class LabelType>
1638template <
class ResultNumber, PolygonSetConcept OtherSet>
1640 ResultNumber best{};
1641 bool seeded =
false;
1644 if (!seeded || current < best) {
Definition forward.hpp:315
Definition forward.hpp:312
Definition forward.hpp:309
Definition forward.hpp:320
Definition forward.hpp:310
Definition forward.hpp:308
Definition forward.hpp:306
Definition forward.hpp:316
Definition forward.hpp:321
Definition forward.hpp:311
Definition forward.hpp:313
Definition forward.hpp:307
Definition forward.hpp:314
Distance and Hausdorff-style measurements between shapes.
#define PGL_HPI_DISTANCE_L1(ConceptName, ArgType)
Definition distancel1.hpp:1421
Definition arrangement.hpp:67
@ y
Definition intervaltree.hpp:24
@ x
Definition intervaltree.hpp:24
@ edge
Definition bitmatrix.hpp:37
@ vertex
Definition bitmatrix.hpp:37
constexpr auto hausdorffDistanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) Hausdorff distance to the given shape.
Definition distancel1.hpp:1074
constexpr bool intersects(const OtherSegment &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:716
constexpr PointType get(std::ptrdiff_t index) const
Cyclic access: same as operator[] but index is taken modulo size(); negative indices wrap from the en...
Definition convex.hpp:289
constexpr std::vector< Segment< PointType > > edges() const
Returns the edges of the convex polygon.
Definition convex.hpp:529
constexpr bool contains(const OtherPoint &point) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1135
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:715
size_t size() const
Returns the number of vertices in the convex polygon.
Definition convex.hpp:840
constexpr Point< ResultNumber, PointLabelType > center() const
Returns the center (circumcenter of the three boundary points) in an explicitly chosen coordinate typ...
Definition disk.hpp:284
constexpr bool contains(const OtherPoint &other) const
Tests whether this shape contains the other shape (A ⊇ B).
Definition contains.hpp:1015
constexpr ResultNumber radius() const
Returns the radius.
Definition disk.hpp:333
detail::floating_result_t< ResultNumber > distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance from this disk to a point.
Definition distancel1.hpp:203
constexpr const PointType & a() const
Returns the first boundary point (lexicographically smallest).
Definition disk.hpp:228
constexpr const PointType & b() const
Returns the second boundary point in canonical order.
Definition disk.hpp:235
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1808
constexpr auto distanceL1(const OtherPoint &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1432
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:407
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:622
constexpr Line< PointType > asLine() const
Returns the boundary line without orientation.
Definition halfplane.hpp:318
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:269
constexpr const PointType & max() const
Returns the largest stored defining point.
Definition line.hpp:189
constexpr const PointType & min() const
Returns the smallest stored defining point.
Definition line.hpp:180
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:312
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1353
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1153
constexpr Line< PointType > asLine() const
Returns the line without orientation.
Definition orientedline.hpp:321
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:306
constexpr auto hausdorffDistanceL1(const OtherSegment &other) const
Returns the Manhattan (L1) Hausdorff distance to the given shape.
Definition distancel1.hpp:975
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:247
Two-dimensional point with optional label payload.
Definition point.hpp:129
constexpr auto hausdorffDistanceL1(const OtherPoint &other) const
Returns the Manhattan (L1) Hausdorff distance to another point.
Definition distancel1.hpp:194
constexpr auto distanceL1(const OtherPoint &other) const
Returns the Manhattan distance to another point.
Definition distance.hpp:75
constexpr const ComponentType & component(std::size_t index) const
Accesses a component by index.
Definition polygonset.hpp:271
PolygonWithHoles< PointType > ComponentType
Definition polygonset.hpp:169
auto distanceL1(const OtherShape &other) const
Computes the squared Euclidean distance to the other shape.
Definition distancel1.hpp:1631
constexpr bool intersects(const OtherPoint &point) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition polygonwithholes.hpp:1649
constexpr auto distanceL1(const OtherPoint &point) const
Computes the squared Euclidean distance to the other shape.
Definition distancel1.hpp:1484
constexpr bool intersects(const OtherChain &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1596
constexpr auto distanceL1(const OtherChain &other) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1121
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1620
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:1275
constexpr const PointType & target() const
Returns the second stored point defining the direction.
Definition ray.hpp:193
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:409
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:339
constexpr const PointType & source() const
Returns the source point of the ray.
Definition ray.hpp:181
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 bool empty() const
Returns whether the rectangle is the empty set of points.
Definition rectangle.hpp:290
constexpr std::array< Segment< PointType >, 4 > edges() const
Returns the four edges as unordered segments.
Definition bounding.hpp:199
constexpr std::array< PointType, 4 > vertices() const
Returns the four vertices in counterclockwise order.
Definition bounding.hpp:188
constexpr std::ptrdiff_t index(const PointType &point) const
Returns the smallest index i with (*this)[i] == point, or -1 if no corner equals point.
Definition rectangle.hpp:330
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:473
constexpr const PointType & max() const
Returns the maximum corner (max x, max y).
Definition rectangle.hpp:359
constexpr auto hausdorffDistanceL1(const OtherRectangle &other) const
Returns the Manhattan (L1) Hausdorff distance to the given shape.
Definition distancel1.hpp:994
Unoriented closed segment between two endpoints plus optional segment label.
Definition segment.hpp:58
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:48
constexpr const PointType & max() const
Returns the largest stored endpoint.
Definition segment.hpp:199
constexpr const PointType & min() const
Returns the smallest stored endpoint.
Definition segment.hpp:190
constexpr auto hausdorffDistanceL1(const OtherSegment &other) const
Returns the Manhattan (L1) Hausdorff distance to the given shape.
Definition distancel1.hpp:961
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:219
constexpr auto distanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) distance to the given shape.
Definition distancel1.hpp:627
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:134
constexpr auto hausdorffDistanceL1(const OtherPoint &point) const
Returns the Manhattan (L1) Hausdorff distance to the given shape.
Definition distancel1.hpp:1036