25 { v.position } -> std::convertible_to<glm::vec3>;
42template <PositionCarrying T>
43[[nodiscard]] glm::vec3
centroid(std::span<T> pts)
noexcept
46 return glm::vec3(0.0F);
48 for (
const auto& p : pts)
49 acc +=
static_cast<glm::vec3
>(p.position);
50 return acc /
static_cast<float>(pts.size());
68template <PositionCarrying T, std::invocable<const T&> WeightFn>
69 requires std::convertible_to<std::invoke_result_t<WeightFn, const T&>,
float>
73 return glm::vec3(0.0F);
76 for (
const auto& p : pts) {
77 const auto w =
static_cast<float>(std::invoke(
weight, p));
78 acc +=
static_cast<glm::vec3
>(p.position) * w;
81 return total > 0.0F ? acc / total : glm::vec3(0.0F);
103 std::invocable<const T&> PosFn,
104 std::invocable<const T&> WeightFn>
105 requires std::convertible_to<std::invoke_result_t<PosFn, const T&>, glm::vec3>
106 && std::convertible_to<std::invoke_result_t<WeightFn, const T&>,
float>
107[[nodiscard]] glm::vec3
centroid(std::span<T> pts, PosFn pos, WeightFn
weight)
noexcept
110 return glm::vec3(0.0F);
113 for (
const auto& p : pts) {
114 const auto w =
static_cast<float>(std::invoke(
weight, p));
115 acc +=
static_cast<glm::vec3
>(std::invoke(pos, p)) * w;
118 return total > 0.0F ? acc / total : glm::vec3(0.0F);
135template <PositionCarrying T>
139 return AABB3D { .
min = glm::vec3(0.0F), .max = glm::vec3(0.0F) };
140 constexpr float inf = std::numeric_limits<float>::max();
141 AABB3D box { .
min = glm::vec3(inf), .max = glm::vec3(-inf) };
142 for (
const auto& p : pts) {
143 const glm::vec3
q =
static_cast<glm::vec3
>(p.position);
144 box.min = glm::min(box.min,
q);
145 box.max = glm::max(box.max,
q);
Satisfied by any type exposing a position field convertible to glm::vec3.
glm::vec3 centroid(std::span< T > pts) noexcept
Arithmetic centroid (uniform weight) of a PositionCarrying span.
AABB3D aabb(std::span< T > pts) noexcept
Axis-aligned bounding box of a PositionCarrying span.
Axis-aligned bounding box in 3D world space.