HSL转RGB函数异常求助:附代码及测试数据
Let’s jump right into solving the issue with your HSL2RGB function— I’ve spotted a couple of critical integer division bugs that are causing the incorrect gray output you’re seeing.
The Root Cause: Integer Division in Floating-Point Logic
In C++, when you use integer literals like 1/3 or 2/3, the compiler performs integer division, which truncates the result to 0 instead of the floating-point fraction you need. This breaks both the hue offset calculations and the core logic of your Hue2RGB helper function.
Specific Fixes to Apply
1. Fix the Hue2RGB Helper Function
The line handling the third hue segment uses integer division for 2/3, which evaluates to 0:
// Original broken line else if (hue * 3 < 2) { return m1 + (m2 - m1) * (2 / 3 - hue) * 6; }
Replace it with floating-point literals to force correct division:
float Hue2RGB(float m1, float m2, float hue) { if (hue < 0) { hue += 1.0f; }; if (hue > 1) { hue -= 1.0f; }; if (hue * 6.0f < 1.0f) { return m1 + (m2 - m1) * hue * 6.0f; } else if (hue * 2.0f < 1.0f) { return m2; } else if (hue * 3.0f < 2.0f) { return m1 + (m2 - m1) * (2.0f / 3.0f - hue) * 6.0f; } else return m1; }
2. Fix Hue Offsets in HSL2RGB
Your red and blue channel calculations use 1/3 (integer division, result 0), meaning all channels ended up using the same hue value:
// Original broken lines return_color.R = Hue2RGB(m1, m2, color.H + 1 / 3); return_color.B = Hue2RGB(m1, m2, color.H - 1 / 3);
Update these to use floating-point fractions:
color_RGB HSL2RGB(color_HSL color) { color.H = color.H / 360.0f; float m1, m2; if (color.L <= 0.5f) { m2 = color.L * (color.S + 1.0f); } else { m2 = color.L + color.S - color.L * color.S; } m1 = color.L * 2.0f - m2; color_RGB return_color; return_color.R = Hue2RGB(m1, m2, color.H + 1.0f / 3.0f); return_color.G = Hue2RGB(m1, m2, color.H); return_color.B = Hue2RGB(m1, m2, color.H - 1.0f / 3.0f); return_color.a = 1.0f; return return_color; }
Bonus: Fix a Hidden Bug in RGB2HSL
You mentioned your RGB2HSL function is verified, but I noticed a logical error that would fail when the blue channel is the maximum value:
// Original broken condition (can never be true) if (max == color.R && max != color.R) { H += 4 + (color.R - color.G) / delta; }
Replace it with the correct condition for blue being the max:
if (max == color.B) { H += 4.0f + (color.R - color.G) / delta; }
Testing the Fix
With these changes, converting your test HSL value {H=351.600006, S=0.499999970, L=0.196078449} back to RGB should return a value very close to your original {R=0.294117659, G=0.0980392247, B=0.125490203} (minor floating-point precision differences are expected).
内容的提问来源于stack exchange,提问作者Major Despard

