diff --git a/Siv3D/include/Siv3D/Math.hpp b/Siv3D/include/Siv3D/Math.hpp index 5c065c87d..bc6ab52c4 100644 --- a/Siv3D/include/Siv3D/Math.hpp +++ b/Siv3D/include/Siv3D/Math.hpp @@ -1321,6 +1321,28 @@ namespace s3d [[nodiscard]] inline constexpr Vec4 Smoothstep(Vec4 v) noexcept; + ////////////////////////////////////////////////// + // + // ClampAngle + // + ////////////////////////////////////////////////// + + /// @brief 最小値と最大値の範囲にクランプした角度を返します。 + /// @param angle クランプする角度 + /// @param min 範囲の最小値 + /// @param max 範囲の最大値 + /// @return クランプした角度 + /// @remark angle が範囲外である場合、角度を円環的に解釈して min または max のうちより近い方の値に調整します。 + [[nodiscard]] + inline float ClampAngle(float angle, float min, float max) noexcept; + + [[nodiscard]] + inline double ClampAngle(double angle, double min, double max) noexcept; + + SIV3D_CONCEPT_ARITHMETIC + [[nodiscard]] + inline double ClampAngle(Arithmetic angle, Arithmetic min, Arithmetic max) noexcept; + ////////////////////////////////////////////////// // // NormalizeAngle diff --git a/Siv3D/include/Siv3D/detail/Math.ipp b/Siv3D/include/Siv3D/detail/Math.ipp index 7aaf15eac..3e4f7a1f4 100644 --- a/Siv3D/include/Siv3D/detail/Math.ipp +++ b/Siv3D/include/Siv3D/detail/Math.ipp @@ -1354,6 +1354,34 @@ namespace s3d SIV3D_MATH_FUNCTION_CONSTEXPR_X(Smoothstep) + ////////////////////////////////////////////////// + // + // ClampAngle + // + ////////////////////////////////////////////////// + + inline float ClampAngle(const float angle, const float min, float max) noexcept + { + const auto start = (min + max) * 0.5f - TwoPiF; + const auto floor = Floor((angle - start) / TwoPiF) * TwoPiF; + return Clamp(angle, min + floor, max + floor); + } + + inline double ClampAngle(const double angle, const double min, double max) noexcept + { + const auto start = (min + max) * 0.5 - TwoPi; + const auto floor = Floor((angle - start) / TwoPi) * TwoPi; + return Clamp(angle, min + floor, max + floor); + } + + SIV3D_CONCEPT_ARITHMETIC_ + inline double ClampAngle(Arithmetic angle, Arithmetic min, Arithmetic max) noexcept + { + const auto start = (min + max) * 0.5 - TwoPi; + const auto floor = Floor((angle - start) / TwoPi) * TwoPi; + return Clamp(angle, min + floor, max + floor); + } + ////////////////////////////////////////////////// // // NormalizeAngle