bwidgets/inc/basic_widgets/core/math.hpp

92 lines
3.0 KiB
C++

#ifndef BWIDGETS_MATH_HPP
#define BWIDGETS_MATH_HPP
#include <algorithm>
#include <cmath>
#include <SDL2/SDL_rect.h>
#include <basic_widgets/core/type/color.hpp>
#include <basic_widgets/core/type/concepts.hpp>
#include <basic_widgets/core/type/size.hpp>
namespace bwidgets
{
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
[[nodiscard]] static inline auto center_line(int available_len, int used_len) noexcept -> int
{
return (available_len - used_len) / 2;
}
[[nodiscard]] static inline auto distance_sqrd(const SDL_Point& a, const SDL_Point& b) noexcept
-> float
{
// NOLINTNEXTLINE(bugprone-narrowing-conversions)
return (a.x - b.x) * (a.x - b.x)
+ (a.y - b.y) * (a.y - b.y);
}
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
[[nodiscard]] static inline auto distance(const SDL_Point& a, const SDL_Point& b) noexcept -> float
{
return std::sqrt(distance_sqrd(a, b));
}
template<FloatingPoint F>
[[nodiscard]] static inline auto lerp(const Color& a, const Color& b, F x, bool op_alpha=false, bool op_color=true) -> Color
{
return {{
op_color ? (uint8_t)std::lerp(a().r, b().r, x) : a().r,
op_color ? (uint8_t)std::lerp(a().g, b().g, x) : a().g,
op_color ? (uint8_t)std::lerp(a().b, b().b, x) : a().b,
op_alpha ? (uint8_t)std::lerp(a().a, b().a, x) : a().a,
}};
}
template<Numeric N>
[[nodiscard]] static inline auto linear(N x, N a, N b) noexcept -> float
{
return (float)(x - a) / (float)(b - a);
}
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
[[nodiscard]] static inline auto rect_in_rect(const SDL_Rect outer, const SDL_Rect inner) noexcept
-> bool
{
SDL_Point top_left {inner.x, inner.y};
SDL_Point bottom_right {inner.x + inner.w, inner.y + inner.h};
return (SDL_PointInRect(&top_left, &outer) == SDL_TRUE)
&& (SDL_PointInRect(&bottom_right, &outer) == SDL_TRUE);
}
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
[[nodiscard]] static inline auto rect_margin(const SDL_Rect& r, const Size& margin) noexcept
-> SDL_Rect
{
return {r.x + margin.w, r.y + margin.h, r.w - 2 * margin.w, r.h - 2 * margin.h};
}
[[nodiscard]] static inline auto rect_offset(const SDL_Rect& r, const SDL_Point& offset) noexcept
-> SDL_Rect
{
return {r.x + offset.x, r.y + offset.y, r.w, r.h};
}
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
[[nodiscard]] static inline auto rect_offset(const SDL_Rect& r, const SDL_Rect& offset) noexcept
-> SDL_Rect
{
return rect_offset(r, SDL_Point {offset.x, offset.y});
}
template<Numeric N>
[[nodiscard]] static inline auto smoothstep(N x, N a, N b) noexcept -> float
{
const float x_norm = linear(std::clamp<float>(x, a, b), a, b);
return 3 * x_norm * x_norm - 2 * x_norm * x_norm * x_norm;
}
}
#endif