【问题标题】:generate random RGB color using rand() function使用 rand() 函数生成随机 RGB 颜色
【发布时间】:2012-06-04 14:22:08
【问题描述】:

我需要一个能够生成三个数字的函数,以便我可以将它们用作我的 SVG 的 RGB 模式。
虽然这很简单,但我还需要确保我没有两次使用相同的颜色。 我该怎么做?使用简单的rand(种子时间激活)一次生成一个数字,然后呢?我不想排除一个数字,但也许是整个模式?
我有点迷路了。

准确地说,首先调用这个函数我会得到例如 218 199 154,然后我会得到 47 212 236,这绝对是两种不同的颜色。有什么建议么?

另外我认为structint r, int g, int b 会适合这个吗?

编辑:颜色应该与人眼不同。很抱歉之前没有提到这一点。

【问题讨论】:

  • 为了保证同一种颜色永远不会被使用两次,只需将目前生成的颜色存储在一个链表中(或者哈希映射,如果你可以访问的话)。继续申请 rand,直到你的号码不在那个集合中。
  • 另一个考虑因素:计算机或人是“相同颜色”吗?如果是第二个,那么 RGB 数字中的一个单位的差异可能不足以使其与眼睛有足够的差异。
  • @Arkadiy:是的,与人眼不同。不仅仅是相同颜色的不同色调,无法识别。
  • @EthanSteinberg:随机是否符合概率定律?我的意思是我有 1/255 来生成一个数字吗?意思是在 255 中的 1 中我会得到例如 1 .. 我不会得到 255 255 0 和 255 255 1 的概率是多少?有时会发生这种情况是对还是我完全错了?
  • 在这种情况下,您需要一个比较过程来决定 = / != 基于人类感知...

标签: c random colors svg srand


【解决方案1】:

您可以使用集合来存储生成的颜色。 首先实例化一个新集合。 然后,每次生成颜色时,查看该值是否存在于您的集合中。 如果记录存在,请跳过它并重试新颜色。如果没有,您可以使用它,但不要忘记将其缓存在 Set 之后。 如果您需要生成大量颜色,这可能会变得不高效。

【讨论】:

  • 这似乎是一个很好的解决方案,但是我如何确保它会为两个不同的调用生成两种不同的颜色,而这些颜色对人眼来说会有所不同,而不仅仅是对计算机而言,我的意思是它会是黄色和紫色,而不是黄色和浅黄色(人眼几乎无法识别)。
  • 好的,然后在生成颜色后,您必须扫描生成的颜色列表以检查它是否不太接近。您必须确定 2 种颜色 (r,g,b) 之间的最低分数,这将使结果独一无二。如果所有三个(r g 和 b)值都太接近现有颜色,则开始新的生成。IE r:200 g:200 b:200。如果您生成 199;199;150 并将 scoree 设置为 5,这很好,感谢蓝色。如果生成 195,198,197,则所有 3 种颜色的间隔都在得分限制之下。
  • 好吧,我照你说的做了,因为这对我来说似乎是最简单的解决方案,而且它似乎工作得很好。谢谢。
【解决方案2】:

最便宜的方法是使用Bloom filter,这在内存方面非常小,但偶尔会导致误报(即,您会认为您使用了一种颜色,但实际上没有)。基本上,创建三个 0-255 之间的随机数,随意保存它们,将它们作为三元组散列,然后将散列放入过滤器中。

此外,您可能希望丢弃每个通道的低位,因为可能不容易区分 #FFFFF0 与 #FFFFF2。

【讨论】:

  • 这很有趣,但问题有点复杂,因为我想确保两种相同的颜色不会再次发生,第一次调用 255 255 0 和第二次调用 255 255 1 不会也会发生。 (因为这很难辨认)
  • 我知道这一点。我的建议并没有按这个顺序产生它们。我的意思是,在计算过滤器中的哈希函数时,你应该丢弃低位以防止这种重复。
  • 我已经设法通过不同的解决方案实现了这一目标,但感谢您抽出宝贵时间 :)
【解决方案3】:

这是一个简单的方法:

1.Generate a random integer.
2.Shift it 8 times to have 24 meaningful bits, store this integer value.
3.Use first 8 bits for R, second group of 8 bits for G,
      and the remaining 8 bits for B value.

对于每个新的随机数,将其移动 8 次,比较您之前存储的所有其他整数值,如果它们都与新的不匹配,则将其用于新颜色(步骤 3)。

人眼的区分是一个有趣的话题,因为感知阈值因人而异。要实现它移位整数 14 次,为 R 获取前 6 位(填充两个 0 以再次获得 8 位),为 G 获取第二个 6 位,为 B 获取最后 6 位。如果您认为 6 位不是对它有好处,减少它 5,4...

每个通道有 4 个有效位的简单运行: 我的随机整数是:

0101-1111-0000-1111-0000-1100-1101-0000

我将它向左移动(你也可以使用乘法或模数)20次:

0000-0000-0000-0000-0000-0101-1111-0000

存储这个值。

然后为 R 获取前 4 位,为 G 获取后 4 位,为 B 获取后 4 位:

R: 0101
G: 1111
B: 0000

填充它们以使它们每个为 8 位。

R: 0101-0000
G: 1111-0000
B: 0000-0000

将这些用于您的颜色组件。

对于移动后的每个新随机数,将其与迄今为止存储的整数值进行比较。如果不同,则存储并用于颜色。

【讨论】:

    【解决方案4】:

    一个想法是使用位向量来表示生成的一组颜色。对于 24 位精度,位向量的长度为 224 位,即 16,777,216 位或 2 MB。现在肯定不是很多,而且查找和插入颜色会非常快。

    【讨论】:

    • 你能再解释一下吗? :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多