对于绘图过程,我有以下三个功能:
void setpen(R, G, B)
- 设置当前画笔的颜色
void putpixel(X, Y)
- 使用画笔将像素置于X Y
我正在尝试绘制HSV渐变:
使用这对代码:
int S, H;
for(S = 0; S<255; S++)
{
for(H = 0; H<255; H++)
{
setpen(S, H, H);
putpixel(S, H);
}
}
但是从这段代码中得出的渐变是:
不喜欢它看起来很糟糕,但它不是我真正想要的结果。另外正如我所看到的那样,在右上方有一些正确的东西..但是在左下角它是青色的。 请问,我的代码有什么问题吗?
答案 0 :(得分:3)
根据您的显示,您需要一个具有固定色调(红色),饱和度上升和值正确的渐变。
使用H = 0
(红色色调)将颜色从HSV转换为RGB时:
- R = V
- G = B = V * (1 - S)
对于您的情况,对于x
中的某些y
和[0; 255]
,您需要以下内容:
- V = x
,因此R = x
;
- S = 255-y
,因此G = B = x * y
。
因此,您可以将此次通话更改为setpen
:
setpen(S, (H*S) / 255, (H*S) / 255);
答案 1 :(得分:2)
你正在使用变量S和H.我假设你打算这个代表“饱和度”和“色调”,但你真正想要的是“饱和度”和“亮度”(或“值”),因为色调总是红色的。从左到右(内环)工作,我们的亮度将从零到255。
您需要一个从HSL转换为RGB的功能。我从this website找到了这样一个函数的实现,并在下面重现。
void HSLtoRGB( int *r, int *g, int *b, int h, int s, int l )
{
int i;
double f, p, q, t;
if( s == 0 ) {
// achromatic (grey)
*r = *g = *b = l;
return;
}
h /= 60.0; // sector 0 to 5
i = floor( h );
f = h - i; // factorial part of h
p = l * ( 255 - s );
q = l * ( 255 - s * f );
t = l * ( 255 - s * ( 1 - f ) );
switch( i ) {
case 0:
*r = (int) l;
*g = (int) t;
*b = (int) p;
break;
case 1:
*r = (int) q;
*g = (int) l;
*b = (int) p;
break;
case 2:
*r = (int) p;
*g = (int) l;
*b = (int) t;
break;
case 3:
*r = (int) p;
*g = (int) q;
*b = (int) l;
break;
case 4:
*r = (int) t;
*g = (int) p;
*b = (int) l;
break;
default: // case 5:
*r = (int) l;
*g = (int) p;
*b = (int) q;
break;
}
}
要将其绑定到您的代码中,只需执行以下操作:
int H, S, L;
H = 0; // ranges from 0 to 359 (degrees), 0 == red
for(S = 0; S<255; S++)
{
for(L = 0; L<255; L++)
{
int r, g, b;
HSLtoRGB(&r, &g, &b, H, S, L);
setpen(r, g, b);
putpixel(L, 255-S);
}
}