生成随机颜色

时间:2012-02-10 01:15:00

标签: grails groovy

我想为我的折线图生成6位数的随机颜色,每行一个。 现在我在Map中有一个颜色列表,每个事件行都有一个颜色,但是现在事件可以是动态的,而不是仅来自这个列表,所以我不能做ColorMap.get(eventname),因为eventname可能是全新的而不是在地图上。例如,我想从事件名称中生成随机颜色或颜色。我应该使用Math.random()还是更简单的方法?

我怎么能在groovy中做到这一点?

2 个答案:

答案 0 :(得分:6)

我假设用6位数字表示一些十六进制代码,如#ff0000(红色)。如果将它们视为随机24位整数,那么生成像这样的随机代码非常简单。也就是说,0到2 ^ 24之间的随机数.1。如此:

def randomRgbCode() {
    def rgb = new Random().nextInt(1 << 24) // A random 24-bit integer
    '#' + Integer.toString(rgb, 16).padLeft(6, '0')
}

这些东西生成的颜色代码非常随机,但看起来不太好;很多灰色的颜色都是一些生动的颜色。 These are该函数生成的一些颜色。

可以用随机HSL值而不是RGB来实现更生动的colos,例如生成随机色调,高饱和度和中等亮度。如果您使用这些颜色作为CSS样式,那么生成颜色代码非常容易,因为CSS现在supports HSL values

def randomHslCode() {
    def rnd = new Random()
    def h = rnd.nextInt(360)
    int s = 65 + rnd.nextInt(35)  // Quite saturated
    def l = 50
    "hsl($h, $s%, $l%)"
}

These are这个新函数生成的一些颜色。如你所见,更加生动。

现在,如果您不打算使用CSS样式中的颜色代码并且需要生成RGB代码,那么您可以生成如上所述的随机HSL值,然后将这些值转换为RGB 。该过程为quite straightforward,但需要更多编码:

import static Math.abs
def floor(x) { x as int }

def randomVividRgbCode() {
    def rnd = new Random()
    def h = rnd.nextFloat()
    def s = 0.65f + rnd.nextFloat() * 0.35f // Quite saturated
    def l = 0.5f
    rgbToColorCode(*hslToRgb(h, s, l))
}

def rgbToColorCode(r, g, b) {
    def rgb = floor(r * 255) << 16 | 
              floor(g * 255) << 8  | 
              floor(b * 255)
    '#' + Integer.toString(rgb, 16).padLeft(6, '0')
}

def hslToRgb(h, s, l) {
    def c = (1 - abs(2 * l - 1)) * s // Chroma.
    def h1 = h * 6
    def x = c * (1 - abs(h1 % 2 - 1))
    def rgb = h1 < 1 ? [c, x, 0] :
              h1 < 2 ? [x, c, 0] :
              h1 < 3 ? [0, c, x] :
              h1 < 4 ? [0, x, c] :
              h1 < 5 ? [x, 0, c] :
                       [c, 0, x]
    def (r, g, b) = rgb
    def m = l - c * 0.5
    [r + m, g + m, b + m]
}

我希望代码不是那么神秘:)。 These are由它生成的一些颜色。


现在,您可能会注意到某些生成的颜色非常相似,如果您想区分图表中的线条,这可能不是很好。你可以做些什么来避免这种情况有一个很好的托盘预定义和易于区分的颜色(你可以在互联网上找到很多颜色)并从那里挑选颜色。如果您的托盘中的颜色用尽(可能对图表中的线条数量没有限制),则可以使用上述方法或任何其他方法生成随机颜色:)

答案 1 :(得分:0)

如果您有特定的值间隔,则需要随机抽取:

random = new Random()
randomInt = random.nextInt((max_value)-(min_value)+1)+(min_value)

对于更接近真实的随机,您可以在Random()中插入种子值。我建议拉动当前系统时间戳。