diff --git a/src/lol/image/color.h b/src/lol/image/color.h index 648f0938..10c5665a 100644 --- a/src/lol/image/color.h +++ b/src/lol/image/color.h @@ -84,20 +84,17 @@ public: */ static vec3 RGBToHSV(vec3 src) { - float offset = 0.f; - - if (src.r < src.g) - src = src.grb, offset = -2.f / 6.f; + float K = 0.f; if (src.g < src.b) - src = src.rbg, offset = -1.f - 4.f * offset; + src = src.rbg, K = -1.f; if (src.r < src.g) - src = src.grb, offset = -2.f / 6.f - offset; + src = src.grb, K = -2.f / 6.f - K; - float chroma = src.r - src.b; - return vec3(abs((src.g - src.b) / (6.f * chroma + 1e-40f) + offset), - chroma / (src.r + 1e-40f), + float chroma = src.r - min(src.g, src.b); + return vec3(abs(K + (src.g - src.b) / (6.f * chroma + 1e-20f)), + chroma / (src.r + 1e-20f), src.r); } diff --git a/test/unit/color.cpp b/test/unit/color.cpp index 46987d1f..9cb15ae1 100644 --- a/test/unit/color.cpp +++ b/test/unit/color.cpp @@ -86,6 +86,21 @@ LOLUNIT_FIXTURE(ColorTest) LOLUNIT_ASSERT_DOUBLES_EQUAL(d2, d3, 0.0001); } } + + LOLUNIT_TEST(RGBToHSV) + { + for (int r = 0; r < 20; r++) + for (int g = 0; g < 20; g++) + for (int b = 0; b < 20; b++) + { + vec3 v1 = vec3(r / 20.f, g / 20.f, b / 20.f); + vec3 v2 = Color::HSVToRGB(Color::RGBToHSV(v1)); + + LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.r, v2.r, 0.0001); + LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.g, v2.g, 0.0001); + LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.b, v2.b, 0.0001); + } + } }; } /* namespace lol */