现在的位置: 首页 > 综合 > 正文

[分形]DLA团簇模型的摸拟

2013年01月11日 ⁄ 综合 ⁄ 共 6079字 ⁄ 字号 评论关闭

[分形]DLA团簇模型的摸拟

EmilMatthew(EmilMatthew@126.com)        

      

1前言:

       DLA团簇模型是分形成长中的一个很易于实现的模型.(当然啦,背后的理论工作是非常高有难度的,涉及到代数,泛函分析,非线性偏微分方程等知识。我们就拿着别人的研究出的成果,来感受一下其中的美妙吧J)

       团簇模型最初是80年代初T.A.WittenL.M.Sander在研究悬浮在溶液或大气中的金属粉末,煤灰和烟尘等微粒的无规扩散凝聚过程中得出的研究成果.

      

2DLA模型的摸拟规则:

a在某个规定好大小的画布的中心处O随机的产生少量粒子.

b在以中心O为圆心,以Rmax为半径的圆周的周围(Rmax稍大,Rmax+d)

随机的生成新的粒子。新粒子随即进行随机的游走------上下左右四个方向。

       如果游走至原来粒子的附近(即一个已吸收粒子的上下左右的任何一个方位),则该粒子认为被吸收。

       如果游戏的粒子走出了距离中心点2*Rmax的距离,则删去这个粒子.

       c当产生粒子数少于规定的最大粒子数时,则重复b.

      

       采用5000个粒子总数,画布大小为400*400的模拟效果如下:

                                      

 

       3程序整体设计:

       While(test particle num<require num)

              {

                            Init a new particle ar Rmax+d circle’s side;

                            While(particle is not restored or particle is not out of  2*Rmax)

                            {

                                          Next pos selection;

                                          Particle move to next step;

Detect whether particle is near the bound of the particles which have been stored.

                                          {

                                                 If(“yes”)

                                                        Update the map matrix , particle restored.

}

}

}

 

       4关键代码:

4.1新粒子是否被吸引的算法:

这里,关于如何判定粒子被吸引的算法值得一提:

关于粒子在图上的分布情况,可以用一个二维矩阵进行存储.

矩阵上的每个位置的取值与画布上的各个像素一一对应,一共可以取三个值UNDRAWED , READY , DRAWED分别表示该点的状况是未着点,边界点,已着点.

对于某个确认新吸收的粒子,设其位置坐标为(curX,curY),则其周围的粒子的值的情况可以用下面这个判定来改变:

                                                 if(infoMatrix[curX-1][curY]!=DRAWED)

                                                        infoMatrix[curX-1][curY]=READY;

                           

                                                 if(infoMatrix[curX][curY-1]!=DRAWED)

                                                        infoMatrix[curX][curY-1]=READY;

             

                                                 if(infoMatrix[curX+1][curY]!=DRAWED)

                                                        infoMatrix[curX+1][curY]=READY;

             

                                                 if(infoMatrix[curX][curY+1]!=DRAWED)

                                                        infoMatrix[curX][curY+1]=READY;   

       这样的话,对于以后生成的新粒子是否已处于被吸收的位置的判定,只需要用一句:

              if(infoMatrix[curX][curY]==READY&&在界内)

       即可,判定是否被吸收算法的复杂度被控制在常数级.

 

4.2模拟程序代码:

void DLATest(long maxNum,int width,int height,HDC inHDC)

{

       long curNum=0;

      

       int centerX,centerY;

       int curX,curY;

       int i,j;

       long drawColor=34048;

       int rMax,d;

       float pi;

       int** infoMatrix;

       bool flag;

       float nextPos;

      

      

       centerX=width/2;centerY=height/2;

      

       /*mem apply*/

       infoMatrix=(int**)malloc(sizeof(int*)*height);

       for(i=0;i<height;i++)

              infoMatrix[i]=(int*)malloc(sizeof(int)*width);

       /*map matrix init*/

       for(j=0;j<width;j++)

              for(i=0;i<height;i++)

                     infoMatrix[i][j]=UNDRAWED;

      

       /*produce the init particles*/

      

       srand((unsigned int)time (NULL));      

      

       i=0;

       while(i<10)

       {

              curX=centerX+(int)eRandom(10);

              curY=centerY+(int)eRandom(10);

              SetPixel(inHDC,curX,curY,drawColor);

 

              infoMatrix[curX][curY]=DRAWED;

             

              if(infoMatrix[curX-1][curY]!=DRAWED)

                            infoMatrix[curX-1][curY]=READY;

                           

              if(infoMatrix[curX][curY-1]!=DRAWED)

                            infoMatrix[curX][curY-1]=READY;

             

              if(infoMatrix[curX+1][curY]!=DRAWED)

                            infoMatrix[curX+1][curY]=READY;

             

              if(infoMatrix[curX][curY+1]!=DRAWED)

                            infoMatrix[curX][curY+1]=READY;          

              i++;

       }

      

       curNum=0;

       rMax=75;

       d=10;

       pi=3.14159;

       while(curNum<maxNum)

       {

              curX=centerX+(rMax+d)*cos(eRandom(180)/pi);

              curY=centerY+(rMax+d)*sin(eRandom(180)/pi);

             

              i=0;

              flag=false;

              while(!flag&&i<20000)

              {

                     nextPos=eRandom(100);

                     if(nextPos<25)//left

                                          curX--;

                     else if(nextPos<50)//up

                                          curY--;

                     else if(nextPos<75)//right

                                          curX++;

                     else

                                          curY++;

                    

                     if(curX<=0||curX>=width||curY<=0||curY>=height)

                                   break;

 

                     if(infoMatrix[curX][curY]==READY&&(curX-centerX)*(curX-centerX)+(curY-centerY)*(curY-centerY)<=rMax*rMax)

                            {

                                                 SetPixel(inHDC,curX,curY,drawColor);

 

                                                 infoMatrix[curX][curY]=DRAWED;

             

                                                 if(infoMatrix[curX-1][curY]!=DRAWED)

                                                        infoMatrix[curX-1][curY]=READY;

                           

                                                 if(infoMatrix[curX][curY-1]!=DRAWED)

                                                        infoMatrix[curX][curY-1]=READY;

             

                                                 if(infoMatrix[curX+1][curY]!=DRAWED)

                                                        infoMatrix[curX+1][curY]=READY;

             

                                                 if(infoMatrix[curX][curY+1]!=DRAWED)

                                                        infoMatrix[curX][curY+1]=READY;   

                                                       

                                                 flag=true;

                            }                  

                     i++;

              }

              curNum++;

       }    

}

 

                                                                                                         完成日:06/03/29

 

附录:

1测试程序下载:

http://emilmatthew.51.net/EmilPapers/06_12DLA/code.rar

 

若直接点击无法下载(或浏览),请将下载(或浏览)的超链接粘接至浏览器地( 推荐MYIEGREENBORWSER)址栏后按回车.若不出意外,此时应能下载.

抱歉!评论已关闭.