Paul
Paul

Reputation:

Mapping colors to an interval

I'm porting a MATLAB piece of code in C/C++ and I need to map many RGB colors in a graph to an integer interval.

Let [-1;1] be the interval a function can have a value in, I need to map -1 and any number below it to a color, +1 and any number above it to another color, any number between -1 and +1 to another color intermediate between the boundaries. Obviously numbers are infinite so I'm not getting worried about how many colors I'm going to map, but it would be great if I could map at least 40-50 colors in it.

I thought of subdividing the [-1;1] interval into X sub-intervals and map every one of them to a RGB color, but this sounds like a terribly boring and long job.

Is there any other way to achieve this? And if there isn't, how should I do this in C/C++?

Upvotes: 3

Views: 1581

Answers (2)

dantswain
dantswain

Reputation: 5467

If performance isn't an issue, then I would do something similar to what High Performance Mark suggested, except maybe do it in HSV color space: Peg the S and V values at maximum and vary the H value linearly over a particular range:

s = 1.0;  v = 1.0;
if(x <= -1){h = h_min;}
else if(x >= 1){h = h_max;}
else {h = h_min + (h_max - h_min)*0.5*(x + 1.0);}

// then convert h, s, v back to r, g, b - see the wikipedia link

If performance is an issue (e.g., you're trying to process video in real-time or something), then calculate the rgb values ahead of time and load them from a file as an array. Then simply map the value of x to an index:

int r, g, b;
int R[NUM_COLORS];
int G[NUM_COLORS];
int B[NUM_COLORS];

// load R, G, B from a file, or define them in a header file, etc

unsigned int i = 0.5*(x + 1.0);
i = MIN(NUM_COLORS-1, i);

r = R[i];  g = G[i];  b = B[i];

Upvotes: 5

High Performance Mark
High Performance Mark

Reputation: 78316

Here's a poor solution. Define a function which takes an input, x, which is a float (or double) and returns a triplet of integers each in the range 0-255. This triplet is, of course, a specification of an RGB color.

The function has 3 pieces;

if x<=-1 f[x] = {0,0,0}

if x>= 1 f[x] = {255,255,255}

if -1<x<1 f[x] = {floor(((x + 1)/2)*255),floor(((x + 1)/2)*255),floor(((x + 1)/2)*255)}

I'm not very good at writing C++ so I'll leave this as pseudocode, you shouldn't have too much problem turning it into valid code.

The reason it isn't a terribly good function is that there isn't a natural color gradient between the values that this plots through RGB color space. I mean, this is likely to produce a sequence of colors which is at odds to most people's expectations of how colors should change. If you are one of those people, I invite you to modify the function as you see fit.

For all of this I blame RGB color space, it is ill-suited to this sort of easy computation of 'neighbouring' colors.

Upvotes: 0

Related Questions