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)};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N> requires (std::is_floating_point_v<T> && (N == 3 || N == 4))
|
||||
T hue(math::vector<T, N> const & c)
|
||||
template <typename T>
|
||||
math::vector<T, 3> rgb_to_hsv(math::vector<T, 3> const & rgb)
|
||||
{
|
||||
T max = std::max({c[0], c[1], c[2]});
|
||||
T min = std::min({c[0], c[1], c[2]});
|
||||
T max = std::max({rgb[0], rgb[1], rgb[2]});
|
||||
T min = std::min({rgb[0], rgb[1], rgb[2]});
|
||||
T delta = max - min;
|
||||
|
||||
if (delta == T{0})
|
||||
return T{0};
|
||||
T hue = 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])
|
||||
{
|
||||
result = (c[1] - c[2]) / delta;
|
||||
}
|
||||
else if (c[1] > c[2])
|
||||
{
|
||||
result = 2.f + (c[2] - c[0]) / delta;
|
||||
}
|
||||
hue *= math::rad<T>(60);
|
||||
|
||||
if (hue < 0)
|
||||
hue += math::rad<T>(360);
|
||||
|
||||
math::vector<T, 3> result;
|
||||
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
|
||||
{
|
||||
result = 4.f + (c[0] - c[1]) / delta;
|
||||
}
|
||||
result = {c, T{0}, x};
|
||||
|
||||
result *= math::rad<T>(60);
|
||||
|
||||
if (result < 0)
|
||||
result += math::rad<T>(360);
|
||||
result += math::vector{m, m, m};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue