336 }
while (index != 0 && subdividingVertex(ring, index));
352template <
class First,
class Second>
353constexpr bool sameRingPointSet(
const First& first,
const Second& second) {
354 if (first.size() < 3 || second.size() < 3) {
357 if (sameRepresentation(first, second)) {
360 if (!(first[0] == second[0])) {
363 if (first.size() == second.size()) {
364 std::size_t index = 1;
365 while (index < first.size() && first[index] == second[index]) {
368 if (index == first.size()) {
372 std::size_t here = 0;
373 std::size_t there = 0;
375 here = nextRingCorner(first, here);
376 there = nextRingCorner(second, there);
377 if (here == 0 || there == 0) {
378 return here == there;
380 if (!(first[here] == second[there])) {
390template <
class First,
class Second>
391constexpr bool sameRingShapes(
const First& first,
const Second& second) {
392 if (sameRepresentation(first, second)) {
395 if (!sameBoundingBox(first, second)) {
400 if (!(first[0] == second[0])) {
408 if (collapsedBelowArea(first)) {
409 return collapsedMatches(first, second);
411 if (collapsedBelowArea(second)) {
412 return collapsedMatches(second, first);
414 return sameRingPointSet(first, second);
429template <
class FirstRange,
class SecondRange,
class Compare>
430constexpr bool sameRingCollection(
const FirstRange& first,
const SecondRange& second, Compare same) {
431 const std::size_t count = first.size();
433 for (std::size_t i = 0; i < count; ++i) {
434 if (!same(first[i], second[i])) {
442 for (
const auto& ring : first) {
444 for (
const auto& candidate : second) {
445 if (same(ring, candidate)) {
466template <PolygonWithHolesConcept First, PolygonWithHolesConcept Second>
467constexpr bool sameRegionRings(
const First& first,
const Second& second) {
468 if (sameRepresentation(first, second)) {
471 if (!sameRingPointSet(first.outer(), second.outer())) {
474 if (first.holeCount() != second.holeCount()) {
477 return sameRingCollection(first.holes(), second.holes(),
478 [](
const auto& one,
const auto& other) {
479 return sameRingPointSet(one, other);
495template <
class SegmentType,
class EdgeRange>
496constexpr bool segmentCoveredByEdges(
const SegmentType& segment,
const EdgeRange& edges) {
497 using EdgeType = std::ranges::range_value_t<EdgeRange>;
499 Point<std::common_type_t<
typename SegmentType::PointType::NumberType,
500 typename EdgeType::PointType::NumberType>>;
502 const CommonPoint low(segment.min());
503 const CommonPoint high(segment.max());
505 for (
const auto&
edge : edges) {
506 if (
edge.contains(low)) {
513 std::vector<std::pair<CommonPoint, CommonPoint>> overlaps;
514 for (
const auto&
edge : edges) {
518 const CommonPoint lo = (
edge.min() < low) ? low : CommonPoint(
edge.min());
519 const CommonPoint hi = (high <
edge.max()) ? high : CommonPoint(
edge.max());
523 overlaps.emplace_back(lo, hi);
525 std::sort(overlaps.begin(), overlaps.end());
527 CommonPoint covered = low;
528 for (
const auto& [lo, hi] : overlaps) {
536 return !(covered < high);
552template <
class First,
class Second>
553constexpr bool sameBoundaryPointSet(
const First& first,
const Second& second) {
554 const auto firstEdges = first.edges();
555 const auto secondEdges = second.edges();
556 for (
const auto&
edge : firstEdges) {
557 if (!segmentCoveredByEdges(
edge, secondEdges)) {
561 for (
const auto&
edge : secondEdges) {
562 if (!segmentCoveredByEdges(
edge, firstEdges)) {
583template <HalfplaneIntersectionConcept Region,
class Ring>
584constexpr bool sameConvexRegionAndRing(
const Region& region,
const Ring& ring) {
585 if (region.isDegenerate()) {
586 return reduceRegionCarrier(region, [&ring](
const auto& carrier) {
587 return samePointSetAny(carrier, ring);
590 if (collapsedBelowArea(ring) || !region.isBounded()) {
594 const std::size_t constraints = region.size();
595 if (constraints < 3) {
601 const std::size_t behind = nextRingCorner(ring, 0);
602 std::size_t start = constraints;
603 for (std::size_t i = 0; i < constraints; ++i) {
604 if (halfplaneBoundedByEdge(region[i], ring[0], ring[behind])) {
609 if (start == constraints) {
615 std::size_t here = 0;
616 for (std::size_t i = 0; i < constraints; ++i) {
617 const std::size_t next = nextRingCorner(ring, here);
618 if (!halfplaneBoundedByEdge(region[(start + i) % constraints], ring[here], ring[next])) {
633template <
class Chain>
634constexpr std::size_t nextChainCorner(
const Chain& chain, std::size_t index) {
635 const std::size_t last = chain.size() - 1;
638 }
while (index < last &&
collinear(chain[index - 1], chain[index], chain[index + 1]));
651template <MonotoneChainConcept First, MonotoneChainConcept Second>
652constexpr bool sameChainPointSet(
const First& first,
const Second& second) {
653 if (sameRepresentation(first, second)) {
656 const std::size_t firstCount = first.size();
657 const std::size_t secondCount = second.size();
658 if (!(first[0] == second[0])) {
661 if (firstCount == secondCount) {
662 std::size_t index = 1;
663 while (index < firstCount && first[index] == second[index]) {
666 if (index == firstCount) {
673 if (i + 1 == firstCount || j + 1 == secondCount) {
674 return i + 1 == firstCount && j + 1 == secondCount;
676 i = nextChainCorner(first, i);
677 j = nextChainCorner(second, j);
678 if (!(first[i] == second[j])) {
695template <
class First,
class Second>
696constexpr bool samePolylinePointSet(
const First& first,
const Second& second) {
697 if (!sameBoundingBox(first, second)) {
702 if (sameRepresentation(first, second)) {
705 if (
const auto carrier = collapsedSegment(first)) {
706 return samePointSetAny(*carrier, second);
708 if (
const auto carrier = collapsedPoint(first)) {
709 return samePointSetAny(*carrier, second);
711 if (first.size() == second.size()) {
712 const std::size_t count = first.size();
714 bool backward =
true;
715 for (std::size_t i = 0; i < count; ++i) {
716 forward = forward && first[i] == second[i];
717 backward = backward && first[i] == second[count - 1 - i];
719 if (forward || backward) {
723 return first.contains(second) && second.contains(first);
735template <Po
intConcept First, Po
intConcept Second>
736constexpr bool samePointSet(
const First& first,
const Second& second) {
737 return first == second;
741template <Po
intConcept First, SegmentConcept Second>
742constexpr bool samePointSet(
const First& first,
const Second& second) {
743 return second.min() == second.max() && first == second.min();
747template <Po
intConcept First, OrientedSegmentConcept Second>
748constexpr bool samePointSet(
const First& first,
const Second& second) {
749 return second.min() == second.max() && first == second.min();
753template <Po
intConcept First, LineConcept Second>
754constexpr bool samePointSet(
const First&,
const Second&) {
759template <Po
intConcept First, OrientedLineConcept Second>
760constexpr bool samePointSet(
const First&,
const Second&) {
765template <Po
intConcept First, RayConcept Second>
766constexpr bool samePointSet(
const First&,
const Second&) {
771template <Po
intConcept First, HalfplaneConcept Second>
772constexpr bool samePointSet(
const First&,
const Second&) {
777template <Po
intConcept First, RectangleConcept Second>
778constexpr bool samePointSet(
const First& first,
const Second& second) {
779 return collapsedMatches(second, first);
783template <Po
intConcept First, TriangleConcept Second>
784constexpr bool samePointSet(
const First& first,
const Second& second) {
785 return collapsedMatches(second, first);
789template <Po
intConcept First, DiskConcept Second>
790constexpr bool samePointSet(
const First& first,
const Second& second) {
791 return collapsedMatches(second, first);
795template <Po
intConcept First, ConvexConcept Second>
796constexpr bool samePointSet(
const First& first,
const Second& second) {
797 return collapsedMatches(second, first);
801template <Po
intConcept First, MonotoneChainConcept Second>
802constexpr bool samePointSet(
const First& first,
const Second& second) {
803 return collapsedMatches(second, first);
807template <Po
intConcept First, PolylineConcept Second>
808constexpr bool samePointSet(
const First& first,
const Second& second) {
809 return collapsedMatches(second, first);
813template <Po
intConcept First, PolygonConcept Second>
814constexpr bool samePointSet(
const First& first,
const Second& second) {
815 return collapsedMatches(second, first);
819template <Po
intConcept First, HalfplaneIntersectionConcept Second>
820constexpr bool samePointSet(
const First& first,
const Second& second) {
821 return collapsedMatches(second, first);
825template <Po
intConcept First, PolygonWithHolesConcept Second>
826constexpr bool samePointSet(
const First& first,
const Second& second) {
827 return collapsedMatches(second, first);
831template <Po
intConcept First, PolygonSetConcept Second>
832constexpr bool samePointSet(
const First& first,
const Second& second) {
833 return collapsedMatches(second, first);
844template <SegmentConcept First, SegmentConcept Second>
845constexpr bool samePointSet(
const First& first,
const Second& second) {
846 return sameSegmentPointSet(first, second);
850template <SegmentConcept First, OrientedSegmentConcept Second>
851constexpr bool samePointSet(
const First& first,
const Second& second) {
852 return sameSegmentPointSet(first, second);
856template <SegmentConcept First, LineConcept Second>
857constexpr bool samePointSet(
const First&,
const Second&) {
862template <SegmentConcept First, OrientedLineConcept Second>
863constexpr bool samePointSet(
const First&,
const Second&) {
868template <SegmentConcept First, RayConcept Second>
869constexpr bool samePointSet(
const First&,
const Second&) {
874template <SegmentConcept First, HalfplaneConcept Second>
875constexpr bool samePointSet(
const First&,
const Second&) {
880template <SegmentConcept First, RectangleConcept Second>
881constexpr bool samePointSet(
const First& first,
const Second& second) {
882 return collapsedMatches(second, first);
886template <SegmentConcept First, TriangleConcept Second>
887constexpr bool samePointSet(
const First& first,
const Second& second) {
888 return collapsedMatches(second, first);
892template <SegmentConcept First, DiskConcept Second>
893constexpr bool samePointSet(
const First& first,
const Second& second) {
894 return collapsedMatches(second, first);
898template <SegmentConcept First, ConvexConcept Second>
899constexpr bool samePointSet(
const First& first,
const Second& second) {
900 return collapsedMatches(second, first);
904template <SegmentConcept First, MonotoneChainConcept Second>
905constexpr bool samePointSet(
const First& first,
const Second& second) {
906 return collapsedMatches(second, first);
913template <SegmentConcept First, PolylineConcept Second>
914constexpr bool samePointSet(
const First& first,
const Second& second) {
915 return collapsedMatches(second, first);
919template <SegmentConcept First, PolygonConcept Second>
920constexpr bool samePointSet(
const First& first,
const Second& second) {
921 return collapsedMatches(second, first);
925template <SegmentConcept First, HalfplaneIntersectionConcept Second>
926constexpr bool samePointSet(
const First& first,
const Second& second) {
927 return collapsedMatches(second, first);
931template <SegmentConcept First, PolygonWithHolesConcept Second>
932constexpr bool samePointSet(
const First& first,
const Second& second) {
933 return collapsedMatches(second, first);
937template <SegmentConcept First, PolygonSetConcept Second>
938constexpr bool samePointSet(
const First& first,
const Second& second) {
939 return collapsedMatches(second, first);
948template <OrientedSegmentConcept First, OrientedSegmentConcept Second>
949constexpr bool samePointSet(
const First& first,
const Second& second) {
950 return sameSegmentPointSet(first, second);
954template <OrientedSegmentConcept First, LineConcept Second>
955constexpr bool samePointSet(
const First&,
const Second&) {
960template <OrientedSegmentConcept First, OrientedLineConcept Second>
961constexpr bool samePointSet(
const First&,
const Second&) {
966template <OrientedSegmentConcept First, RayConcept Second>
967constexpr bool samePointSet(
const First&,
const Second&) {
972template <OrientedSegmentConcept First, HalfplaneConcept Second>
973constexpr bool samePointSet(
const First&,
const Second&) {
978template <OrientedSegmentConcept First, RectangleConcept Second>
979constexpr bool samePointSet(
const First& first,
const Second& second) {
980 return collapsedMatches(second, first);
984template <OrientedSegmentConcept First, TriangleConcept Second>
985constexpr bool samePointSet(
const First& first,
const Second& second) {
986 return collapsedMatches(second, first);
990template <OrientedSegmentConcept First, DiskConcept Second>
991constexpr bool samePointSet(
const First& first,
const Second& second) {
992 return collapsedMatches(second, first);
996template <OrientedSegmentConcept First, ConvexConcept Second>
997constexpr bool samePointSet(
const First& first,
const Second& second) {
998 return collapsedMatches(second, first);
1002template <OrientedSegmentConcept First, MonotoneChainConcept Second>
1003constexpr bool samePointSet(
const First& first,
const Second& second) {
1004 return collapsedMatches(second, first);
1008template <OrientedSegmentConcept First, PolylineConcept Second>
1009constexpr bool samePointSet(
const First& first,
const Second& second) {
1010 return collapsedMatches(second, first);
1014template <OrientedSegmentConcept First, PolygonConcept Second>
1015constexpr bool samePointSet(
const First& first,
const Second& second) {
1016 return collapsedMatches(second, first);
1020template <OrientedSegmentConcept First, HalfplaneIntersectionConcept Second>
1021constexpr bool samePointSet(
const First& first,
const Second& second) {
1022 return collapsedMatches(second, first);
1026template <OrientedSegmentConcept First, PolygonWithHolesConcept Second>
1027constexpr bool samePointSet(
const First& first,
const Second& second) {
1028 return collapsedMatches(second, first);
1032template <OrientedSegmentConcept First, PolygonSetConcept Second>
1033constexpr bool samePointSet(
const First& first,
const Second& second) {
1034 return collapsedMatches(second, first);
1044template <LineConcept First, LineConcept Second>
1045constexpr bool samePointSet(
const First& first,
const Second& second) {
1046 return sameLinePointSet(first, second);
1050template <LineConcept First, OrientedLineConcept Second>
1051constexpr bool samePointSet(
const First& first,
const Second& second) {
1052 return sameLinePointSet(first, second);
1056template <LineConcept First, RayConcept Second>
1057constexpr bool samePointSet(
const First&,
const Second&) {
1062template <LineConcept First, HalfplaneConcept Second>
1063constexpr bool samePointSet(
const First&,
const Second&) {
1068template <LineConcept First, RectangleConcept Second>
1069constexpr bool samePointSet(
const First&,
const Second&) {
1074template <LineConcept First, TriangleConcept Second>
1075constexpr bool samePointSet(
const First&,
const Second&) {
1080template <LineConcept First, DiskConcept Second>
1081constexpr bool samePointSet(
const First&,
const Second&) {
1086template <LineConcept First, ConvexConcept Second>
1087constexpr bool samePointSet(
const First&,
const Second&) {
1092template <LineConcept First, MonotoneChainConcept Second>
1093constexpr bool samePointSet(
const First&,
const Second&) {
1098template <LineConcept First, PolylineConcept Second>
1099constexpr bool samePointSet(
const First&,
const Second&) {
1104template <LineConcept First, PolygonConcept Second>
1105constexpr bool samePointSet(
const First&,
const Second&) {
1110template <LineConcept First, HalfplaneIntersectionConcept Second>
1111constexpr bool samePointSet(
const First& first,
const Second& second) {
1112 const auto carrier = second.getIfLine();
1113 return carrier && sameLinePointSet(first, *carrier);
1117template <LineConcept First, PolygonWithHolesConcept Second>
1118constexpr bool samePointSet(
const First&,
const Second&) {
1123template <LineConcept First, PolygonSetConcept Second>
1124constexpr bool samePointSet(
const First&,
const Second&) {
1134template <OrientedLineConcept First, OrientedLineConcept Second>
1135constexpr bool samePointSet(
const First& first,
const Second& second) {
1136 return sameLinePointSet(first, second);
1140template <OrientedLineConcept First, RayConcept Second>
1141constexpr bool samePointSet(
const First&,
const Second&) {
1146template <OrientedLineConcept First, HalfplaneConcept Second>
1147constexpr bool samePointSet(
const First&,
const Second&) {
1152template <OrientedLineConcept First, RectangleConcept Second>
1153constexpr bool samePointSet(
const First&,
const Second&) {
1158template <OrientedLineConcept First, TriangleConcept Second>
1159constexpr bool samePointSet(
const First&,
const Second&) {
1164template <OrientedLineConcept First, DiskConcept Second>
1165constexpr bool samePointSet(
const First&,
const Second&) {
1170template <OrientedLineConcept First, ConvexConcept Second>
1171constexpr bool samePointSet(
const First&,
const Second&) {
1176template <OrientedLineConcept First, MonotoneChainConcept Second>
1177constexpr bool samePointSet(
const First&,
const Second&) {
1182template <OrientedLineConcept First, PolylineConcept Second>
1183constexpr bool samePointSet(
const First&,
const Second&) {
1188template <OrientedLineConcept First, PolygonConcept Second>
1189constexpr bool samePointSet(
const First&,
const Second&) {
1194template <OrientedLineConcept First, HalfplaneIntersectionConcept Second>
1195constexpr bool samePointSet(
const First& first,
const Second& second) {
1196 const auto carrier = second.getIfLine();
1197 return carrier && sameLinePointSet(first, *carrier);
1201template <OrientedLineConcept First, PolygonWithHolesConcept Second>
1202constexpr bool samePointSet(
const First&,
const Second&) {
1207template <OrientedLineConcept First, PolygonSetConcept Second>
1208constexpr bool samePointSet(
const First&,
const Second&) {
1218template <RayConcept First, RayConcept Second>
1219constexpr bool samePointSet(
const First& first,
const Second& second) {
1220 return sameRayPointSet(first, second);
1224template <RayConcept First, HalfplaneConcept Second>
1225constexpr bool samePointSet(
const First&,
const Second&) {
1230template <RayConcept First, RectangleConcept Second>
1231constexpr bool samePointSet(
const First&,
const Second&) {
1236template <RayConcept First, TriangleConcept Second>
1237constexpr bool samePointSet(
const First&,
const Second&) {
1242template <RayConcept First, DiskConcept Second>
1243constexpr bool samePointSet(
const First&,
const Second&) {
1248template <RayConcept First, ConvexConcept Second>
1249constexpr bool samePointSet(
const First&,
const Second&) {
1254template <RayConcept First, MonotoneChainConcept Second>
1255constexpr bool samePointSet(
const First&,
const Second&) {
1260template <RayConcept First, PolylineConcept Second>
1261constexpr bool samePointSet(
const First&,
const Second&) {
1266template <RayConcept First, PolygonConcept Second>
1267constexpr bool samePointSet(
const First&,
const Second&) {
1272template <RayConcept First, HalfplaneIntersectionConcept Second>
1273constexpr bool samePointSet(
const First& first,
const Second& second) {
1274 const auto carrier = second.getIfRay();
1275 return carrier && sameRayPointSet(first, *carrier);
1279template <RayConcept First, PolygonWithHolesConcept Second>
1280constexpr bool samePointSet(
const First&,
const Second&) {
1285template <RayConcept First, PolygonSetConcept Second>
1286constexpr bool samePointSet(
const First&,
const Second&) {
1297template <HalfplaneConcept First, HalfplaneConcept Second>
1298constexpr bool samePointSet(
const First& first,
const Second& second) {
1299 return sameHalfplanePointSet(first, second);
1303template <HalfplaneConcept First, RectangleConcept Second>
1304constexpr bool samePointSet(
const First&,
const Second&) {
1309template <HalfplaneConcept First, TriangleConcept Second>
1310constexpr bool samePointSet(
const First&,
const Second&) {
1315template <HalfplaneConcept First, DiskConcept Second>
1316constexpr bool samePointSet(
const First&,
const Second&) {
1321template <HalfplaneConcept First, ConvexConcept Second>
1322constexpr bool samePointSet(
const First&,
const Second&) {
1327template <HalfplaneConcept First, MonotoneChainConcept Second>
1328constexpr bool samePointSet(
const First&,
const Second&) {
1333template <HalfplaneConcept First, PolylineConcept Second>
1334constexpr bool samePointSet(
const First&,
const Second&) {
1339template <HalfplaneConcept First, PolygonConcept Second>
1340constexpr bool samePointSet(
const First&,
const Second&) {
1349template <HalfplaneConcept First, HalfplaneIntersectionConcept Second>
1350constexpr bool samePointSet(
const First& first,
const Second& second) {
1351 const auto carrier = second.getIfHalfplane();
1352 return carrier && sameHalfplanePointSet(first, *carrier);
1356template <HalfplaneConcept First, PolygonWithHolesConcept Second>
1357constexpr bool samePointSet(
const First&,
const Second&) {
1362template <HalfplaneConcept First, PolygonSetConcept Second>
1363constexpr bool samePointSet(
const First&,
const Second&) {
1374template <RectangleConcept First, RectangleConcept Second>
1375constexpr bool samePointSet(
const First& first,
const Second& second) {
1376 return first.min() == second.min() && first.max() == second.max();
1383template <RectangleConcept First, TriangleConcept Second>
1384constexpr bool samePointSet(
const First& first,
const Second& second) {
1385 return collapsedMatches(first, second);
1389template <RectangleConcept First, DiskConcept Second>
1390constexpr bool samePointSet(
const First& first,
const Second& second) {
1391 return collapsedMatches(second, first);
1395template <RectangleConcept First, ConvexConcept Second>
1396constexpr bool samePointSet(
const First& first,
const Second& second) {
1397 return sameRingShapes(first, second);
1401template <RectangleConcept First, MonotoneChainConcept Second>
1402constexpr bool samePointSet(
const First& first,
const Second& second) {
1403 return collapsedMatches(first, second);
1407template <RectangleConcept First, PolylineConcept Second>
1408constexpr bool samePointSet(
const First& first,
const Second& second) {
1409 return collapsedMatches(first, second);
1413template <RectangleConcept First, PolygonConcept Second>
1414constexpr bool samePointSet(
const First& first,
const Second& second) {
1415 return sameRingShapes(first, second);
1419template <RectangleConcept First, HalfplaneIntersectionConcept Second>
1420constexpr bool samePointSet(
const First& first,
const Second& second) {
1421 return sameConvexRegionAndRing(second, first);
1428template <RectangleConcept First, PolygonWithHolesConcept Second>
1429constexpr bool samePointSet(
const First& first,
const Second& second) {
1430 if (second.hasHoles()) {
1433 return sameRingShapes(first, second.outer());
1440template <RectangleConcept First, PolygonSetConcept Second>
1441constexpr bool samePointSet(
const First& first,
const Second& second) {
1442 if (second.componentCount() != 1) {
1445 return samePointSetAny(first, second.component(0));
1457template <TriangleConcept First, TriangleConcept Second>
1458constexpr bool samePointSet(
const First& first,
const Second& second) {
1459 if (first.isDegenerate() || second.isDegenerate()) {
1460 return sameRingShapes(first, second);
1462 return first[0] == second[0] && first[1] == second[1] && first[2] == second[2];
1466template <TriangleConcept First, DiskConcept Second>
1467constexpr bool samePointSet(
const First& first,
const Second& second) {
1468 return collapsedMatches(second, first);
1472template <TriangleConcept First, ConvexConcept Second>
1473constexpr bool samePointSet(
const First& first,
const Second& second) {
1474 return sameRingShapes(first, second);
1478template <TriangleConcept First, MonotoneChainConcept Second>
1479constexpr bool samePointSet(
const First& first,
const Second& second) {
1480 return collapsedMatches(first, second);
1484template <TriangleConcept First, PolylineConcept Second>
1485constexpr bool samePointSet(
const First& first,
const Second& second) {
1486 return collapsedMatches(first, second);
1490template <TriangleConcept First, PolygonConcept Second>
1491constexpr bool samePointSet(
const First& first,
const Second& second) {
1492 return sameRingShapes(first, second);
1496template <TriangleConcept First, HalfplaneIntersectionConcept Second>
1497constexpr bool samePointSet(
const First& first,
const Second& second) {
1498 return sameConvexRegionAndRing(second, first);
1502template <TriangleConcept First, PolygonWithHolesConcept Second>
1503constexpr bool samePointSet(
const First& first,
const Second& second) {
1504 if (second.hasHoles()) {
1507 return sameRingShapes(first, second.outer());
1511template <TriangleConcept First, PolygonSetConcept Second>
1512constexpr bool samePointSet(
const First& first,
const Second& second) {
1513 if (second.componentCount() != 1) {
1516 return samePointSetAny(first, second.component(0));
1529template <DiskConcept First, DiskConcept Second>
1530constexpr bool samePointSet(
const First& first,
const Second& second) {
1531 if (first.isPoint() || second.isPoint()) {
1532 return first.isPoint() && second.isPoint() && first.a() == second.a();
1534 return inCircleSign(first.a(), first.b(), first.c(), second.a()) == 0 &&
1535 inCircleSign(first.a(), first.b(), first.c(), second.b()) == 0 &&
1536 inCircleSign(first.a(), first.b(), first.c(), second.c()) == 0;
1540template <DiskConcept First, ConvexConcept Second>
1541constexpr bool samePointSet(
const First& first,
const Second& second) {
1542 return collapsedMatches(first, second);
1546template <DiskConcept First, MonotoneChainConcept Second>
1547constexpr bool samePointSet(
const First& first,
const Second& second) {
1548 return collapsedMatches(first, second);
1552template <DiskConcept First, PolylineConcept Second>
1553constexpr bool samePointSet(
const First& first,
const Second& second) {
1554 return collapsedMatches(first, second);
1558template <DiskConcept First, PolygonConcept Second>
1559constexpr bool samePointSet(
const First& first,
const Second& second) {
1560 return collapsedMatches(first, second);
1564template <DiskConcept First, HalfplaneIntersectionConcept Second>
1565constexpr bool samePointSet(
const First& first,
const Second& second) {
1566 return collapsedMatches(first, second);
1570template <DiskConcept First, PolygonWithHolesConcept Second>
1571constexpr bool samePointSet(
const First& first,
const Second& second) {
1572 return collapsedMatches(first, second);
1576template <DiskConcept First, PolygonSetConcept Second>
1577constexpr bool samePointSet(
const First& first,
const Second& second) {
1578 return collapsedMatches(first, second);
1588template <ConvexConcept First, ConvexConcept Second>
1589constexpr bool samePointSet(
const First& first,
const Second& second) {
1590 return sameRingShapes(first, second);
1594template <ConvexConcept First, MonotoneChainConcept Second>
1595constexpr bool samePointSet(
const First& first,
const Second& second) {
1596 return collapsedMatches(first, second);
1600template <ConvexConcept First, PolylineConcept Second>
1601constexpr bool samePointSet(
const First& first,
const Second& second) {
1602 return collapsedMatches(first, second);
1606template <ConvexConcept First, PolygonConcept Second>
1607constexpr bool samePointSet(
const First& first,
const Second& second) {
1608 return sameRingShapes(first, second);
1612template <ConvexConcept First, HalfplaneIntersectionConcept Second>
1613constexpr bool samePointSet(
const First& first,
const Second& second) {
1614 return sameConvexRegionAndRing(second, first);
1618template <ConvexConcept First, PolygonWithHolesConcept Second>
1619constexpr bool samePointSet(
const First& first,
const Second& second) {
1620 if (second.hasHoles()) {
1623 return sameRingShapes(first, second.outer());
1627template <ConvexConcept First, PolygonSetConcept Second>
1628constexpr bool samePointSet(
const First& first,
const Second& second) {
1629 if (second.componentCount() != 1) {
1632 return samePointSetAny(first, second.component(0));
1642template <MonotoneChainConcept First, MonotoneChainConcept Second>
1643constexpr bool samePointSet(
const First& first,
const Second& second) {
1644 return sameChainPointSet(first, second);
1648template <MonotoneChainConcept First, PolylineConcept Second>
1649constexpr bool samePointSet(
const First& first,
const Second& second) {
1650 return samePolylinePointSet(second, first);
1654template <MonotoneChainConcept First, PolygonConcept Second>
1655constexpr bool samePointSet(
const First& first,
const Second& second) {
1656 return collapsedMatches(second, first);
1660template <MonotoneChainConcept First, HalfplaneIntersectionConcept Second>
1661constexpr bool samePointSet(
const First& first,
const Second& second) {
1662 return collapsedMatches(second, first);
1666template <MonotoneChainConcept First, PolygonWithHolesConcept Second>
1667constexpr bool samePointSet(
const First& first,
const Second& second) {
1668 return collapsedMatches(second, first);
1672template <MonotoneChainConcept First, PolygonSetConcept Second>
1673constexpr bool samePointSet(
const First& first,
const Second& second) {
1674 return collapsedMatches(second, first);
1684template <PolylineConcept First, PolylineConcept Second>
1685constexpr bool samePointSet(
const First& first,
const Second& second) {
1686 return samePolylinePointSet(first, second);
1690template <PolylineConcept First, PolygonConcept Second>
1691constexpr bool samePointSet(
const First& first,
const Second& second) {
1692 return collapsedMatches(second, first);
1696template <PolylineConcept First, HalfplaneIntersectionConcept Second>
1697constexpr bool samePointSet(
const First& first,
const Second& second) {
1698 return collapsedMatches(second, first);
1702template <PolylineConcept First, PolygonWithHolesConcept Second>
1703constexpr bool samePointSet(
const First& first,
const Second& second) {
1704 return collapsedMatches(second, first);
1708template <PolylineConcept First, PolygonSetConcept Second>
1709constexpr bool samePointSet(
const First& first,
const Second& second) {
1710 return collapsedMatches(second, first);
1719template <PolygonConcept First, PolygonConcept Second>
1720constexpr bool samePointSet(
const First& first,
const Second& second) {
1721 return sameRingShapes(first, second);
1728template <PolygonConcept First, HalfplaneIntersectionConcept Second>
1729constexpr bool samePointSet(
const First& first,
const Second& second) {
1730 return sameConvexRegionAndRing(second, first);
1734template <PolygonConcept First, PolygonWithHolesConcept Second>
1735constexpr bool samePointSet(
const First& first,
const Second& second) {
1736 if (second.hasHoles()) {
1739 return sameRingShapes(first, second.outer());
1743template <PolygonConcept First, PolygonSetConcept Second>
1744constexpr bool samePointSet(
const First& first,
const Second& second) {
1745 if (second.componentCount() != 1) {
1748 return samePointSetAny(first, second.component(0));
1763template <HalfplaneIntersectionConcept First, HalfplaneIntersectionConcept Second>
1764constexpr bool samePointSet(
const First& first,
const Second& second) {
1765 if (first.isDegenerate() || second.isDegenerate()) {
1766 return reduceRegionCarrier(first, [&second](
const auto& carrier) {
1767 return samePointSetAny(carrier, second);
1770 if (first.size() != second.size()) {
1773 for (std::size_t i = 0; i < first.size(); ++i) {
1774 if (!sameHalfplanePointSet(first[i], second[i])) {
1786template <HalfplaneIntersectionConcept First, PolygonWithHolesConcept Second>
1787constexpr bool samePointSet(
const First& first,
const Second& second) {
1788 if (second.hasHoles()) {
1791 return sameConvexRegionAndRing(first, second.outer());
1795template <HalfplaneIntersectionConcept First, PolygonSetConcept Second>
1796constexpr bool samePointSet(
const First& first,
const Second& second) {
1797 if (second.componentCount() != 1) {
1800 return samePointSetAny(first, second.component(0));
1810template <PolygonWithHolesConcept First, PolygonWithHolesConcept Second>
1811constexpr bool samePointSet(
const First& first,
const Second& second) {
1812 if (sameRepresentation(first, second)) {
1815 if (!sameBoundingBox(first, second) || !(first.outer()[0] == second.outer()[0])) {
1820 if (collapsedBelowArea(first)) {
1821 return collapsedMatches(first, second);
1823 if (collapsedBelowArea(second)) {
1824 return collapsedMatches(second, first);
1826 return sameRegionRings(first, second);
1839template <PolygonWithHolesConcept First, PolygonSetConcept Second>
1840constexpr bool samePointSet(
const First& first,
const Second& second) {
1841 if (second.componentCount() == 1) {
1842 return samePointSetAny(first, second.component(0));
1844 if (collapsedBelowArea(first)) {
1847 return sameBoundingBox(first, second) && sameBoundaryPointSet(first, second);
1866template <PolygonSetConcept First, PolygonSetConcept Second>
1867constexpr bool samePointSet(
const First& first,
const Second& second) {
1868 if (sameRepresentation(first, second)) {
1871 if (first.componentCount() == second.componentCount() &&
1872 sameRingCollection(first.components(), second.components(),
1873 [](
const auto& one,
const auto& other) {
1874 return sameRegionRings(one, other);
1878 if (collapsedBelowArea(first) || collapsedBelowArea(second)) {
1879 return collapsedMatches(first, second) || collapsedMatches(second, first);
1881 return sameBoundingBox(first, second) && sameBoundaryPointSet(first, second);
1902template <AnyShapeConcept First, AnyShapeConcept Second>
1903constexpr bool samePointSetAny(
const First& first,
const Second& second) {
1904 if constexpr (ShapeConcept<First>) {
1906 [&second](
const auto& value) {
return samePointSetAny(value, second); },
1908 }
else if constexpr (ShapeConcept<Second>) {
1910 [&first](
const auto& value) {
return samePointSetAny(first, value); },
1912 }
else if constexpr (EmptyShapeConcept<First> || EmptyShapeConcept<Second>) {
1913 return coversNoPoint(first) && coversNoPoint(second);
1915 const bool firstEmpty = coversNoPoint(first);
1916 const bool secondEmpty = coversNoPoint(second);
1917 if (firstEmpty || secondEmpty) {
1918 return firstEmpty && secondEmpty;
1920 if constexpr (shapeRank<std::remove_cvref_t<First>> >
1921 shapeRank<std::remove_cvref_t<Second>>) {
1922 return samePointSet(second, first);
1924 return samePointSet(first, second);
1933template <
class Number,
class Label>
1934template <AnyShapeConcept OtherShape>
1936 return detail::samePointSetAny(*
this, other);