I was in need to create a nice set of RGB values to represent a
Bellow is small snippet of code to create a 8 bit RGB values based on 8 bit hue. It will generate raibow colours starting from red with input value 0 to violet with input value 255. No floating point operation is used in calculation.
Algorithm is based on what is described in Wikipedia in HSV to RGB section.
Algorithm description
Performing HSV to RGB conversion assuming value and saturation at maximum i.e V=S=1. I only map H values from 0 to 300 degree, dropping last 60 degree to.
H1 = H / 60. 0 <= H1 <= 6 // will be using only <= 5
Value: V = 1
Saturation: S = 1
Chroma: C = V * S = 1
X = C x ( 1 - | H1 mod 2 - 1 | ) = 1 - | H1 mod 2 - 1 |
( R 1 , G 1 , B 1 ) = {
( C , X , 0 ) if 0 ≤ H1 < 1
( X , C , 0 ) if 1 ≤ H1 < 2
( 0 , C , X ) if 2 ≤ H1 < 3
( 0 , X , C ) if 3 ≤ H1 < 4
( X , 0 , C ) if 4 ≤ H1 < 5
( C , 0 , X ) if 5 ≤ H1 < 6 }
m = V - C = 0
R,G,B = R1 + m,G1 + m, B1 + m = R1,G1,B1
Code
It is written to be use in OpenCL kernel module. So it is C with some extensions.
FYI: uint3 == unsigned int[3]
uint3 rainbow(int position) {
// Feed position 0 <= position <= 255 and get rainbow colour
__private int H1 = abs(position) % 255; //I'm paranoid
// H is going between 0 and 300 degree, no need for 300 - 360 part for rainbow
__private uint X = 255 - abs( 255 - (( H1 * 5 ) % 510 )); // this should create a zigzag between 0 and 255 repeating 2.5 times for H between 0 and 300
switch ( H1 / 51 ) {
case 0 : return((uint3)(255,X,0));
case 1 : return((uint3)(X,255,0));
case 2 : return((uint3)(0,255,X));
case 3 : return((uint3)(0,X,255));
case 4 : return((uint3)(X,0,255));
case 5 : return((uint3)(255,0,X));
};
};