From 3e75d32f5925093f2b5521442754f014f836d710 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 29 Mar 2025 04:00:35 +0300 Subject: [PATCH 1/2] fixed style --- include/omath/color.hpp | 192 +++++++++++++++++------------- tests/general/unit_test_color.cpp | 8 +- 2 files changed, 110 insertions(+), 90 deletions(-) diff --git a/include/omath/color.hpp b/include/omath/color.hpp index 3734f37..bafefc3 100644 --- a/include/omath/color.hpp +++ b/include/omath/color.hpp @@ -12,111 +12,131 @@ namespace omath { struct HSV { - float m_hue{}; - float m_saturation{}; - float m_value{}; + float hue{}; + float saturation{}; + float value{}; }; class Color final : public Vector4 { - public: - constexpr Color(const float r, const float g, const float b, const float a) : Vector4(r,g,b,a) + public: + constexpr Color(const float r, const float g, const float b, const float a) : Vector4(r, g, b, a) + { + Clamp(0.f, 1.f); + } + + constexpr explicit Color() = default; + [[nodiscard]] + constexpr static Color FromRGBA(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) + { + return Color{Vector4(r, g, b, a) / 255.f}; + } + + [[nodiscard]] + constexpr static Color FromHSV(float hue, const float saturation, const float value) + { + float r{}, g{}, b{}; + + hue = std::clamp(hue, 0.f, 1.f); + + const int i = static_cast(hue * 6.f); + const float f = hue * 6 - i; + const float p = value * (1 - saturation); + const float q = value * (1 - f * saturation); + const float t = value * (1 - (1 - f) * saturation); + + switch (i % 6) { - Clamp(0.f, 1.f); + case 0: + r = value, g = t, b = p; + break; + case 1: + r = q, g = value, b = p; + break; + case 2: + r = p, g = value, b = t; + break; + case 3: + r = p, g = q, b = value; + break; + case 4: + r = t, g = p, b = value; + break; + case 5: + r = value, g = p, b = q; + break; + + default: + return {0.f, 0.f, 0.f, 0.f}; } - constexpr explicit Color() : Vector4() - { + return {r, g, b, 1.f}; + } - } - [[nodiscard]] - constexpr static Color FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) - { - return Color{Vector4(r, g, b, a) / 255.f}; - } + [[nodiscard]] + constexpr static Color FromHSV(const HSV& hsv) + { + return FromHSV(hsv.hue, hsv.saturation, hsv.value); + } - [[nodiscard]] - constexpr static Color FromHSV(float hue, float saturation, float value) - { - float r{}, g{}, b{}; + [[nodiscard]] + constexpr HSV ToHSV() const + { + HSV hsvData; - hue = std::clamp(hue, 0.f, 1.f); + const float& red = x; + const float& green = y; + const float& blue = z; - const int i = static_cast(hue * 6.f); - const float f = hue * 6 - i; - const float p = value * (1 - saturation); - const float q = value * (1 - f * saturation); - const float t = value * (1 - (1 - f) * saturation); - - switch (i % 6) - { - case 0: r = value, g = t, b = p; break; - case 1: r = q, g = value, b = p; break; - case 2: r = p, g = value, b = t; break; - case 3: r = p, g = q, b = value; break; - case 4: r = t, g = p, b = value; break; - case 5: r = value, g = p, b = q; break; - - default: return {0.f, 0.f, 0.f, 0.f}; - } - - return {r, g, b, 1.f}; - } - - [[nodiscard]] - constexpr HSV ToHSV() const - { - HSV hsvData; - - const float& red = x; - const float& green = y; - const float& blue = z; - - const float max = std::max({red, green, blue}); - const float min = std::min({red, green, blue}); - const float delta = max - min; + const float max = std::max({red, green, blue}); + const float min = std::min({red, green, blue}); + const float delta = max - min; - if (delta == 0.f) - hsvData.m_hue = 0.f; + if (delta == 0.f) + hsvData.hue = 0.f; - else if (max == red) - hsvData.m_hue = 60.f * (std::fmodf(((green - blue) / delta), 6.f)); - else if (max == green) - hsvData.m_hue = 60.f * (((blue - red) / delta) + 2.f); - else if (max == blue) - hsvData.m_hue = 60.f * (((red - green) / delta) + 4.f); + else if (max == red) + hsvData.hue = 60.f * (std::fmodf(((green - blue) / delta), 6.f)); + else if (max == green) + hsvData.hue = 60.f * (((blue - red) / delta) + 2.f); + else if (max == blue) + hsvData.hue = 60.f * (((red - green) / delta) + 4.f); - if (hsvData.m_hue < 0.f) - hsvData.m_hue += 360.f; + if (hsvData.hue < 0.f) + hsvData.hue += 360.f; - hsvData.m_hue /= 360.f; - hsvData.m_saturation = max == 0.f ? 0.f : delta / max; - hsvData.m_value = max; + hsvData.hue /= 360.f; + hsvData.saturation = max == 0.f ? 0.f : delta / max; + hsvData.value = max; - return hsvData; - } + return hsvData; + } - constexpr explicit Color(const Vector4& vec) : Vector4(vec) - { - Clamp(0.f, 1.f); - } + constexpr explicit Color(const Vector4& vec) : Vector4(vec) + { + Clamp(0.f, 1.f); + } - [[nodiscard]] - constexpr Color Blend(const Color& other, float ratio) const - { - return Color( (*this * (1.f - ratio)) + (other * ratio) ); - } + [[nodiscard]] + constexpr Color Blend(const Color& other, float ratio) const + { + ratio = std::clamp(ratio, 0.f, 1.f); + return Color(*this * (1.f - ratio) + other * ratio); + } - [[nodiscard]] static constexpr Color Red() {return {1.f, 0.f, 0.f, 1.f};} - [[nodiscard]] static constexpr Color Green() {return {0.f, 1.f, 0.f, 1.f};} - [[nodiscard]] static constexpr Color Blue() {return {0.f, 0.f, 1.f, 1.f};} + [[nodiscard]] static constexpr Color Red() + { + return {1.f, 0.f, 0.f, 1.f}; + } + [[nodiscard]] static constexpr Color Green() + { + return {0.f, 1.f, 0.f, 1.f}; + } + [[nodiscard]] static constexpr Color Blue() + { + return {0.f, 0.f, 1.f, 1.f}; + } }; - - [[nodiscard]] - constexpr Color Blend(const Color& first, const Color& second, float ratio) - { - return Color{first * (1.f - std::clamp(ratio, 0.f, 1.f)) + second * ratio}; - } -} \ No newline at end of file +} // namespace omath diff --git a/tests/general/unit_test_color.cpp b/tests/general/unit_test_color.cpp index 0120862..77aeaf3 100644 --- a/tests/general/unit_test_color.cpp +++ b/tests/general/unit_test_color.cpp @@ -63,9 +63,9 @@ TEST_F(UnitTestColor, FromHSV) TEST_F(UnitTestColor, ToHSV) { HSV hsv = color1.ToHSV(); // Red color - EXPECT_FLOAT_EQ(hsv.m_hue, 0.0f); - EXPECT_FLOAT_EQ(hsv.m_saturation, 1.0f); - EXPECT_FLOAT_EQ(hsv.m_value, 1.0f); + EXPECT_FLOAT_EQ(hsv.hue, 0.0f); + EXPECT_FLOAT_EQ(hsv.saturation, 1.0f); + EXPECT_FLOAT_EQ(hsv.value, 1.0f); } // Test color blending @@ -106,7 +106,7 @@ TEST_F(UnitTestColor, BlendVector3) { constexpr Color v1(1.0f, 0.0f, 0.0f, 1.f); // Red constexpr Color v2(0.0f, 1.0f, 0.0f, 1.f); // Green - constexpr Color blended = Blend(v1, v2, 0.5f); + constexpr Color blended = v1.Blend(v2, 0.5f); EXPECT_FLOAT_EQ(blended.x, 0.5f); EXPECT_FLOAT_EQ(blended.y, 0.5f); EXPECT_FLOAT_EQ(blended.z, 0.0f); From d72ad663cd9f8c96d4440a8dca71fc7592a4bade Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 29 Mar 2025 05:41:55 +0300 Subject: [PATCH 2/2] added new methods --- include/omath/color.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/omath/color.hpp b/include/omath/color.hpp index bafefc3..c82c19d 100644 --- a/include/omath/color.hpp +++ b/include/omath/color.hpp @@ -118,7 +118,29 @@ namespace omath { Clamp(0.f, 1.f); } + consteval void SetHue(const float hue) + { + auto hsv = ToHSV(); + hsv.hue = hue; + *this = FromHSV(hsv); + } + + consteval void SetSaturation(const float saturation) + { + auto hsv = ToHSV(); + hsv.saturation = saturation; + + *this = FromHSV(hsv); + } + + consteval void SetValue(const float value) + { + auto hsv = ToHSV(); + hsv.value = value; + + *this = FromHSV(hsv); + } [[nodiscard]] constexpr Color Blend(const Color& other, float ratio) const {