I'm trying to draw a color wheel in HSI color space. The color wheel I get has cyan, yellow, and magenta very wide, which just looks wrong. All other color wheels I've seen have red, green, and blue having the widest bands.
Is this just how the HSI color wheel looks? Or is my math wrong? I've tried every snippet for HSI to RGB I can find, and looked the equation up in books. The equation has a lot of variations, but they all lead to the same result when I draw my circle. The only thing I'm doing differently is clamping the channels at the end. My Intensity is 1.0 everywhere, the Hue is the angle of the pixel (rotated a little extra), and the Saturation is the magnitude of the distance to the center.
Here is my messy code for converting HSI to RGB (Objective-C):
float r;
float g;
float b;
S = S > 1.0f ? 1.0f : S;
I = I > 1.0f ? 1.0f : I;
H = H > 1.0f ? H - 1.0 : H;
H = H * M_PI * 2.0;
H = fmod(H, M_PI * 2.0);
if(S==0.0f){
r = I;
g = I;
b = I;
} else{
if((H>=0.0) && (H<2.0*M_PI/3.0)){
b = (1.0f-S)/3.0f;
r = (1.0f + S*cosf(H) / cosf(M_PI/3.0-H))/3.0f;
g = 1.0f-r-b;
} else if((H>=2.0*M_PI/3.0) && (H<4.0*M_PI/3.0)){
H = H - 2.0f*M_PI/3.0f;
r = (1.0f-S)/3.0f;
g = (1.0f+S*cosf(H)/cosf(M_PI/3.0 - H))/3.0f;
b = 1.0f-r-g;
} else if ((H>=4.0*M_PI/3.0) && (H<2.0*M_PI)){
H= H-4.0f*M_PI/3.0f;
g = (1.0f-S)/3.0f;
b = (1.0f+S*cosf(H)/cosf(M_PI/3.0-H))/3.0f;
r = 1.0f-b-g;
}
}
if(r<0.0f)
r=0.0f;
if(g<0.0f)
g=0.0f;
if(b<0.0f)
b=0.0f;
float R = 3.0f*I*r;
float G = 3.0f*I*g;
float B = 3.0f*I*b;
if(R>1.0f)
R=1.0f;
if(G>1.0f)
G=1.0f;
if(B>1.0f)
B=1.0f;
After reading the comments, it became clear that clamping the RGB values was causing the CMY bias. Decreasing the intensity removed the bias, but there were still strange banding issues, and the color wheel still didn't look like anyone else's color wheel. This result makes sense given the math, but for some reason, nobody mentions these problems anywhere in any of the books or online information about HSI. People show HSI color wheels that look like HSV/B color wheels, but I still have no idea how they got that result when converting to RGB.
The solution: I switched to HSV color space, which turned out to fit my requirements better than HSI.