37template <
class ResultNumber>
40 const ResultNumber dx = b.x() - a.x();
41 const ResultNumber dy = b.y() - a.y();
42 const ResultNumber px = q.x() - a.x();
43 const ResultNumber py = q.y() - a.y();
45 if (dx == 0 && dy == 0) {
46 const ResultNumber ax = pgl::detail::abs(px);
47 const ResultNumber ay = pgl::detail::abs(py);
48 return ax > ay ? ax : ay;
51 bool haveBest =
false;
53 const auto consider = [&](
const ResultNumber& value) {
54 if (!haveBest || value < best) {
61 const ResultNumber ax = pgl::detail::abs(px);
62 const ResultNumber ay = pgl::detail::abs(py);
63 consider(ax > ay ? ax : ay);
66 const ResultNumber ax = pgl::detail::abs(px - dx);
67 const ResultNumber ay = pgl::detail::abs(py - dy);
68 consider(ax > ay ? ax : ay);
71 const ResultNumber cross = dx * py - dy * px;
72 const auto considerCrossing = [&](
const ResultNumber& n,
const ResultNumber& d) {
82 if (boundedLow && (d > 0 ? n < 0 : n > 0)) {
85 if (boundedHigh && n * d > d * d) {
88 consider(pgl::detail::abs(cross) / pgl::detail::abs(d));
90 considerCrossing(px, dx);
91 considerCrossing(py, dy);
92 considerCrossing(px - py, dx - dy);
93 considerCrossing(px + py, dx + dy);
107template <
class ResultNumber,
class Self,
class OtherShape>
108constexpr ResultNumber maxVertexDistanceLInf(
const Self& self,
const OtherShape& other) {
109 const auto self_vertices = self.vertices();
110 const auto distanceToVertex = [&other](
const auto&
vertex) -> ResultNumber {
111 return other.template distanceLInf<ResultNumber>(
vertex);
113 ResultNumber worst = distanceToVertex(self_vertices[0]);
114 for (std::size_t index = 1; index < self_vertices.size(); ++index) {
115 const ResultNumber current = distanceToVertex(self_vertices[index]);
116 if (worst < current) {
130template <
class Float =
double>
131Float diskPointDistanceLInf(Float a, Float b, Float r) {
132 const auto h = [&](Float theta) {
133 return std::max(std::abs(a + r * std::cos(theta)), std::abs(b + r * std::sin(theta)));
136 constexpr int coarseSteps = 720;
138 Float bestValue = h(Float{0});
139 for (
int i = 1; i < coarseSteps; ++i) {
140 const Float theta = Float{2} * std::numbers::pi_v<Float> * i / coarseSteps;
141 const Float value = h(theta);
142 if (value < bestValue) {
148 const Float step = Float{2} * std::numbers::pi_v<Float> / coarseSteps;
149 Float lo = bestTheta - step;
150 Float hi = bestTheta + step;
151 constexpr Float invPhi = 0.6180339887498949;
152 Float c1 = hi - invPhi * (hi - lo);
153 Float c2 = lo + invPhi * (hi - lo);
156 for (
int i = 0; i < 100; ++i) {
161 c1 = hi - invPhi * (hi - lo);
167 c2 = lo + invPhi * (hi - lo);
172 return std::min({bestValue, hc1, hc2});
180template <
class Number,
class Label>
181template <
class ResultNumber, Po
intConcept OtherPo
int>
189template <
class Po
intType_,
class TLabel>
190template <
class ResultNumber, Po
intConcept OtherPo
int>
192 const OtherPoint& point)
const {
193 using Float = detail::floating_result_t<ResultNumber>;
197 const Float
a =
center<Float>().x() -
static_cast<Float
>(point.x());
198 const Float
b =
center<Float>().y() -
static_cast<Float
>(point.y());
205template <
class Po
intType,
class LabelType>
206template <
class ResultNumber, Po
intConcept OtherPo
int>
208 return detail::segmentLikeDistanceLInf<ResultNumber>(
212template <
class Po
intType,
class LabelType>
213template <
class ResultNumber, SegmentConcept OtherSegment>
216 return ResultNumber{};
224 const auto best_from_this = this_min_to_other < this_max_to_other ? this_min_to_other : this_max_to_other;
225 const auto best_from_other = other_min_to_this < other_max_to_this ? other_min_to_this : other_max_to_this;
227 return best_from_this < best_from_other ? best_from_this : best_from_other;
233template <
class Po
intType,
class LabelType>
234template <
class ResultNumber, Po
intConcept OtherPo
int>
239template <
class Po
intType,
class LabelType>
240template <
class ResultNumber, SegmentConcept OtherSegment>
245template <
class Po
intType,
class LabelType>
246template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
255template <
class Po
intType,
class LabelType>
256template <
class ResultNumber, Po
intConcept OtherPo
int>
258 return detail::segmentLikeDistanceLInf<ResultNumber>(
262template <
class Po
intType,
class LabelType>
263template <
class ResultNumber, LineConcept OtherLine>
266 return ResultNumber{};
271template <
class Po
intType,
class LabelType>
272template <
class ResultNumber, SegmentConcept OtherSegment>
275 return ResultNumber{};
280 return source_distance < target_distance ? source_distance : target_distance;
283template <
class Po
intType,
class LabelType>
284template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
292template <
class Po
intType,
class LabelType>
293template <
class ResultNumber, Po
intConcept OtherPo
int>
298template <
class Po
intType,
class LabelType>
299template <
class ResultNumber, LineConcept OtherLine>
304template <
class Po
intType,
class LabelType>
305template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
310template <
class Po
intType,
class LabelType>
311template <
class ResultNumber, SegmentConcept OtherSegment>
316template <
class Po
intType,
class LabelType>
317template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
325template <
class Po
intType,
class LabelType>
326template <
class ResultNumber, Po
intConcept OtherPo
int>
328 return detail::segmentLikeDistanceLInf<ResultNumber>(
332template <
class Po
intType,
class LabelType>
333template <
class ResultNumber, LineConcept OtherLine>
336 return ResultNumber{};
341template <
class Po
intType,
class LabelType>
342template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
345 return ResultNumber{};
350template <
class Po
intType,
class LabelType>
351template <
class ResultNumber, SegmentConcept OtherSegment>
354 return ResultNumber{};
360 const auto best_from_segment = other_min_to_this < other_max_to_this ? other_min_to_this : other_max_to_this;
361 return source_to_other < best_from_segment ? source_to_other : best_from_segment;
364template <
class Po
intType,
class LabelType>
365template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
368 return ResultNumber{};
374 const auto best_from_segment = other_source_to_this < other_target_to_this ? other_source_to_this : other_target_to_this;
375 return source_to_other < best_from_segment ? source_to_other : best_from_segment;
378template <
class Po
intType,
class LabelType>
379template <
class ResultNumber, RayConcept OtherRay>
382 return ResultNumber{};
387 return this_source_to_other < other_source_to_this ? this_source_to_other : other_source_to_this;
393template <
class Po
intType,
class LabelType>
394template <
class ResultNumber, Po
intConcept OtherPo
int>
397 return ResultNumber{};
402template <
class Po
intType,
class LabelType>
403template <
class ResultNumber, SegmentConcept OtherSegment>
406 return ResultNumber{};
411template <
class Po
intType,
class LabelType>
412template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
415 return ResultNumber{};
420template <
class Po
intType,
class LabelType>
421template <
class ResultNumber, LineConcept OtherLine>
424 return ResultNumber{};
429template <
class Po
intType,
class LabelType>
430template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
433 return ResultNumber{};
438template <
class Po
intType,
class LabelType>
439template <
class ResultNumber, RayConcept OtherRay>
442 return ResultNumber{};
447template <
class Po
intType,
class LabelType>
448template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
451 return ResultNumber{};
459template <
class Po
intType,
class LabelType>
460template <
class ResultNumber, Po
intConcept OtherPo
int>
465 const ResultNumber dx =
static_cast<ResultNumber
>(axisDistance(
min().
x(),
max().
x(), point.x(), point.x()));
466 const ResultNumber dy =
static_cast<ResultNumber
>(axisDistance(
min().
y(),
max().
y(), point.y(), point.y()));
467 return dx > dy ? dx : dy;
470template <
class Po
intType,
class LabelType>
471template <
class ResultNumber, LineConcept OtherLine>
477 return ResultNumber{};
480 const auto rectangle_vertices =
vertices();
482 for (std::size_t
index = 1;
index < rectangle_vertices.size(); ++
index) {
484 if (current_distance < best_distance) {
485 best_distance = current_distance;
489 return best_distance;
492template <
class Po
intType,
class LabelType>
493template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
501template <
class Po
intType,
class LabelType>
502template <
class ResultNumber, SegmentConcept OtherSegment>
508 return ResultNumber{};
513 if (other_max_distance < best_distance) {
514 best_distance = other_max_distance;
517 const auto rectangle_edges =
edges();
518 for (
const auto&
edge : rectangle_edges) {
520 if (current_distance < best_distance) {
521 best_distance = current_distance;
525 return best_distance;
528template <
class Po
intType,
class LabelType>
529template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
537template <
class Po
intType,
class LabelType>
538template <
class ResultNumber, RayConcept OtherRay>
544 return ResultNumber{};
548 const auto rectangle_edges =
edges();
549 for (
const auto&
edge : rectangle_edges) {
551 if (current_distance < best_distance) {
552 best_distance = current_distance;
556 return best_distance;
559template <
class Po
intType,
class LabelType>
560template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
566 return ResultNumber{};
571template <
class Po
intType,
class LabelType>
572template <
class ResultNumber, RectangleConcept OtherRectangle>
577 const ResultNumber dx =
static_cast<ResultNumber
>(axisDistance(
min().
x(),
max().
x(), other.min().x(), other.max().x()));
578 const ResultNumber dy =
static_cast<ResultNumber
>(axisDistance(
min().
y(),
max().
y(), other.min().y(), other.max().y()));
579 return dx > dy ? dx : dy;
585template <
class Po
intType,
class LabelType>
586template <
class ResultNumber,
class OtherShape>
587constexpr ResultNumber Triangle<PointType, LabelType>::edgeMinDistanceLInf(
const OtherShape& other)
const {
588 const auto triangle_edges = edges();
589 auto best = triangle_edges[0].template distanceLInf<ResultNumber>(other);
590 for (std::size_t index = 1; index < triangle_edges.size(); ++index) {
591 const auto current = triangle_edges[index].template distanceLInf<ResultNumber>(other);
592 if (current < best) {
599template <
class Po
intType,
class LabelType>
600template <
class ResultNumber,
class OtherShape>
601constexpr ResultNumber Triangle<PointType, LabelType>::vertexMinDistanceLInf(
const OtherShape& other)
const {
602 const auto triangle_vertices = vertices();
603 auto best = other.template distanceLInf<ResultNumber>(triangle_vertices[0]);
604 for (std::size_t index = 1; index < triangle_vertices.size(); ++index) {
605 const auto current = other.template distanceLInf<ResultNumber>(triangle_vertices[index]);
606 if (current < best) {
613template <
class Po
intType,
class LabelType>
614template <
class ResultNumber, Po
intConcept OtherPo
int>
617 return ResultNumber{};
619 return this->
template edgeMinDistanceLInf<ResultNumber>(point);
622template <
class Po
intType,
class LabelType>
623template <
class ResultNumber, SegmentConcept OtherSegment>
626 return ResultNumber{};
628 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
631template <
class Po
intType,
class LabelType>
632template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
635 return ResultNumber{};
637 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
640template <
class Po
intType,
class LabelType>
641template <
class ResultNumber, LineConcept OtherLine>
644 return ResultNumber{};
646 return this->
template vertexMinDistanceLInf<ResultNumber>(other);
649template <
class Po
intType,
class LabelType>
650template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
653 return ResultNumber{};
655 return this->
template vertexMinDistanceLInf<ResultNumber>(other);
658template <
class Po
intType,
class LabelType>
659template <
class ResultNumber, RayConcept OtherRay>
662 return ResultNumber{};
664 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
667template <
class Po
intType,
class LabelType>
668template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
671 return ResultNumber{};
676template <
class Po
intType,
class LabelType>
677template <
class ResultNumber, RectangleConcept OtherRectangle>
680 return ResultNumber{};
682 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
685template <
class Po
intType,
class LabelType>
686template <
class ResultNumber, TriangleConcept OtherTriangle>
689 return ResultNumber{};
691 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
701template <
class Po
intType_,
class LabelType>
702template <
class ResultNumber, Po
intConcept OtherPo
int>
705 return ResultNumber{};
707 auto edgeVector =
edges();
709 for (
auto& e : edgeVector) {
711 if (current < best) {
718template <
class Po
intType_,
class LabelType>
719template <
class ResultNumber, SegmentConcept OtherSegment>
722 return ResultNumber{};
724 auto edgeVector =
edges();
726 for (
auto& e : edgeVector) {
728 if (current < best) {
735template <
class Po
intType_,
class LabelType>
736template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
742template <
class Po
intType_,
class LabelType>
743template <
class ResultNumber, ConvexConcept OtherConvex>
746 return ResultNumber{};
749 const auto minOverEdges = [](
const auto& source,
const auto& target) {
750 const auto edgeVector = source.edges();
752 for (
const auto&
edge : edgeVector) {
754 if (current < best) {
761 if (
size() <= other.size()) {
762 return minOverEdges(*
this, other);
764 return minOverEdges(other, *
this);
767template <
class Po
intType_,
class LabelType>
768template <
class ResultNumber, TriangleConcept OtherTriangle>
773template <
class Po
intType_,
class LabelType>
774template <
class ResultNumber, RectangleConcept OtherRectangle>
779template <
class Po
intType_,
class LabelType>
780template <
class ResultNumber, LineConcept OtherLine>
783 return ResultNumber{};
786 for (std::ptrdiff_t i = 1; i < static_cast<std::ptrdiff_t>(
size()); ++i) {
788 if (current < best) {
795template <
class Po
intType_,
class LabelType>
796template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
801template <
class Po
intType_,
class LabelType>
802template <
class ResultNumber, RayConcept OtherRay>
805 return ResultNumber{};
807 auto edgeVector =
edges();
809 for (
const auto& e : edgeVector) {
811 if (current < best) {
818template <
class Po
intType_,
class LabelType>
819template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
822 return ResultNumber{};
830template <
class Po
intType_,
class TLabel>
831template <
class ResultNumber,
class OtherShape>
832constexpr ResultNumber Polygon<PointType_, TLabel>::edgeMinDistanceLInf(
const OtherShape& other)
const {
833 const auto boundaryEdges = edges();
834 ResultNumber best = boundaryEdges[0].template distanceLInf<ResultNumber>(other);
835 for (std::size_t index = 1; index < boundaryEdges.size(); ++index) {
836 const ResultNumber current = boundaryEdges[index].template distanceLInf<ResultNumber>(other);
837 if (current < best) {
844template <
class Po
intType_,
class TLabel>
845template <
class ResultNumber, Po
intConcept OtherPo
int>
848 return ResultNumber{};
850 return this->
template edgeMinDistanceLInf<ResultNumber>(point);
853template <
class Po
intType_,
class TLabel>
854template <
class ResultNumber, SegmentConcept OtherSegment>
857 return ResultNumber{};
859 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
862template <
class Po
intType_,
class TLabel>
863template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
866 return ResultNumber{};
868 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
871template <
class Po
intType_,
class TLabel>
872template <
class ResultNumber, LineConcept OtherLine>
875 return ResultNumber{};
877 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
880template <
class Po
intType_,
class TLabel>
881template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
884 return ResultNumber{};
886 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
889template <
class Po
intType_,
class TLabel>
890template <
class ResultNumber, RayConcept OtherRay>
893 return ResultNumber{};
895 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
898template <
class Po
intType_,
class TLabel>
899template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
902 return ResultNumber{};
904 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
907template <
class Po
intType_,
class TLabel>
908template <
class ResultNumber, RectangleConcept OtherRectangle>
911 return ResultNumber{};
913 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
916template <
class Po
intType_,
class TLabel>
917template <
class ResultNumber, TriangleConcept OtherTriangle>
920 return ResultNumber{};
922 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
925template <
class Po
intType_,
class TLabel>
926template <
class ResultNumber, ConvexConcept OtherConvex>
929 return ResultNumber{};
931 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
934template <
class Po
intType_,
class TLabel>
935template <
class ResultNumber, PolygonConcept OtherPolygon>
938 return ResultNumber{};
940 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
947template <
class Po
intType,
class LabelType>
948template <
class ResultNumber, SegmentConcept OtherSegment>
950 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
951 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
952 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
955template <
class Po
intType,
class LabelType>
956template <
class ResultNumber, Po
intConcept OtherPo
int>
958 return detail::maxVertexDistanceLInf<ResultNumber>(*
this, point);
961template <
class Po
intType,
class LabelType>
962template <
class ResultNumber, SegmentConcept OtherSegment>
967template <
class Po
intType,
class LabelType>
968template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
974template <
class Po
intType,
class LabelType>
975template <
class ResultNumber, Po
intConcept OtherPo
int>
980template <
class Po
intType,
class LabelType>
981template <
class ResultNumber, RectangleConcept OtherRectangle>
986 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
987 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
988 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
991template <
class Po
intType,
class LabelType>
992template <
class ResultNumber, Po
intConcept OtherPo
int>
997 return detail::maxVertexDistanceLInf<ResultNumber>(*
this, point);
1000template <
class Po
intType,
class LabelType>
1001template <
class ResultNumber, SegmentConcept OtherSegment>
1006 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1007 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1008 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1011template <
class Po
intType,
class LabelType>
1012template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1017 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1018 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1019 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1022template <
class Po
intType,
class LabelType>
1023template <
class ResultNumber, Po
intConcept OtherPo
int>
1025 return detail::maxVertexDistanceLInf<ResultNumber>(*
this, point);
1028template <
class Po
intType,
class LabelType>
1029template <
class ResultNumber, SegmentConcept OtherSegment>
1031 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1032 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1033 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1036template <
class Po
intType,
class LabelType>
1037template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1039 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1040 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1041 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1044template <
class Po
intType,
class LabelType>
1045template <
class ResultNumber, RectangleConcept OtherRectangle>
1047 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1048 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1049 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1052template <
class Po
intType,
class LabelType>
1053template <
class ResultNumber, TriangleConcept OtherTriangle>
1055 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1056 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1057 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1060template <
class Po
intType_,
class LabelType>
1061template <
class ResultNumber, Po
intConcept OtherPo
int>
1063 return detail::maxVertexDistanceLInf<ResultNumber>(*
this, point);
1066template <
class Po
intType_,
class LabelType>
1067template <
class ResultNumber, SegmentConcept OtherSegment>
1069 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1070 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1071 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1074template <
class Po
intType_,
class LabelType>
1075template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1077 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1078 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1079 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1082template <
class Po
intType_,
class LabelType>
1083template <
class ResultNumber, RectangleConcept OtherRectangle>
1085 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1086 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1087 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1090template <
class Po
intType_,
class LabelType>
1091template <
class ResultNumber, TriangleConcept OtherTriangle>
1093 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1094 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1095 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1098template <
class Po
intType_,
class LabelType>
1099template <
class ResultNumber, ConvexConcept OtherConvex>
1101 const auto worst_from_this = detail::maxVertexDistanceLInf<ResultNumber>(*
this, other);
1102 const auto worst_from_other = detail::maxVertexDistanceLInf<ResultNumber>(other, *
this);
1103 return worst_from_this > worst_from_other ? worst_from_this : worst_from_other;
1107template <
class Po
intType_,
class TLabel>
1108template <
class ResultNumber, MonotoneChainConcept OtherChain>
1111 return ResultNumber{};
1113 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1119template <
class Po
intType,
class LabelType,
class Storage>
1120template <
class ResultNumber,
class OtherShape>
1121constexpr ResultNumber MonotoneChain<PointType, LabelType, Storage>::edgeMinDistanceLInf(
const OtherShape& other)
const {
1122 assert(size() >= 1);
1126 return (*
this)[0].template distanceLInf<ResultNumber>(other);
1130 const ResultNumber current =
1132 if (current < best) {
1139template <
class Po
intType,
class LabelType,
class Storage>
1140template <
class ResultNumber, Po
intConcept OtherPo
int>
1143 return ResultNumber{};
1145 return this->
template edgeMinDistanceLInf<ResultNumber>(point);
1148template <
class Po
intType,
class LabelType,
class Storage>
1149template <
class ResultNumber, SegmentConcept OtherSegment>
1152 return ResultNumber{};
1154 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1157template <
class Po
intType,
class LabelType,
class Storage>
1158template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1161 return ResultNumber{};
1163 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1166template <
class Po
intType,
class LabelType,
class Storage>
1167template <
class ResultNumber, LineConcept OtherLine>
1170 return ResultNumber{};
1172 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1175template <
class Po
intType,
class LabelType,
class Storage>
1176template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1179 return ResultNumber{};
1181 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1184template <
class Po
intType,
class LabelType,
class Storage>
1185template <
class ResultNumber, RayConcept OtherRay>
1188 return ResultNumber{};
1190 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1193template <
class Po
intType,
class LabelType,
class Storage>
1194template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1197 return ResultNumber{};
1199 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1202template <
class Po
intType,
class LabelType,
class Storage>
1203template <
class ResultNumber, RectangleConcept OtherRectangle>
1206 return ResultNumber{};
1208 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1211template <
class Po
intType,
class LabelType,
class Storage>
1212template <
class ResultNumber, TriangleConcept OtherTriangle>
1215 return ResultNumber{};
1217 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1220template <
class Po
intType,
class LabelType,
class Storage>
1221template <
class ResultNumber, ConvexConcept OtherConvex>
1224 return ResultNumber{};
1226 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1229template <
class Po
intType,
class LabelType,
class Storage>
1230template <
class ResultNumber, MonotoneChainConcept OtherChain>
1233 return ResultNumber{};
1235 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1241template <
class Po
intType,
class LabelType>
1242template <
class ResultNumber,
class OtherShape>
1243constexpr ResultNumber Polyline<PointType, LabelType>::edgeMinDistanceLInf(
const OtherShape& other)
const {
1244 assert(size() >= 1);
1248 return (*
this)[0].template distanceLInf<ResultNumber>(other);
1250 ResultNumber best = this->
template boundaryAt<false>(0).template distanceLInf<ResultNumber>(other);
1251 for (std::size_t index = 1; index + 1 < size(); ++index) {
1252 const ResultNumber current =
1253 this->
template boundaryAt<false>(index).template distanceLInf<ResultNumber>(other);
1254 if (current < best) {
1261template <
class Po
intType,
class LabelType>
1262template <
class ResultNumber, Po
intConcept OtherPo
int>
1265 return ResultNumber{};
1267 return this->
template edgeMinDistanceLInf<ResultNumber>(point);
1270template <
class Po
intType,
class LabelType>
1271template <
class ResultNumber, SegmentConcept OtherSegment>
1274 return ResultNumber{};
1276 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1279template <
class Po
intType,
class LabelType>
1280template <
class ResultNumber, PolylineConcept OtherPolyline>
1283 return ResultNumber{};
1285 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1289template <
class Po
intType,
class LabelType>
1290template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1293 return ResultNumber{};
1295 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1298template <
class Po
intType,
class LabelType>
1299template <
class ResultNumber, LineConcept OtherLine>
1302 return ResultNumber{};
1304 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1307template <
class Po
intType,
class LabelType>
1308template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1311 return ResultNumber{};
1313 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1316template <
class Po
intType,
class LabelType>
1317template <
class ResultNumber, RayConcept OtherRay>
1320 return ResultNumber{};
1322 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1325template <
class Po
intType,
class LabelType>
1326template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1329 return ResultNumber{};
1331 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1334template <
class Po
intType,
class LabelType>
1335template <
class ResultNumber, RectangleConcept OtherRectangle>
1338 return ResultNumber{};
1340 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1343template <
class Po
intType,
class LabelType>
1344template <
class ResultNumber, TriangleConcept OtherTriangle>
1347 return ResultNumber{};
1349 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1352template <
class Po
intType,
class LabelType>
1353template <
class ResultNumber, ConvexConcept OtherConvex>
1356 return ResultNumber{};
1358 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1361template <
class Po
intType,
class LabelType>
1362template <
class ResultNumber, MonotoneChainConcept OtherChain>
1365 return ResultNumber{};
1367 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1370template <
class Po
intType_,
class TLabel>
1371template <
class ResultNumber, PolylineConcept OtherPolyline>
1374 return ResultNumber{};
1376 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1390template <
class ResultNumber,
class Region,
class Other>
1391constexpr ResultNumber regionEdgesDistanceLInf(
const Region& region,
const Other& other) {
1392 ResultNumber best{};
1394 for (std::size_t i = 0; i < region.size(); ++i) {
1395 const ResultNumber current = std::visit(
1396 [&other](
const auto& piece) {
1397 return static_cast<ResultNumber
>(piece.template distanceLInf<ResultNumber>(other));
1400 if (!has || current < best) {
1410#define PGL_HPI_DISTANCE_LINF(ConceptName, ArgType) \
1411 template <class PointType, class LabelType> \
1412 template <class ResultNumber, ConceptName ArgType> \
1413 constexpr auto HalfplaneIntersection<PointType, LabelType>::distanceLInf( \
1414 const ArgType& other) const { \
1415 if (intersects(other)) { \
1416 return ResultNumber{}; \
1418 return detail::regionEdgesDistanceLInf<ResultNumber>(*this, other); \
1435#undef PGL_HPI_DISTANCE_LINF
1437template <
class Po
intType,
class LabelType>
1438template <
class ResultNumber, HalfplaneIntersectionConcept OtherRegion>
1443 return ResultNumber{};
1445 return detail::regionEdgesDistanceLInf<ResultNumber>(*
this, other);
1455template <
class Po
intType,
class LabelType>
1456template <
class ResultNumber,
class OtherShape>
1457constexpr ResultNumber PolygonWithHoles<PointType, LabelType>::edgeMinDistanceLInf(
const OtherShape& other)
const {
1458 ResultNumber best{};
1459 bool seeded =
false;
1460 anyBoundaryEdge([&](
const auto&
edge) {
1461 const ResultNumber current =
edge.template distanceLInf<ResultNumber>(other);
1462 if (!seeded || current < best) {
1471template <
class Po
intType,
class LabelType>
1472template <
class ResultNumber, Po
intConcept OtherPo
int>
1475 return ResultNumber{};
1477 return this->
template edgeMinDistanceLInf<ResultNumber>(point);
1480template <
class Po
intType,
class LabelType>
1481template <
class ResultNumber, SegmentConcept OtherSegment>
1484 return ResultNumber{};
1486 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1489template <
class Po
intType,
class LabelType>
1490template <
class ResultNumber, OrientedSegmentConcept OtherOrientedSegment>
1493 return ResultNumber{};
1495 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1498template <
class Po
intType,
class LabelType>
1499template <
class ResultNumber, LineConcept OtherLine>
1502 return ResultNumber{};
1504 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1507template <
class Po
intType,
class LabelType>
1508template <
class ResultNumber, OrientedLineConcept OtherOrientedLine>
1511 return ResultNumber{};
1513 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1516template <
class Po
intType,
class LabelType>
1517template <
class ResultNumber, RayConcept OtherRay>
1520 return ResultNumber{};
1522 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1525template <
class Po
intType,
class LabelType>
1526template <
class ResultNumber, HalfplaneConcept OtherHalfplane>
1529 return ResultNumber{};
1531 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1534template <
class Po
intType,
class LabelType>
1535template <
class ResultNumber, RectangleConcept OtherRectangle>
1538 return ResultNumber{};
1540 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1543template <
class Po
intType,
class LabelType>
1544template <
class ResultNumber, TriangleConcept OtherTriangle>
1547 return ResultNumber{};
1549 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1552template <
class Po
intType,
class LabelType>
1553template <
class ResultNumber, ConvexConcept OtherConvex>
1556 return ResultNumber{};
1558 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1561template <
class Po
intType,
class LabelType>
1562template <
class ResultNumber, PolygonConcept OtherPolygon>
1565 return ResultNumber{};
1567 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1570template <
class Po
intType,
class LabelType>
1571template <
class ResultNumber, PolygonWithHolesConcept OtherRegion>
1574 return ResultNumber{};
1576 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1579template <
class Po
intType,
class LabelType>
1580template <
class ResultNumber, MonotoneChainConcept OtherChain>
1583 return ResultNumber{};
1585 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1588template <
class Po
intType,
class LabelType>
1589template <
class ResultNumber, PolylineConcept OtherPolyline>
1592 return ResultNumber{};
1594 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1597template <
class Po
intType,
class LabelType>
1598template <
class ResultNumber, HalfplaneIntersectionConcept OtherIntersection>
1601 return ResultNumber{};
1603 return this->
template edgeMinDistanceLInf<ResultNumber>(other);
1617template <
class Po
intType,
class LabelType>
1618template <
class ResultNumber, detail::SetOperandConcept OtherShape>
1619 requires detail::ComponentDistanceLInfConcept<ResultNumber, PolygonWithHoles<PointType>, OtherShape>
1626template <
class Po
intType,
class LabelType>
1627template <
class ResultNumber, PolygonSetConcept OtherSet>
1629 ResultNumber best{};
1630 bool seeded =
false;
1633 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
Manhattan (L1) distance between shapes.
#define PGL_HPI_DISTANCE_LINF(ConceptName, ArgType)
Definition distancelinf.hpp:1410
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 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 auto hausdorffDistanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
Definition distancelinf.hpp:1062
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:703
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
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
detail::floating_result_t< ResultNumber > distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance from this disk to a point.
Definition distancelinf.hpp:191
constexpr ResultNumber radius() const
Returns the radius.
Definition disk.hpp:333
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 auto distanceLInf(const OtherPoint &other) const
Returns the Chebyshev (L∞) distance to the given shape.
Definition distancelinf.hpp:1421
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1808
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:395
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 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 auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:257
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1141
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1353
constexpr Line< PointType > asLine() const
Returns the line without orientation.
Definition orientedline.hpp:321
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:294
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:235
constexpr auto hausdorffDistanceLInf(const OtherSegment &other) const
Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
Definition distancelinf.hpp:963
Two-dimensional point with optional label payload.
Definition point.hpp:129
constexpr auto distanceLInf(const OtherPoint &other) const
Returns the Chebyshev distance to another point.
Definition distance.hpp:83
static constexpr std::size_t size()
Definition point.hpp:246
constexpr std::ptrdiff_t index(const NumberType &value) const
Definition point.hpp:267
constexpr auto hausdorffDistanceLInf(const OtherPoint &other) const
Returns the Chebyshev (LInf) Hausdorff distance to another point.
Definition distancelinf.hpp:182
auto distanceLInf(const OtherShape &other) const
Computes the squared Euclidean distance to the other shape.
Definition distancelinf.hpp:1620
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
constexpr auto distanceLInf(const OtherPoint &point) const
Computes the squared Euclidean distance to the other shape.
Definition distancelinf.hpp:1473
constexpr bool intersects(const OtherPoint &point) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition polygonwithholes.hpp:1649
constexpr bool intersects(const OtherChain &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1596
constexpr auto distanceLInf(const OtherChain &other) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1109
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:1263
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:1620
constexpr const PointType & target() const
Returns the second stored point defining the direction.
Definition ray.hpp:193
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:327
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:409
constexpr const PointType & source() const
Returns the source point of the ray.
Definition ray.hpp:181
constexpr auto hausdorffDistanceLInf(const OtherRectangle &other) const
Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
Definition distancelinf.hpp:982
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 auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:461
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 const PointType & max() const
Returns the maximum corner (max x, max y).
Definition rectangle.hpp:359
Unoriented closed segment between two endpoints plus optional segment label.
Definition segment.hpp:58
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:207
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 hausdorffDistanceLInf(const OtherSegment &other) const
Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
Definition distancelinf.hpp:949
constexpr bool intersects(const OtherPoint &other) const
Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
Definition intersects.hpp:134
constexpr auto hausdorffDistanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
Definition distancelinf.hpp:1024
constexpr auto distanceLInf(const OtherPoint &point) const
Returns the Chebyshev (LInf) distance to the given shape.
Definition distancelinf.hpp:615