【问题标题】:Is there any effective way to find colors like this?有什么有效的方法可以找到这样的颜色吗?
【发布时间】:2012-10-31 18:11:59
【问题描述】:

在我们的项目中,我们会尝试为不同的图形使用不同的颜色。这些颜色应满足以下条件:

  1. 所有颜色应满足:abs(A.R - A.G) + abs(A.G - A.B) + abs(A.B - A.R) > 250
  2. 所有颜色都应该足够不同。如果颜色 A 和 B 相遇:abs(A.R - B.R) + abs(A.G - B.G) + abs(A.B - B.B) >= 50,那么它们就足够不同了。 问题是我们最多可以获得多少种颜色?有没有不枚举所有组合的快速方法来获取颜色?

【问题讨论】:

  • 因为你没有使用颜色属性,只是坐标,这是一个几何问题。拿一个立方体,使用标准 1 将自己限制在其中的一个子集,然后在该子集中选择由标准 2 成对限制的点。不幸的是,它不是完全 球形包装(已经研究过),因为您的距离度量不是欧几里得距离。

标签: algorithm math


【解决方案1】:

我认为获得准确结果的最简单方法是通过拉斯维加斯算法,在该算法中,您尝试通过逐步添加不会使当前集无效的随机颜色来组合尽可能大的颜色集。如果没有这样的颜色可用(例如,因为最近 100 次尝试寻找这样的颜色失败),则当前集形成结果。

请注意,当它被卡住时,它不会尝试“撤消”可能的错误添加,它只是终止,这使得算法报告许多次优集,但速度非常快。因此,您需要多次(数千次?)运行此算法,以查看您可以组合多大的集合。

我认为这是用相对较少的编程或分析工作获得体面结果的更快方法之一。

编辑:进行了几次快速运行:我发现由非冲突颜色组成的最大设置大小为 273

编辑2根据要求,对应(相关)源代码:

public class Colour
{
    public int Red;
    public int Green;
    public int Blue;

    public int Primality
    {
        get { return Math.Abs(Red - Green) + Math.Abs(Green - Blue) + Math.Abs(Blue - Red); }
    }

    public int Difference(Colour other)
    {
        return Math.Abs(this.Red - other.Red) + Math.Abs(this.Green - other.Green) + Math.Abs(this.Blue - other.Blue);
    }

    public Colour(int red, int green, int blue)
    {
        Red = red;
        Green = green;
        Blue = blue;
    }

    public static Colour Generate(Random rnd)
    {
        return new Colour(rnd.Next(256), rnd.Next(256), rnd.Next(256));
    }

    public static Colour GeneratePrimal(Random rnd)
    {
        Colour candidate = null;
        do
        {
            candidate = Generate(rnd);
        } while (candidate.Primality <= 250);

        return candidate;
    }
}

使用此类,所描述的算法的单次运行将如下所示:

private Random _rnd = new Random();

public List<Colour> Run()
{
    List<Colour> resultSet = new List<Colour>();

    //Shouldn't find a set larger than 1000 Colours.
    for (int colourCount = 0; colourCount < 1000; colourCount++)
    {
        Colour candidate = null;
        bool found = false;

        //100000 means: Try *very* hard to find a next candidate
        for (int index = 0; index < 100000; index++)
        {
            candidate = Colour.GeneratePrimal(_rnd);
            if (resultSet.Any(col => candidate.Difference(col) < 50) == false)
            {
                resultSet.Add(candidate);
                found = true;
                break;
            }
        }

        if (found == false)
            return resultSet;
    }

    return resultSet;
}

【讨论】:

  • 完成了...顺便说一句,如果这是最有帮助的帖子,您能把它标记为答案吗?
【解决方案2】:

这取决于您需要颜色的位置(网站、图片等)。我曾经遇到过一个非常相似的问题,下面是我发现的。最后,我只使用了 HSV 颜色空间(这在我的应用程序中很简单),它允许您将色调范围划分为大小相等的间隔,并且每次都获得不同的颜色。

这是我发现有用的:

Generate distinctly different RGB colors in graphs

How to automatically generate N "distinct" colors?

Generate unique colours

【讨论】:

    猜你喜欢
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多