Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evenly Distributed Color Range Depending On A Count

I have a legend that I need to be color coordinated and have pretty much an infinite range of colors (infinite in the terms of 50-100 identifiers. I would like to use the color spectrum like a rainbow and evenly distribute colors from the number of items in the legend. For example.

I have pool A, B, and C, and would like them to be distinguised by color. A is red, B is orange, and C is green, etc. I would like to dynamically have this figured out using the hex color code going from 000000 to FFFFFF. So my pools would evenly pick three colors in that range. If I had 10 pools, it evenly pick 10 colors and so on. What would be the best algorithm to do this?

This will be done in javascript, but would love to have it done in SASS.

like image 204
Mike Flynn Avatar asked Jan 26 '26 07:01

Mike Flynn


2 Answers

I strongly recommend to let the algorithm be a human being: Let somebody, who knows the trade, select 100 colors for you (with the most pleasing to the eye first), use this as a static array and just use index 0..N-1.

That said: A common algorithm is to use the PAL/NTSC color model:

R=Y+V/0.88
G=Y-0.38*U-0.58*V
B=Y+U/0.49

With U/V being the coordinates of the color and Y being the brightness.

So you create a circle of radius 1 with center at 0/0 in the U/V-plane and mark N points on it - this can easily be done with U=cos(phi), V=sin(phi) and phi going 0..360 degrees in N steps. This gives you an array of N (U/V) tuples.

Using an eye-plesing Y (ca. 0.5) you calculate the RGB-Values like above, resulting in an array of N (R/G/B) tuples.

like image 167
Eugen Rieck Avatar answered Jan 29 '26 04:01

Eugen Rieck


Not sure exactly what you're asking, but this may help. It spits out a color of the rainbow from w=0 (red) to w=1.0 (purple). If you wanted to divide it evenly between N colors, I would do this:

for(int i = 0; i<N; i++){
  colors[i] = spectrum(i/((double)(N-1)));
}

Using this method:

public Color spectrum(double w) {
if (w>1)w=1;
if (w<0)w=0;

w=w*(645-380)+380;
double R,B,G;
if (w >= 380 && w < 440){
    R = -(w - 440.) /(440. - 350.);
    G = 0.0;
    B = 1.0;
}
else if (w >= 440 && w < 490){
    R = 0.0;
    G = (w - 440.) /(490. - 440.);
    B = 1.0;
}
else if (w >= 490 && w < 510){
    R = 0.0;
    G = 1.0;
    B = (510-w) /(510. - 490.);
}
else if (w >= 510 && w < 580){
    R = (w - 510.) /(580. - 510.);
    G = 1.0;
    B = 0.0;
}
else if (w >= 580 && w < 645){
    R = 1.0;
    G = -(w - 645.) /(645. - 580.);
    B = 0.0;
}
else if (w >= 645 && w <= 780){
    R = 1.0;
    G = 0.0;
    B = 0.0;
}
else{
    R = 0.0;
    G = 0.0;
    B = 0.0;
}
return new Color(R,G,B);

}

Sorry it's not in javascript. I am much more fluent in Java. The numbers in there map to wavelengths in nanometers, so it's useful for all kinds of stuff. The R,G,B values can of course be converted to ints by multiplying by 255 and truncating decimals.

like image 25
Chet Avatar answered Jan 29 '26 03:01

Chet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!