画色轮 算法
上多媒体课的时候,老师留了一个作业,就是在讲颜色组成的时候给我们看了个色轮,也简单的讲了一下计算机的颜色表示原理。就让我们自己也用程序画一个色轮;虽然以前也知道点原理,但是还真么有尝试过用程序来画色轮。开始以为很简单,就是颜色的渐变嘛,把RGB的值逐渐变化就应该行了,当时没有想这么多老师问可以画出来不,我说没问题。
但是在画的时候是没有想的那么简单的啊
开始的想法是:
1. 既然要画一个渐变的色轮,必然三原色是平均的出现在一个圆盘中的
2.RGB三个值的分量,分别在圆的三等分点上
3.各个颜色分量在基准点上开始向两边开始扩散,由于三个分量等分圆,
那么就向两边分别扩散120度吧,那么每个颜色分量就刚好扩散到相邻的等分点就结束了,也就是说从一个等分点到相邻等分点之间一个颜色分量从255递减到0或从0递增到255;
4.经过第3点的分析后那么在等分点之间就有两个颜色值得逐渐混合,从而达到颜色渐变的效果
下面是效果图:
很明显这个结果不对啊.Google加百度都没有相关的原理代码,最后下载到一个易语言的画色轮的代码,打开一看,使用中文写的源代码,顿时傻了。中文写的代码看不懂。算了还是自己分析吧。
于是把ps的色板打开分析:
其实在上面的分析中在第三点红色文字之前的分析都是对的。
1.各个原色不是从各自的基本点就开始向两边开始渐变到零,比如说R这个分量,在整个最外围的圆圈中有1/3的区域中R的值都是为255的,
2.每个原色分量的值各自向左右60度的范围都为255,然后再有60度是从255递减到0;
最后一点就是径向的变化,径向变化时就是所有的外圈的颜色逐渐向圆心变为白色,根据该点的值按百分比逐渐向圆心递增就行了;
现在也该上代码了
这个函数是根据角度获得分量颜色值的,max为原色变化范围,value为当前偏移角度
int getAngleInt(float max,float value)
{
if (Math.Abs( value) < r13) return 255;
max -= r13;
value = Math.Abs(value)- r13;
float f = value/max;
int r=255- (int)(255*(f));
return r;
}
下面这个函数就是整个分析的逻辑核心代码了,嘿嘿代码没得注释,其实也不难懂哈
private void setColor()
{
int r, g, b;
int x=0, y=0;
Color color;
float sin,sing,sinb;
float cos,cosg,cosb;
float baseangler = 0;
float baseangleg = 120;
float baseangleb = 240;
float deltat = 0.004f;
int alpha = 0;
for (float sa = -range; sa <= range; sa += deltat)
{
float f = (sa + baseangler) * j2pi;
sin = (float)Math.Sin(f);
cos = (float)Math.Cos(f);
f = (sa + baseangleg) * j2pi;
sing = (float)Math.Sin(f);
cosg = (float)Math.Cos(f);
f = (sa + baseangleb) * j2pi;
sinb = (float)Math.Sin(f);
cosb = (float)Math.Cos(f);
alpha = 255;
for (int i = 255; i >=255; i--)
{
r = getAngleInt(range, sa);
int value = r;
x = (int)(sin * i) + 255;
y = (int)(cos * i) + 255;
cw[x, y].R = value;
cw[x, y].A = alpha;
x = (int)(sing * i) + 255;
y = (int)(cosg * i) + 255;
cw[x, y].G = value;
cw[x, y].A = alpha;
x = (int)(sinb * i) + 255;
y = (int)(cosb * i) + 255;
cw[x, y].B = value;
cw[x, y].A = alpha;
}
}
pixel p;
int tr, tg, tb;
for (float sa = 0; sa <= 360.0f; sa += deltat)
{
float f = sa * j2pi;
sin = (float)Math.Sin(f);
cos = (float)Math.Cos(f);
x = (int)((255) * cos) + 255;
y = (int)((255) * sin) + 255;
p = cw[x, y];
r = p.R;
b = p.B;
g = p.G;
for (int i = 1; i<=254; i++)
{
tr =r+ (int)((255-i) / 255.0 * (255 - r));
tg = g + (int)((255 - i) / 255.0 * (255 - g));
tb = b + (int)((255 - i) / 255.0 * (255 - b));
x = (int)(i * cos) + 255;
y = (int)(i * sin) + 255;
p = cw[x, y];
p.A = 255;
p.R = tr;
p.G = tg;
p.B = tb;
}
}
for (int i = 0; i < 512; i++)
for (int j = 0; j < 512; j++)
{
p=cw[i,j];
color=Color.FromArgb(p.A,p.R,p.G,p.B);
bitmap.SetPixel(i,j,color);
}
//color.s
}
写程序的时候发现C#直接没有画点的函数,郁闷,又不想用画线的方法来代替。就想到了C#中的Bitmap有个函数是设置一个点的颜色值,那么就用它来代替画板吧,在位图中画好了在向C#的画板中绘制位图,这样在也不怕刷新界面的时候去调用复杂的计算函数了。
最后的效果如图,再双击色轮的时候可以取色到右边的色板列表,在色板列表中双击item可以把颜色值拷贝到剪贴板,按下鼠标左键在色轮中移动可以观察颜色值得变化情况
http://download.csdn.net/detail/u012706436/7104463 嘿嘿照样贴上完整源代码的连接,求下载送积分啊