diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd86673..a171a49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,7 @@ Jump to version:
### MLEM
Additions
-- Added ColorExtensions.ToHsl and ColorHelper.FromHsl
+- Added ColorExtensions.ToHsl and ColorHelper.FromHsl as well as ColorExtensions.ToHsv and ColorHelper.FromHsv
## 7.0.0
diff --git a/MLEM/Graphics/ColorExtensions.cs b/MLEM/Graphics/ColorExtensions.cs
index 897fbb8..bbd569c 100644
--- a/MLEM/Graphics/ColorExtensions.cs
+++ b/MLEM/Graphics/ColorExtensions.cs
@@ -91,6 +91,38 @@ namespace MLEM.Graphics {
return (h, s, l);
}
+ ///
+ /// Converts the given into HSV representation and returns the result as a value tuple with values between 0 and 1.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The color to convert.
+ /// The resulting HSV color as a value tuple containing H, S and V, each between 0 and 1.
+ public static (float H, float S, float V) ToHsv(this Color color) {
+ var r = color.R / 255F;
+ var g = color.G / 255F;
+ var b = color.B / 255F;
+
+ var max = Math.Max(Math.Max(r, g), b);
+ var min = Math.Min(Math.Min(r, g), b);
+ var d = max - min;
+ float h, s = max == 0 ? 0 : d / max, v = max;
+
+ if (max == min) {
+ h = 0; // achromatic
+ } else {
+ if (r == max) {
+ h = (g - b) / d + (g < b ? 6 : 0);
+ } else if (g == max) {
+ h = (b - r) / d + 2;
+ } else {
+ h = (r - g) / d + 4;
+ }
+ h /= 6;
+ }
+
+ return (h, s, v);
+ }
+
}
///
@@ -184,6 +216,46 @@ namespace MLEM.Graphics {
return new Color(r, g, b);
}
+ ///
+ ///Converts the given HSV color to an RGB and returns the result.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The HSV color to convert, as a value tuple that contains H, S and V values, each between 0 and 1.
+ /// The resulting RGB color.
+ public static Color FromHsv((float H, float S, float V) color) {
+ return ColorHelper.FromHsv(color.H, color.S, color.V);
+ }
+
+ ///
+ ///Converts the given HSV values to an RGB and returns the result.
+ ///
+ /// This code is adapted from https://gist.github.com/mjackson/5311256.
+ /// The H component of the HSV color, between 0 and 1.
+ /// The S component of the HSV color, between 0 and 1.
+ /// The V component of the HSV color, between 0 and 1.
+ /// The resulting RGB color.
+ public static Color FromHsv(float h, float s, float v) {
+ var i = (int) (h * 6);
+ var f = h * 6 - i;
+ var p = v * (1 - s);
+ var q = v * (1 - f * s);
+ var t = v * (1 - (1 - f) * s);
+ switch (i % 6) {
+ case 0:
+ return new Color(v, t, p);
+ case 1:
+ return new Color(q, v, p);
+ case 2:
+ return new Color(p, v, t);
+ case 3:
+ return new Color(p, q, v);
+ case 4:
+ return new Color(t, p, v);
+ default: // 5
+ return new Color(v, p, q);
+ }
+ }
+
private static float HueToRgb(float p, float q, float t) {
if (t < 0)
t += 1;
diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs
index 3a2711f..0431ac3 100644
--- a/Sandbox/GameImpl.cs
+++ b/Sandbox/GameImpl.cs
@@ -398,27 +398,27 @@ public class GameImpl : MlemGame {
Console.WriteLine("Buttons: " + string.Join(", ", GenericInput.AllButtons));
Console.WriteLine("Inputs: " + string.Join(", ", GenericInput.AllInputs));*/
- var hsl = new Panel(Anchor.Center, new Vector2(100), true);
- var color = Color.Pink.ToHsl();
- hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "H"));
- hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ var hsv = new Panel(Anchor.Center, new Vector2(100), true);
+ var color = Color.Pink.ToHsv();
+ hsv.AddChild(new Paragraph(Anchor.AutoLeft, 1, "H"));
+ hsv.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
CurrentValue = color.H,
OnValueChanged = (_, v) => color.H = v
});
- hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "S"));
- hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ hsv.AddChild(new Paragraph(Anchor.AutoLeft, 1, "S"));
+ hsv.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
CurrentValue = color.S,
OnValueChanged = (_, v) => color.S = v
});
- hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "L"));
- hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
- CurrentValue = color.L,
- OnValueChanged = (_, v) => color.L = v
+ hsv.AddChild(new Paragraph(Anchor.AutoLeft, 1, "V"));
+ hsv.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
+ CurrentValue = color.V,
+ OnValueChanged = (_, v) => color.V = v
});
- hsl.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 40), false) {
- OnDrawn = (e, _, batch, _, _) => batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorHelper.FromHsl(color))
+ hsv.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 40), false) {
+ OnDrawn = (e, _, batch, _, _) => batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorHelper.FromHsv(color))
});
- this.UiSystem.Add("HSL", hsl);
+ this.UiSystem.Add("HSV", hsv);
}
protected override void DoUpdate(GameTime gameTime) {