psihodelia - 9 months ago 63

C Question

I have a function f(x,y), mostly monotonic, which produces some values in the range {0.0 .. 100.0}. I would like to draw them using different colors as a 2D picture, where (x,y) are coordinates and where distinctive colors stand for distinctive values of the function. The problem is following: I don't know how to map the values of this function to RGB color space preserving the order (visibly). I have found that smth. like:

`R = f(x,y) * 10.0f;`

G = f(x,y) * 20.0f;

B = f(x,y) * 30.0f;

color = B<<16|G<<8|R; //@low-endian

works fine, but the resulting picture is too dark. If I increase these constants, it makes things not better, because at some moment a color component will be greater than 0xFF, so it will overflow (one color component should be in the range {0 .. 0xFF}.

Do you have any idea how to map values from {0.0 .. 100.0} to

RGB=[{0 .. 0xFF}<<16|{0 .. 0xFF}<<8|{0 .. 0xFF}] so that the resulting RGB values are visibly Ok?

PS: maybe you know, where to find more info about related theory online? I remember only Comp.Graphics by Foley/Van Dam, but I don't have this book.

UPDATE: I am looking for how to generate a chroma palette like one on the right:

Answer

You could just try clamping the values to a maximum of 255 (0xff).

```
R = min((int)(f(x,y) * 10.0f), 0xff);
G = min((int)(f(x,y) * 20.0f), 0xff);
B = min((int)(f(x,y) * 30.0f), 0xff);
```

**Edit:** There are a lot of different ways to convert to colors automatically, but you might find that none of them generates the exact progression you're looking for. Since you already have a picture of an acceptable palette, one method would be to create a lookup table of 256 colors.

```
#define RGB(R,G,B) (B<<16|G<<8|R)
int palette[256] = { RGB(0,0,0), RGB(0,0,128), ... };
int greyscale = (int)(f(x,y) * 2.559999);
assert(greyscale >= 0 && greyscale <= 255);
int rgb = palette[greyscale];
```

If the lookup table is too much trouble, you could also break the greyscale range into different subranges and do a linear interpolation between the endpoints of each range.

```
int interpolate(int from, int to, double ratio)
{
return from + (int)((to - from) * ratio);
}
if (greyscale <= 48)
{
R = 0;
G = 0;
B = interpolate(0, 255, greyscale/48.0);
}
else if (greyscale <= 96)
{
R = 0;
G = interpolate(0, 255, (greyscale-48)/48.0);
B = interpolate(255, 0, (greyscale-48)/48.0);
}
else if ...
```

Source (Stackoverflow)