views:

517

answers:

4

Hi, I want to write a function in ruby that given a number between 1 and 500 will output a 6 digit hex color code that gets linearly darker for higher numbers. This doesn't seem that hard but I'm not sure where to begin. How can I implement this?

edit

Hue seems like a more reliable way to go. I'd like to give a reference color, say a shade of green, and then darken or lighten it based on the input number.

input: 10
output: color code (in rgb or HSV) that is a light shade of the reference color

input: 400
output: color code (in rgb or HSV) that is a fairly dark shade of the reference color

edit 2

The only reason I need to use between 1 and 500 is because that's the input I have to work with. It's alright if some numbers that are close together map to the same color.

+1  A: 

Why not just return a gray level then, #ffffff to #000000? 500 levels of darkness aren't really distinguishable anyway, and grays give you 256 levels.

Ned Batchelder
Thanks, but I need to use a reference color. Grays won't work for me.
William
just divide the number 1 to 500 by 2 and you'll get 1 to 250, which is probably perfect for what you need. (actual math: nuval = oldval * 255 / 500 -- with ints, make sure to multiply before you divide)
Jared Updike
+2  A: 

The 6 digit hex color code is in RGB. What you want is to work in HSV: pick a Hue and Saturation, and gradually decrease the Value. Convert from HSV to RGB to output the color. See here for an example.

mbeckish
other links: http://en.wikipedia.org/wiki/HSL_and_HSV
Jared Updike
This looks good. Is there a simple way to convert from HSV to RGB in Ruby?
William
@William - Yes, the wikipedia link from Jared Updike shows a simple formula. All you need is floor, mod, and arithmetic.
mbeckish
+1  A: 

If you only want to darken your reference color, it's easy. Given an R,G,B color that is the brightest you want to go, multiply each of the 3 values by (500-input) and divide by 499. Convert each of the values to 2 hex digits and append them with a # at the front.

Mark Ransom
as pointed out elsewhere, this isn't how RGB color works. HSV is a better color system for this.
Gregg Lind
I'm not sure I understand the objection. There are other operations that might be easier in another color space, but darkening an RGB color is quite trivial.
Mark Ransom
+2  A: 

Basic linear interpolation?

// Pseudocode
function fade_colour(source, factor)
    const max = 500
    const min = 1

    foreach component in source
        output[component] = round(source[component] * (max - value) / (max - min))
    endforeach

    return output
endfunction
strager
@Ransom, Are you sure? If I input value=1 I get source[component] back, according to Google, and if I input value=500 I get 0.
strager
Sorry, I don't know what I was thinking - your formula is exactly the same as mine, only more generic. I withdraw my comment.
Mark Ransom