稳定的随机颜色算法

发布于 2024-09-04 00:52:25 字数 842 浏览 8 评论 0原文

这里我们有一个涉及颜色的有趣的现实世界算法要求。

  1. N 漂亮的颜色:为了绘制漂亮的图表(即饼图),我们需要随机选择一组 N 颜色,它们是“足够不同”并且在一起看起来很好。这可以通过固定亮度和饱和度并以 360/N 的步长逐步调整色调来实现。
  2. 稳定的颜色分配:给定 Pie_1 的扇区标记为 ('A','B','C') 和 Pie_2 的扇区标记为 ('B','C','D'),它会如果 Pie_1 和 Pie_2 上 B 区和 C 区的颜色相同,那就太好了。如果随着时间的推移扇区被删除或添加到图表中,这将有助于防止混乱。标签是唯一稳定的东西。
  3. 允许硬编码颜色:算法应允许硬编码标签->颜色关系作为输入,但会计算其余标签的颜色(根据规则 1 和 2)。

我认为这个算法,即使它看起来很特别,也将在不止一种情况下有用。

有什么想法吗?

更新: 埃里克是对的,随着新标签的出现和消失,不可能保证每个标签颜色的稳定性。但如果它“足够稳定”,即颜色变化最小化,我会很高兴。

我在想这样的事情:

  1. 每个标签使用 hash(label)%360 获取随机色调值
  2. 为了保证生成的色调足够不同,我们将色调圈划分为固定数量的步骤(即: 2*N)并尝试将以前的色调值“舍入”为新的差异值。
  3. 如果不同的标签具有相同的舍入色调值,我们会以某种方式打破平局并将点移动到其他地方。

但这忽略了硬编码颜色的问题。

Here we have an interesting real-world algorithm requirement involving colors.

  1. N Pretty Colors: In order to draw a beautiful chart (i.e: pie chart) we need to pick a random set of N colors that are "different enough" and look good together. This could be accomplished by fixing brightness and saturation and stepping through hue in steps of 360/N.
  2. Stable Color Assignment: given Pie_1 with sectors labelled ('A','B','C') and Pie_2 with sectors labelled ('B','C','D'), it would be nice if the color of sectors B and C are the same on both Pie_1 and Pie_2. This will help prevent confusion if sectors are removed or added to the chart over time. The label is the only stable thing.
  3. Allows Hard-coded colors: The algorithm should allow hardcoded label->color relationships as an input but will compute colors (according to rules 1 and 2) for the rest of the labels.

I think this algorithm, even if it looks quite ad-hoc, will be useful in more than one situation.

Any ideas?

Update:
Eric is right that is impossible to guarantee the stability of colors for each label as new labels appear and disappear. But I'm happy if it is "stable enough", i.e. color changes are minimized.

I was thinking of something like:

  1. Every label gets a random hue value using hash(label)%360
  2. In order to guarantee that the generated hues are different enough, we divide the hue circle in a fixed amount of steps (i.e: 2*N) and try to 'round' the previous hue values to the new differentiated ones.
  3. In the case of different labels going to the same rounded hue value, we break the tie somehow and move the point somewhere else.

But this leaves aside the issue of hard-coded colors.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愛上了 2024-09-11 00:52:25

您可以使用色轮算法选择一组看起来不错的随机颜色。这是一个带有实施指南的相关SO问题,或者谷歌搜索许多其他问题。

您可以使用标签散列之类的东西作为色轮上的起点,以确保稳定性。这也满足 3. 如果您有一个覆盖机制来声明特定标签哈希值应对应于色轮上的特定起点。

编辑:

色轮允许您选择一个主起点(例如(散列(A)% 360)并确保其他两种颜色(B,C)与 A 一起使用时“很好”。B 和 C 由 A 确定 稍后可以有一个饼图 (B, Y, Z),则 B 将设置为 (hash(B) % 360),并且与 (A, B, C) 情况下的情况不同。

如果您 可以在饼图上任意混合标签,没有算法可以确保它们总是看起来很好。这里有一个简单的证明:

A,B,C,使它们看起来很好

现在让A以任意颜色Z出现。

选择 当然,为 Z 选择一些颜色,这样 A 和 Z 就会发生冲突,

您只能保证某一组颜色在一起看起来很好,并且选择相同的颜色组将重现相同的颜色,

您可以使用例如第一个颜色的哈希值。标签作为轮子上的起点 (hash(A)),或者您可以组合哈希值 (hash(A) + 31*hash(B) + 31*31*hash(C))。 )是来自 Java 世界的东西,有助于确保在组合多个哈希时获得更好的数学分布。

You can pick a set of random colors that look good together using a color wheel algorithm. Here's a related SO question with implementation guides, or google for many others.

You can use something like a hash of your labels as a starting point on the color wheel to ensure stability. This also satisfies 3. if you have an override mechanism to state that a specific label hash value should correspond to a specific starting point on the color wheel.

EDIT:

The color wheel lets you pick one master starting point (e.g. (hash(A) % 360) and ensure that two other colors (B, C) are "nice" when used together with A. B and C are determined by A. If you can later have a pie chart (B, Y, Z), B would be set as (hash(B) % 360) and would be different than it was in the (A, B, C) case.

If you can arbitrarily mix labels on pie charts, NO algorithm can ensure they will always look good together. Here's a simple proof:

Let A, B, C be selected so that they look good together.

Now let A appear with an arbitrary color Z

You can certainly pick some color for Z such that A and Z will clash.

You can only guarantee that a certain set of colors will look good together, and that picking the same set will reproduce the same colors.

You can use the hash of e.g. the first label as the starting point on the wheel (hash(A)) or you can combine the hashes (hash(A) + 31*hash(B) + 31*31*hash(C)). Multiplying by 31 (a prime number) is something from the Java world that helps ensure a better mathematical distribution when combining multiple hashes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文