渐变图形问题---->200分 请各位高人指教!!!!!!!(200分)

  • 主题发起人 主题发起人 hongdu
  • 开始时间 开始时间
H

hongdu

Unregistered / Unconfirmed
GUEST, unregistred user!
__________
| A | B |
|____|____|
| C | D |
|____|____|
在如上的方块中,A块中心点为红色,B块中心点为蓝色,C块中心点为绿色,D块中心点为白色,能否有这样的算法,在这四块中实现均匀的渐变,即颜色混合.
请各位高人指教!!!!!!!
 
请各位高人指教!!!!!!!
 
这是个有趣的问题,具体怎么做我还没想好,但基本思路是这样:
因为每一点都可以用rgb(red,green,blue)表示,你可以根据图中任一点离red,green,blue
的距离来确定该点的rgb值。white = rgb(255,255,255)
我先做一个实验,please wait...
 
我的基本思路是这样:
|1 |2 线1是红色的,线2是兰色的,这是一维的渐变,
| |
|------->|
| |
--------- 1
|
|
|
--------- 2
两者合成后的结果我想可以满足,可是算法没有想出!!!!!
 
我真的头晕了,我不知道白点往外会是什么颜色???
 
怎么才叫均匀呢?在四个点中间的部分还好办,可以直接按照当前点到各中心点的
距离来算。仿照有四个有质量的球体,在其周围产生立场的计算方法,
就是 Fx = color / r^2 , x 取1-4,
计算出各点的Fx值再相加。最后做一次线性的变换,映射到颜色空间中去。
在这个部分之外的,就要看你想最后边框是什么颜色。
 
先不考虑白点外的问题,画出框来再说.
var x,y:integer;
begin
for x:=0 to 255do
for y:=0 to 255do
Canvas.Pixels[x,y]:=rgb(255-trunc(abs(y-x)),y,x);
end;
稍候再改进...
 
我的思路是,矩形四个中心点是纯粹的红,兰,白,绿,即饱和色,以这四点分别为中心
向外扩散,也就是分四次扫描,每次扫描将整个大矩形的每一点的R,G,B,亮度值分别按照它距相应中心点的距离进行线性或非线性衰减.
当然,由于矩形的对称性,可将四次扫描结合在一起,例如某点X距红点的距离等于
X的中心对称点X'距白点D的距离.
 
白点其实就是R=G=B=255,向外扩散时R,G,B要同时变.
 
我想,边框应该是黑的!
 
menxin:我也曾有此感,但仔细想一下你会知道不是这样!
首先白色附近不可能是黑边框!
然后其他颜色附近也不可能是黑边框,因为无法解释255->0 !
我觉得由于白色的存在,导致设计颜色算法时的问题-- 白色在中心或许好一点!
 
最好选无穷远为黑色.构造一函数F(0)=1,F(Infinite)=0
例如,f(x)=arccotan(x)/(Pi/2)
或 f(x)=exp(-x)
 
若只在四个方框中渐变一种颜色是可以的,但好象你还要求这四个方框的颜色混和
则有点差强人意,因为你要对三基色进行编程,这可不件容易的事。若有三个单色
光源通过变换一定的位置可得出五颜六色的颜色,但用程序则是困难的。
 
向下一步做太复杂,其它人想吧,我撤!
 
程序如下:
me选了一个不太好的函数作渐变函数(//shy),exp下降太快,不得不对局离开了
几重根号;计算距离只对1/16的正方形进行,可充分利用它的对称性.
image大小:200*200

procedure TForm1.FormCreate(Sender: TObject);
var
i,j:integer;
Saturation:array [0..3] of Integer;
begin
for i:=0 to 100do
for j:=0 to ido
begin
Saturation[0]:=round(255*exp(-Sqrt(Sqrt(Sqrt(Sqrt((i-50)*(i-50)+(j-50)*(j-50)))))));
Saturation[1]:=round(255*Exp(-Sqrt(Sqrt(Sqrt(Sqrt((i-150)*(i-150)+(j-50)*(j-50)))))));
Saturation[2]:=round(255*Exp(-Sqrt(Sqrt(Sqrt(Sqrt((i-50)*(i-50)+(j-150)*(j-150)))))));
Saturation[3]:=round(255*Exp(-SQrt(Sqrt(Sqrt(Sqrt((i-150)*(i-150)+(j-150)*(j-150)))))));
Image1.Canvas.Pixels[i,j]:=RGB(Saturation[0]+Saturation[3],
Saturation[1]+Saturation[3],saturation[2]+Saturation[3]);
Image1.Canvas.Pixels[j,i]:=RGB(Saturation[0]+Saturation[3],
Saturation[2]+Saturation[3],saturation[1]+Saturation[3]);
Image1.Canvas.Pixels[j,200-i]:=RGB(Saturation[1]+Saturation[2],Saturation[3]+Saturation[2],saturation[0]+Saturation[2]);
Image1.Canvas.Pixels[i,200-j]:=RGB(Saturation[2]+Saturation[1],Saturation[3]+Saturation[1],saturation[0]+Saturation[1]);
Image1.Canvas.Pixels[200-i,200-j]:=RGB(Saturation[3]+Saturation[0],Saturation[2]+Saturation[0],saturation[1]+Saturation[0]);
Image1.Canvas.Pixels[200-j,200-i]:=RGB(Saturation[3]+Saturation[0],Saturation[1]+Saturation[0],saturation[2]+Saturation[0]);
Image1.Canvas.Pixels[200-j,i]:=RGB(Saturation[2]+Saturation[1],Saturation[0]+Saturation[1],saturation[3]+Saturation[1]);
Image1.Canvas.Pixels[200-i,j]:=RGB(Saturation[1]+Saturation[2],Saturation[0]+Saturation[2],saturation[3]+Saturation[2]);
end
end;
 
用blur算法最简单 :)
原理:
for i := bdo
wnto 1do
for j := 0 to heightdo
for x := 0 to widthdo
scanline[j][x] := (scanline[j-b][x] +
scanline[j][x-b] +
scanline[j][x+b] +
scanline[j+b][x]) shr 2;
b 为blur数值, 一般3-5就满足要求了(超过7就基本融合了).
上面算法加进边界检查即可.
 
抱歉写错了:
for i := bdo
wnto 1do
for j := 0 to heightdo
for i := 0 to width * 3do
scanline[j][x] := (scanline[j-b][x-b] +
scanline[j-b][x+b] +
scanline[j+b][x-b] +
scanline[j+b][x+b]) shr 2;
 
这两天做个Xeon Grid控件做得头晕, 竟然两遍都写错. 再写错的话以后eYes就此消失.
这次加上了边界检查:
procedure Blur(b: Integer;
Bmp: TBitmap);
var
i, j, x: Integer;
Line1, line2, Color1, color2: Integer;
begin
with bmpdo
begin
PixelFormat := pf24bit;
// pixelformat must be pf24bit
for i := bdo
wnto 1do
for j := 0 to height - 1do
for x := 0 to width * 3 - 1do
begin
if (j - i) < 0 then
line1 := 0
else
line1 := j - i;
if (j + i) >= height then
line2 := height - 1
else
line2 := j + i;
if x - i * 3 < 0 then
color1 := x
else
color1 := x - i * 3;
if x + i * 3 >= width * 3 then
color2 := x
else
color2 := x + i * 3;
scanline[j][x] := ( scanline[line1][color1] +
scanline[line1][color2] +
scanline[line2][color1] +
scanline[line2][color2] ) shr 2;
end;
end;

:(
 
感谢大家这么热情的帮我,其实边界的颜色我们定为固定色,说明白点是蓝色,
这个算法的目标是解决一个场值动态图形显示,用不同的颜色来表示各点的场强.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部