画随机块(100分)

  • 主题发起人 主题发起人 有助
  • 开始时间 开始时间

有助

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在做一套屏幕保护程序,需要实现随机块效果,即随机地从源画布拷贝一小块,图像
到目标画布,直到目标画布被铺满为止。随机块的大小计划有三种规格,一种是2x2像素的,
一种是5x5像素的,还有一种是10x10像素的(就像Stardust公司的Stardust ScreenSaver
Toolkit制作出的屏保效果那样),算法该如何设计?我看一本介绍C++ Builder的书上看
到一个算法,但是不符合我的要求,而且速度太慢:

if (x<300){
int i,j;
while (b[i=random(15)][j=random(20)]);
Bit1->Canvas->CopyRect(Rect(30*j,30*i,30*j+30,30*i+30),
Bit2->Canvas,
Rect(30*j,30*i,30*j+30,30*i+30));
Canvas->Draw(0,0,Bit1);
b[j]=true;
x++;
}

其中x为全局整数型变量,b[][]为全局逻辑型数组

上面这个算法是把一个600x450像素的图分为横20,纵15共300个30x30像素的块,并定义
一个逻辑数组,每当写了一个块后就把相应的数组b[][]中的成员标识为True,即已写,
这个过程放在一个Timer的OnTimer事件过程中执行,但运行速度太过于慢了,我需要一个
更快的算法,并且不能在OnTimer过程中执行,必须在一个循环中执行。
 
肯定用线程啦。
 
这个算法有些莫名其妙的说,为什么不直接用copyrect把图象拷贝的屏幕。试试下面的
算法。

if (x<300){
int i,j;
while (b[i=random(15)][j=random(20)]);
Canvas->CopyRect(Rect(30*j,30*i,30*j+30,30*i+30),
bit2->Canvas,
Rect(30*j,30*i,30*j+30,30*i+30));
b[j]=true;
x++;
}
也就是省去了中间变量bit1,以前的算法有很多时间都花在bit1的拷贝和绘制上了。现在可以
很快了。


 
大家不如这样想:
我需要往一个有A x B个元素的矩阵里随机地填数据,已经填过数据的单元里就不再填入,
直到所有的单元都填满为止,如何实现这一算法?
 
建立一个A*B 数组对应A*B矩阵中的单元块,初始数组变量的值为0,算法中
填一个单元的话,就把这个单元所对应的数祖值设为1.下次随机选择时候把范围定
在值为0的单元中.继续填充......
下次我会贴出源程序的.
 
Step 1: 定义一个长度为图块总数的数组并初始化。
Step 2: 打乱数组内容。
Step 3: 进行图块拷贝。

void __fastcall TForm1::FormDblClick(TObject *Sender)
{
//把800*600像素的位图分为4*4像素的小块,共计30000个小块

const MCount=30000;
int i,j;
TPoint temp;
TPoint Dest[MCount];
Graphics::TBitmap *BufPic = new Graphics::TBitmap;

BufPic->LoadFromFile("C://Mydocu~1//ScrSnap1.bmp");

//初始化数组
for (i=0; i<MCount; i++){
Dest.x = (i%200)*4; //设矩阵的水平坐标元素值
Dest.y = (i/200)*4; //设矩阵的垂直坐标元素值
}

randomize();
//打乱数组内容
for (i=0; i<MCount; i++){
j = random(MCount);
temp = Dest;
Dest = Dest[j];
Dest[j] = temp;
}

//拷贝图块
for (i=0; i<MCount; i++){
for (j=0; j<5000; j++){ //因为速度太快,需要人为延迟一下
j = j*2/2;
}
Canvas->CopyRect(Rect(Dest.x,Dest.y,Dest.x+4,Dest.y+4),
BufPic->Canvas, Rect(Dest.x,Dest.y,Dest.x+4,Dest.y+4));
}
delete BufPic;
}
//---------------------------------------------------------------------------
 
我想速度问题可能不是运算问题,而是图形的处理的问题,我的方法是在程序运行前先随机
分块,然后存入一个TMemoryStream数组中, 显示时从流中读出。
 
纯粹随机肯定不好的,因为它不会区分已经填充的区域和未填充的区域
Sachow的方法比较好。
 
上面那段代码由于有“<”号,代码又被吞掉两段,请查看源文件或到XML版上去看。
 
多人接受答案了。
 
后退
顶部