-
Notifications
You must be signed in to change notification settings - Fork 699
Add methods to support generating color palettes #6720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+165
−0
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
ece4f7d
add methods to support generating color palettes
mqole aae482c
guess we doin arrays now
mqole d042eb0
robust random
mqole 4a8ab7e
schmoovin
mqole 249660b
angels
mqole 8937501
tests
mqole 4e69bf2
yeas
mqole eb25a03
fuckit one more
mqole 4d1e393
OOPS
mqole 7ffe5fc
yeah ok
mqole 167a93a
test edits
mqole File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| using NUnit.Framework; | ||
| using Robust.Shared.Maths; | ||
| using Robust.Shared.Utility; | ||
|
|
||
| namespace Robust.Shared.Tests.Utility; | ||
|
|
||
| [Parallelizable(ParallelScope.All)] | ||
| [TestOf(typeof(ColorExtensions))] | ||
| internal sealed class ColorExtensionsTest | ||
| { | ||
| [Test] | ||
| public void TestAnalogousPalette() | ||
| { | ||
| var palette = ColorExtensions.GetAnalogousComplementaries(Color.Red); | ||
|
|
||
| using (Assert.EnterMultipleScope()) | ||
| { | ||
| Assert.That(palette, Has.Length.EqualTo(3)); | ||
| Assert.That(MathHelper.CloseToPercent(palette[0], Color.Red)); | ||
|
|
||
| Assert.That(Color.ToHsl(palette[0]).X, Is.Zero); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[1]).X, 30f / 360f)); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[2]).X, 1f - 30f / 360f)); | ||
| } | ||
| } | ||
|
|
||
| [Test] | ||
| public void TestTriadicPalette() | ||
| { | ||
| var palette = ColorExtensions.GetTriadicComplementaries(Color.Red); | ||
|
|
||
| using (Assert.EnterMultipleScope()) | ||
| { | ||
| Assert.That(palette, Has.Length.EqualTo(3)); | ||
| Assert.That(MathHelper.CloseToPercent(palette[0], Color.Red)); | ||
|
|
||
| Assert.That(Color.ToHsl(palette[0]).X, Is.Zero); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[1]).X, 120f / 360f)); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[2]).X, 1f - 120f / 360f)); | ||
| } | ||
| } | ||
|
|
||
| [Test] | ||
| public void TestSplitComplementaryPalette() | ||
| { | ||
| var palette = ColorExtensions.GetSplitComplementaries(Color.Red); | ||
|
|
||
| using (Assert.EnterMultipleScope()) | ||
| { | ||
| Assert.That(palette, Has.Length.EqualTo(3)); | ||
| Assert.That(MathHelper.CloseToPercent(palette[0], Color.Red)); | ||
|
|
||
| Assert.That(Color.ToHsl(palette[0]).X, Is.Zero); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[1]).X, 150f / 360f)); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[2]).X, 1f - 150f / 360f)); | ||
| } | ||
| } | ||
|
|
||
| [Test] | ||
| public void TestComplementaryPalette() | ||
| { | ||
| var palette = ColorExtensions.GetOneComplementary(Color.Red); | ||
|
|
||
| using (Assert.EnterMultipleScope()) | ||
| { | ||
| Assert.That(palette, Has.Length.EqualTo(3)); | ||
| Assert.That(MathHelper.CloseToPercent(palette[0], Color.Red)); | ||
|
|
||
| Assert.That(Color.ToHsl(palette[0]).X, Is.Zero); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[1]).X, 180f / 360f)); | ||
| Assert.That(MathHelper.CloseToPercent(Color.ToHsl(palette[2]).X, 1f - 180f / 360f)); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| using System; | ||
| using System.Numerics; | ||
| using Robust.Shared.Random; | ||
| using Robust.Shared.Maths; | ||
|
|
||
| namespace Robust.Shared.Utility; | ||
|
|
||
| public static class ColorExtensions | ||
| { | ||
| public static readonly float AnalogousHueDelta = 30f / 360f; // +/- 1/12. 30 degrees, 0.08333... over hue | ||
| public static readonly float TriadicHueDelta = 120f / 360f; // +/- 1/3. 120 degrees, 0.333 over hue | ||
| public static readonly float SplitComplementaryHueDelta = 150f / 360f; // +/- 5/12. 150 degrees, 0.4166... over hue | ||
| public static readonly float ComplementaryHueDelta = 180f / 360f; // +/- 1/2. 180 degrees | ||
|
|
||
| /// <summary> | ||
| /// Generates a list of analogous complementary colors | ||
| /// </summary> | ||
| public static Color[] GetAnalogousComplementaries(this Color color) | ||
| { | ||
| return GetComplementaryColors(color, AnalogousHueDelta); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Generates a list of triadic complementary colors | ||
| /// </summary> | ||
| public static Color[] GetTriadicComplementaries(this Color color) | ||
| { | ||
| return GetComplementaryColors(color, TriadicHueDelta); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Generates a list of split complementary colors | ||
| /// </summary> | ||
| public static Color[] GetSplitComplementaries(this Color color) | ||
| { | ||
| return GetComplementaryColors(color, SplitComplementaryHueDelta); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Generates a list containing the base color and two copies of a single complementary color | ||
| /// </summary> | ||
| public static Color[] GetOneComplementary(this Color color) | ||
| { | ||
| return GetComplementaryColors(color, ComplementaryHueDelta); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Generates a complementary color palette for a provided | ||
| /// color by rotating a set amount of degrees around the | ||
| /// color wheel, and then varying the value and saturation | ||
| /// slightly. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// A list of 3 colors. | ||
| /// </returns> | ||
| public static Color[] GetComplementaryColors(Color color, float hueDelta) | ||
| { | ||
| var hsl = Color.ToHsl(color); | ||
| var random = new RobustRandom(); | ||
|
|
||
| // sorry about how messy these are, but to get all random values we need to reroll for positive and negative HSL. | ||
| // since we want to rotate x degrees around the colour wheel, we need to do so in both directions- doing x + x degrees will give us the wrong hue! | ||
|
|
||
| // also varying the saturation and lightness just a little to add some contrast. | ||
| // since 'color' is our main color, we are desaturating our secondary colors. | ||
| // this means our main color will always stand out the most. | ||
|
|
||
| var hVal = hsl.X + hueDelta; | ||
| hVal -= MathF.Floor(hVal); | ||
| var positiveHSL = new Vector4( | ||
| hVal, | ||
| MathHelper.Clamp01(hsl.Y + random.Next(-20 / 100, 0)), | ||
| MathHelper.Clamp01(hsl.Z + random.Next(-15 / 100, 16 / 100)), | ||
| hsl.W); | ||
|
|
||
| var hVal1 = hsl.X - hueDelta; | ||
| if (hVal1 < 0f) | ||
| hVal1 += 1f; | ||
| var negativeHSL = new Vector4( | ||
| hVal1, | ||
| MathHelper.Clamp01(hsl.Y + random.Next(-20 / 100, 0)), | ||
| MathHelper.Clamp01(hsl.Z + random.Next(-15 / 100, 16 / 100)), | ||
| hsl.W); | ||
|
|
||
| var c0 = Color.FromHsl(positiveHSL); | ||
| var c1 = Color.FromHsl(negativeHSL); | ||
|
|
||
| var palette = new Color[] { color, c0, c1 }; | ||
| return palette; | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.