Add HSV <-> RGB conversions
This commit is contained in:
parent
4f4e86ce4f
commit
12eed4dda5
1 changed files with 54 additions and 22 deletions
|
|
@ -317,35 +317,67 @@ namespace psemek::gfx
|
||||||
return generic_color{dark(c.c, darkness)};
|
return generic_color{dark(c.c, darkness)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t N> requires (std::is_floating_point_v<T> && (N == 3 || N == 4))
|
template <typename T>
|
||||||
T hue(math::vector<T, N> const & c)
|
math::vector<T, 3> rgb_to_hsv(math::vector<T, 3> const & rgb)
|
||||||
{
|
{
|
||||||
T max = std::max({c[0], c[1], c[2]});
|
T max = std::max({rgb[0], rgb[1], rgb[2]});
|
||||||
T min = std::min({c[0], c[1], c[2]});
|
T min = std::min({rgb[0], rgb[1], rgb[2]});
|
||||||
T delta = max - min;
|
T delta = max - min;
|
||||||
|
|
||||||
if (delta == T{0})
|
T hue = T{0};
|
||||||
return T{0};
|
|
||||||
|
|
||||||
T result;
|
if (delta > T{0})
|
||||||
|
{
|
||||||
|
if (rgb[0] > rgb[1] && rgb[0] > rgb[2])
|
||||||
|
{
|
||||||
|
hue = (rgb[1] - rgb[2]) / delta;
|
||||||
|
}
|
||||||
|
else if (rgb[1] > rgb[2])
|
||||||
|
{
|
||||||
|
hue = 2.f + (rgb[2] - rgb[0]) / delta;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hue = 4.f + (rgb[0] - rgb[1]) / delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (c[0] > c[1] && c[0] > c[2])
|
hue *= math::rad<T>(60);
|
||||||
{
|
|
||||||
result = (c[1] - c[2]) / delta;
|
if (hue < 0)
|
||||||
}
|
hue += math::rad<T>(360);
|
||||||
else if (c[1] > c[2])
|
|
||||||
{
|
math::vector<T, 3> result;
|
||||||
result = 2.f + (c[2] - c[0]) / delta;
|
result[0] = hue;
|
||||||
}
|
result[1] = (max > T{0}) ? (delta / max) : T{0};
|
||||||
|
result[2] = max;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
math::vector<T, 3> hsv_to_rgb(math::vector<T, 3> const & hsv)
|
||||||
|
{
|
||||||
|
auto c = hsv[1] * hsv[2];
|
||||||
|
auto x = c * (T{1} - std::abs(std::fmod(hsv[0] / math::rad<T>(60), 2.f) - 1.f));
|
||||||
|
auto m = hsv[2] - c;
|
||||||
|
|
||||||
|
math::vector<T, 3> result;
|
||||||
|
|
||||||
|
if (hsv[0] < math::rad<T>(60))
|
||||||
|
result = {c, x, T{0}};
|
||||||
|
else if (hsv[0] < math::rad<T>(120))
|
||||||
|
result = {x, c, T{0}};
|
||||||
|
else if (hsv[0] < math::rad<T>(180))
|
||||||
|
result = {T{0}, c, x};
|
||||||
|
else if (hsv[0] < math::rad<T>(240))
|
||||||
|
result = {T{0}, x, c};
|
||||||
|
else if (hsv[0] < math::rad<T>(300))
|
||||||
|
result = {x, T{0}, c};
|
||||||
else
|
else
|
||||||
{
|
result = {c, T{0}, x};
|
||||||
result = 4.f + (c[0] - c[1]) / delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
result *= math::rad<T>(60);
|
result += math::vector{m, m, m};
|
||||||
|
|
||||||
if (result < 0)
|
|
||||||
result += math::rad<T>(360);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue