2

Possible Duplicate:
android color between two colors, based on percentage?
How to find all the colors between two colors?

At the beginning, we have two colors in RGB, and a number, for the intermediate colors between them. Method must return an array with required colors. Strongly need help with an algorithm.

Community
  • 1
  • 1
NiLL
  • 13,645
  • 14
  • 46
  • 59
  • [Homework](http://meta.stackexchange.com/q/10811/)? – outis Jun 23 '12 at 22:03
  • Nope, it's for my hobby project ^_^ – NiLL Jun 23 '12 at 22:05
  • possible duplicate of [How to find all the colors between two colors?](http://stackoverflow.com/q/6025043/). See also [Color interpolation between 3 colors](http://stackoverflow.com/q/5406681/), [How to interpolate a color sequence?](http://stackoverflow.com/q/5860100/), [Non-Linear color interpolation?](http://stackoverflow.com/q/3017019/). – outis Jun 23 '12 at 22:12
  • ... [Generating a list of colors, blue through red, 0% through 100%](http://stackoverflow.com/q/3642430/), [Fastest way to calculate colors for a gradient?](http://stackoverflow.com/q/8252996/), [colour range in javascript](http://stackoverflow.com/q/4285475/), [Color generation function](http://stackoverflow.com/q/875270/). – outis Jun 23 '12 at 22:25
  • 1
    [Programmers.SE](http://programmers.stackexchange.com/) is a better fit for whiteboard problems, such as algorithm design. – outis Jun 23 '12 at 22:26

2 Answers2

7

Suppose we have 2 Colors (R1,G1,B1) (R2,G2,B2) and N number of intermediate colors:

for i from 1 to N:
    Ri = R1 + (R2-R1) * i / N
    Bi = B1 + (B2-B1) * i / N
    Gi = G1 + (G2-G1) * i / N
    AddToArray(Ri,Gi,Bi)

Is that what you are looking for?

PS: I would recommend using the HSL color space instead of the RGB if you want to have a more natural color gradient.

Samy Arous
  • 6,794
  • 13
  • 20
  • 1
    For reference, this is called 'linear interpolation'. – phs Jun 23 '12 at 22:11
  • wouldn't that be a Trilinear interpolation instead? (yes, I know it is an extension of a linear interpolation :)) – Samy Arous Jun 23 '12 at 22:14
  • No, it's still linear interpolation, because you're only filling in points along a line - it's linear interpolation along each dimension. Bilinear interpolation is what you would use for resizing an image, and trilinear interpolation is used for interpolating a volume. The interpolation needed here must generate a function that maps an integer to a color, but trilinear interpolation would be to map a vector or point in 3d space to a value. – user57368 Jun 23 '12 at 22:37
  • As pointed out by Charles Ma in its reply, doing this in the RGB color space produces poor results. It's much better to convert the colors to HSV, perform the linear interpolation there and then convert back to RGV – salva Jun 23 '12 at 23:31
2

Let your current cR, cG and cB value be 0%, and let the R, G, and B values be 100%, then you just have to iterate i = 1 to 100 with each iteration adding cRGB + i * (RGB - cRGB). You don't have to use 100 intermediate colors, you can use N of them.

function(currentColor, desiredColor, N) {

    var colors = [],
    cR = currentColor.R,
    cG = currentColor.G,
    cB = currentColor.B,
    dR = desiredColor.R - cR,
    dG = desiredColor.G - cG,
    dB = desiredColor.B - cB;

    for(var i = 1; i <= N; i++) {
        colors.push(new Color(cR + i * dR / N, cG + i * dG / N, cB + i * dB / N));
    }

    return colors;
}

However, that won't give you very good intermediate colors. The first thing you should do is convert your colors into HSV or similar colorspace where intensity is separate from hue and saturation. That will give you much better intermediate colors. http://en.wikipedia.org/wiki/HSL_and_HSV

To do that, first convert your colors to HSV, and run the same algorithm as above, but with H S and V instead of RGB, but keep in mind that S and V have a min of 0 and max of 1, while H is represented in degrees between 0 and 360. You might have to do something with H if you want it to go from the current color to destination color as quickly as possible e.g. if cH = 10 and dH = 50, then going from 10 -> 50 is shortest, but if cH = 10 and dH = 350, then going from 10 -> -10 (same as 350 degrees) is shorter.

Charles Ma
  • 47,141
  • 22
  • 87
  • 101