Wednesday, March 21, 2007

heat map, code snippet

It's been a long time since I've posted a little code snippet that might be of use to people. (OK, not many people.) But, I wrote a function to simulate a "heat map", to map a number to a color, depending on where it falls in a range.

As mentioned previously, one way to generate a rainbow progression of colors is described here:


What I wanted to do was to write a function so that "big" numbers would yield a red color, which would then progress through yellow, then green, to light blue, to dark blue. In other words, 4 of the 6 segments in the above progression.

The following function "heatMap()" takes 3 input variables: map, min, and max. "Map" is the number you want to heat map. If it's greater than or equal to "max", the color is returned as red. From "max" to "min", the colors progress through yellow, green, light blue, and dark blue. It's a linear function, and a "map" value exactly in the middle of "min" and "max" maps to pure green. "Map" values lower than min return pure blue. It returns a vector that can be used in color-setting functions in LSL.

I used the heatMap() function for color-coding in my avatar radar HUD, so that avatar target radar blips above you were red, those at the same altitude were green, and those below you were blue, all along a spectrum of colors. I found that the color was enough information, and less cluttered than numbers.

Hope you find the function helpful :)


vector heatMap(float map, float min, float max)
{
// by Ged Larsen
// map a float to 4 of 6 segments of a color progression
//
// -1 to -0.5 <0,0,1> to <0,1,1> dark blue to light blue
// -0.5 to 0 <0,1,1> to <0,1,0> light blue to green
// 0 to 0.5 <0,1,0> to <1,1,0> green to yellow
// 0.5 to 1 <1,1,0> to <1,0,0> yellow to red

float fraction;

if (
map < min) { fraction = -1.0; }
else if (
map > max) { fraction = 1.0; }
else {
fraction = 2.0*map/(max-min)+1.0 - (2.0*max / (max-min)); }

if (
fraction < -0.5 ) { return <0.0, 2*(fraction+1), 1.0>; }
else if (
fraction < 0 ) { return <0.0, 1.0, 1.0 - 2.0*(fraction+0.5)>; }
else if (
fraction < 0.5 ) { return <2.0*fraction, 1.0, 0.0>; }
else { return <
1.0, 1.0 - 2.0*(fraction - 0.5), 0.0>; }
}