24template <
class Container>
25using min_disk_input_point_t =
26 std::remove_cvref_t<decltype(*std::begin(std::declval<const Container&>()))>;
28template <
class Container>
29using min_disk_result_t =
30 Disk<Point<typename min_disk_input_point_t<Container>::NumberType>>;
32template <Po
intConcept Po
intType>
33[[nodiscard]]
constexpr Disk<PointType> pointDisk(
const PointType& point) {
43template <Po
intConcept Po
intType>
44[[nodiscard]]
constexpr Disk<PointType> diameterDisk(
const PointType& first,
45 const PointType& second) {
46 using Number =
typename PointType::NumberType;
47 const Number two =
static_cast<Number
>(2);
48 const PointType midpoint((first.x() + second.x()) / two,
49 (first.y() + second.y()) / two);
50 const PointType radius((second.x() - first.x()) / two,
51 (second.y() - first.y()) / two);
52 const PointType third(midpoint.x() - radius.y(), midpoint.y() + radius.x());
65template <Po
intConcept Po
intType>
66[[nodiscard]]
constexpr Disk<PointType> threePointDisk(
const PointType& first,
67 const PointType& second,
68 const PointType& third) {
73 const auto firstSecond = first.template squaredDistance<typename PointType::NumberType>(second);
74 const auto secondThird = second.template squaredDistance<typename PointType::NumberType>(third);
75 const auto thirdFirst = third.template squaredDistance<typename PointType::NumberType>(first);
76 if (firstSecond >= secondThird && firstSecond >= thirdFirst) {
77 return diameterDisk(first, second);
79 if (secondThird >= thirdFirst) {
80 return diameterDisk(second, third);
82 return diameterDisk(third, first);
113template <
class Container,
class UniformRandomBitGenerator>
114[[nodiscard]] detail::min_disk_result_t<Container>
116 using InputPoint = detail::min_disk_input_point_t<Container>;
118 "smallestEnclosingDisk requires a container of pgl::Point values");
119 using ResultNumber =
typename InputPoint::NumberType;
123 std::vector<ResultPoint> points;
124 for (
const auto& point : input) {
125 points.emplace_back(point);
127 assert(!points.empty());
128 std::shuffle(points.begin(), points.end(),
129 std::forward<UniformRandomBitGenerator>(generator));
131 ResultDisk disk = detail::pointDisk(points.front());
132 for (std::size_t i = 1; i < points.size(); ++i) {
133 if (disk.contains(points[i])) {
137 disk = detail::pointDisk(points[i]);
138 for (std::size_t j = 0; j < i; ++j) {
139 if (disk.contains(points[j])) {
143 disk = detail::diameterDisk(points[i], points[j]);
144 for (std::size_t k = 0; k < j; ++k) {
145 if (!disk.contains(points[k])) {
146 disk = detail::threePointDisk(points[i], points[j], points[k]);
165template <
class Container>
166[[nodiscard]] detail::min_disk_result_t<Container>
172 std::mt19937 generator(0x50474cU);
179template <
class Po
intType,
class LabelType>
180template <
class UniformRandomBitGenerator>
181Disk<Point<typename Convex<PointType, LabelType>::NumberType>>
183 UniformRandomBitGenerator&& generator)
const {
187 *
this, std::forward<UniformRandomBitGenerator>(generator));
190template <
class Po
intType,
class LabelType>
Definition forward.hpp:306
Convex hull algorithms built from Pangolin point predicates.
Definition arrangement.hpp:67
constexpr std::partial_ordering orientationSign(const Point< ANumber, ALabel > &a, const Point< BNumber, BLabel > &b, const Point< CNumber, CLabel > &c)
Classifies the orientation of three points.
Definition orientation.hpp:544
detail::min_disk_result_t< Container > smallestEnclosingDisk(const Container &input, UniformRandomBitGenerator &&generator)
Computes the smallest closed disk containing a set of points.
Definition mindisk.hpp:115
Disk() -> Disk< Point<>, NoLabel >
Deduces a default disk with Point<> boundary points and no label.
Definition disk.hpp:1691
constexpr bool empty() const
Definition convex.hpp:390
Disk< Point< NumberType > > smallestEnclosingDisk() const
Returns the smallest closed disk containing the convex polygon.
Definition mindisk.hpp:192
Closed Euclidean disk stored by boundary points plus optional disk label.
Definition disk.hpp:66
Two-dimensional point with optional label payload.
Definition point.hpp:129