将颜色从HSL转换为RGB时出现问题。我写了以下函数:
struct RGB {
float r, g, b;
};
RGB hslToRgb( float hue, float saturation, float lightness ) {
RGB rgb1, rgbResult;
float chroma = ( 1.0 - (float) abs( 2.0 * lightness - 1.0 ) ) * saturation;
float h1 = hue / 60.0;
float x = chroma * ( 1.0 - (float) abs( (float) ( (int) h1 % 2 ) - 1.0 ) );
if ( ( 0 <= h1 ) && ( h1 < 1 ) ) {
rgb1.r = chroma;
rgb1.g = x;
rgb1.b = 0.0;
} else if ( ( 1 <= h1 ) && ( h1 < 2 ) ) {
rgb1.r = x;
rgb1.g = chroma;
rgb1.b = 0.0;
} else if ( ( 2 <= h1 ) && ( h1 < 3 ) ) {
rgb1.r = 0.0;
rgb1.g = chroma;
rgb1.b = x;
} else if ( ( 3 <= h1 ) && ( h1 < 4 ) ) {
rgb1.r = 0.0;
rgb1.g = x;
rgb1.b = chroma;
} else if ( ( 4 <= h1 ) && ( h1 < 5 ) ) {
rgb1.r = x;
rgb1.g = 0.0;
rgb1.b = chroma;
} else if ( ( 5 <= h1 ) && ( h1 < 6 ) ) {
rgb1.r = chroma;
rgb1.g = 0;
rgb1.b = x;
} else {
rgb1.r = 0.0;
rgb1.g = 0.0;
rgb1.b = 0.0;
}
float m = lightness - 0.5 * chroma;
rgbResult.r = rgb1.r + m;
rgbResult.g = rgb1.g + m;
rgbResult.b = rgb1.b + m;
return rgbResult;
}
这是它的测试:
float cHue = 0.0;
while ( cHue < 360 ) {
RGB rgb1 = hslToRgb( (int) cHue, 1.0, 0.5 ); // max on saturation and a middle value for lightness
printf( "r = %f, g = %f, b = %f\n", rgb1.r, rgb1.g, rgb1.b );
cHue += 1.0;
}
但是当我需要获得这个“整数”之间的所有范围时,我只得到1.0和0.0。
r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 0.000000
r = 1.000000, g = 0.000000, b = 0.000000
r = 1.000000, g = 0.000000, b = 0.000000
任何人都可以帮我这个代码吗? 公式来自:http://en.wikipedia.org/wiki/HSL_and_HSV
答案 0 :(得分:4)
将浮点模fmodf
用作:
float x = chroma * ( 1.0 - (float) abs( fmodf(h1, 2.0) - 1.0 ));
答案 1 :(得分:1)
在C ++代码中停止使用C风格的强制转换(如(int)
和(float)
)。需要浮点绝对函数时,请使用fabs
。将复杂的公式分解为多个步骤,在一条线上完成所有操作都无法获得任何效率。
每行进行1次计算。使用描述性名称将结果存储在您认为需要的类型的变量中。看看你是否可以避免使用int
,除非你应该明确地舍入。
答案 2 :(得分:0)
您的色度值似乎已关闭。你有它
float chroma = ( 1.0 - (float) abs( 2.0 * lightness - 1.0 ) ) * saturation;
但我认为应该是
float chroma = saturation * lightness;
自维基百科说,
From HSV
Given a color with hue H ∈ [0°, 360°), saturation SHSV ∈ [0, 1], and value V ∈ [0, 1],
we first find chroma:
C = V \times S_{HSV}
答案 3 :(得分:-1)
在你的行上:
float x = chroma * ( 1.0 - (float) abs( (float) ( (int) h1 % 2 ) - 1.0 ) );
为模数转换(int)
会导致它删除浮点数的所有小数。从而使这成为二元函数。
您需要一个浮点模数函数,如Michael Sh described。