C# - 对颜色列表进行排序的更好方法
C# - Better ways to sort a list of colors
因此,在有人称此 post 为重复之前,让我解释一下。我试图找到更优化的排序算法来根据十六进制值列表组织颜色列表。我目前正在根据色调对颜色进行排序。这很好,但是当有一堆颜色时,它似乎会产生一些噪音。
我目前正在尝试寻找 C# 方法来对大量随机十六进制值进行排序。我参考了这个 Whosebug question and used some knowledgement from this 网站并在下面创建了我的代码。
RichTextBox1:
#ee82ee // Violet
#008000 // Green
#ffa500 // Orange
#0000ff // Blue
#ff0000 // Red
#ffff00 // Yellow
#4b0082 // Indigo
// Create a List from each color within the richtextbox
List<Color> tiledata = new List<Color> ();
foreach (string line in richTextBox1.Lines)
{
// Get Each Line From Richtoxbox And Convert The Hex
tiledata.Add(System.Drawing.ColorTranslator.FromHtml(line));
}
// Sort colors based on HUE
//
var hexColorsSorted = tiledata.OrderBy(color => color.GetHue()).ThenBy(o => o.R * 3 + o.G * 2 + o.B * 1);
// Expand Each Item Of The List
foreach (var color in hexColorsSorted)
{
// Output the data
Console.WriteLine(ColorConverterExtensions.ToHexString(color));
}
从上面看,这显然会按照正确的彩虹顺序对颜色进行排序。然而,一旦你引入了更多如此相似的颜色,上图中的事情就开始变得非常混乱。目前的排序算法只是先按HUE排序,再按RGB排序。有没有其他方法或更多我可以做的来清理一下?我唯一的要求是允许它与 List<Tuple<Color>>
一起使用,例如下面的示例。
.OrderBy(color => color.Item3.GetHue()).ThenBy(o => o.Item3.R * 3 + o.Item3.G * 2 + o.Item3.B * 1)
Bellow 是一种排序算法,此方法似乎尝试 并遵循但最终失败。如果事情看起来类似于以下步骤排序算法,那就太好了。
要么
更新:我进行了调整以更像示例中的色调方向。
我已经从你的示例中重新创建了样式,你只需要使用这个比较器对数组进行排序:
class ColorRampComparer : IComparer<Color>
{
public int Compare(Color a, Color b)
{
var c1 = Step(a);
var c2 = Step(b);
return ((IComparable)c1).CompareTo(c2);
}
private Tuple<int, int, int> Step(Color color, int repetitions = 8)
{
int lum = (int)Math.Sqrt(.241 * color.R + .691 * color.G + .068 * color.B);
float hue = 1 - Rotate(color.GetHue(), 90) / 360;
float lightness = color.GetBrightness();
int h2 = (int)(hue * repetitions);
int v2 = (int)(lightness * repetitions);
// To achieve second style uncomment this condition
//if ((h2 % 2) == 0)
// v2 = repetitions - v2;
//else
// lum = repetitions - lum;
return Tuple.Create(h2, lum, v2);
}
private float Rotate(float angle, float degrees)
{
angle = (angle + degrees) % 360;
if (angle < 0) angle += 360;
return angle;
}
}
结果如下:
如果您取消注释 Step
函数中的片段,那么它将如下所示:
要对数组或可枚举对象进行排序,请使用 Sort
方法:
colors.Sort(new ColorRampComparer());
因此,在有人称此 post 为重复之前,让我解释一下。我试图找到更优化的排序算法来根据十六进制值列表组织颜色列表。我目前正在根据色调对颜色进行排序。这很好,但是当有一堆颜色时,它似乎会产生一些噪音。
我目前正在尝试寻找 C# 方法来对大量随机十六进制值进行排序。我参考了这个 Whosebug question and used some knowledgement from this 网站并在下面创建了我的代码。
RichTextBox1:
#ee82ee // Violet
#008000 // Green
#ffa500 // Orange
#0000ff // Blue
#ff0000 // Red
#ffff00 // Yellow
#4b0082 // Indigo
// Create a List from each color within the richtextbox
List<Color> tiledata = new List<Color> ();
foreach (string line in richTextBox1.Lines)
{
// Get Each Line From Richtoxbox And Convert The Hex
tiledata.Add(System.Drawing.ColorTranslator.FromHtml(line));
}
// Sort colors based on HUE
//
var hexColorsSorted = tiledata.OrderBy(color => color.GetHue()).ThenBy(o => o.R * 3 + o.G * 2 + o.B * 1);
// Expand Each Item Of The List
foreach (var color in hexColorsSorted)
{
// Output the data
Console.WriteLine(ColorConverterExtensions.ToHexString(color));
}
从上面看,这显然会按照正确的彩虹顺序对颜色进行排序。然而,一旦你引入了更多如此相似的颜色,上图中的事情就开始变得非常混乱。目前的排序算法只是先按HUE排序,再按RGB排序。有没有其他方法或更多我可以做的来清理一下?我唯一的要求是允许它与 List<Tuple<Color>>
一起使用,例如下面的示例。
.OrderBy(color => color.Item3.GetHue()).ThenBy(o => o.Item3.R * 3 + o.Item3.G * 2 + o.Item3.B * 1)
Bellow 是一种排序算法,此方法似乎尝试 并遵循但最终失败。如果事情看起来类似于以下步骤排序算法,那就太好了。
更新:我进行了调整以更像示例中的色调方向。
我已经从你的示例中重新创建了样式,你只需要使用这个比较器对数组进行排序:
class ColorRampComparer : IComparer<Color>
{
public int Compare(Color a, Color b)
{
var c1 = Step(a);
var c2 = Step(b);
return ((IComparable)c1).CompareTo(c2);
}
private Tuple<int, int, int> Step(Color color, int repetitions = 8)
{
int lum = (int)Math.Sqrt(.241 * color.R + .691 * color.G + .068 * color.B);
float hue = 1 - Rotate(color.GetHue(), 90) / 360;
float lightness = color.GetBrightness();
int h2 = (int)(hue * repetitions);
int v2 = (int)(lightness * repetitions);
// To achieve second style uncomment this condition
//if ((h2 % 2) == 0)
// v2 = repetitions - v2;
//else
// lum = repetitions - lum;
return Tuple.Create(h2, lum, v2);
}
private float Rotate(float angle, float degrees)
{
angle = (angle + degrees) % 360;
if (angle < 0) angle += 360;
return angle;
}
}
结果如下:
如果您取消注释 Step
函数中的片段,那么它将如下所示:
要对数组或可枚举对象进行排序,请使用 Sort
方法:
colors.Sort(new ColorRampComparer());