📄 dlaview.cpp
字号:
// DLAView.cpp : implementation of the CDLAView class
//
#include "stdafx.h"
#include "DLA.h"
#include "math.h"
#include "DLADoc.h"
#include "DLAView.h"
#define N 16000
#define PI 3.14159
#define R 300
#define X R
#define Y R
#define ED 10//产生粒子的位置与边界的距离
char mat[2*R+1][2*R+1];
int x,y;
int minx,maxx,miny,maxy;
long sum;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDLAView
IMPLEMENT_DYNCREATE(CDLAView, CView)
BEGIN_MESSAGE_MAP(CDLAView, CView)
//{{AFX_MSG_MAP(CDLAView)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDLAView construction/destruction
CDLAView::CDLAView()
{
// TODO: add construction code here
}
CDLAView::~CDLAView()
{
}
BOOL CDLAView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDLAView drawing
void produce_particle(); //产生种子
void produce_particle2();
void movement();
bool adhere();
void expand(int,int);
void init();
void calculate_dimension(int );
int distance(int ,int ,int ,int );
bool cover(int ,int ,int ) ;//判断边长为t盒(i,j)是否覆盖凝聚体的点
void save(int);
/*void CDLAView::OnDraw(CDC* pDC)
{
CDLADoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int p,d;
srand(0);
init();
M[X][Y]=1;
//expand(X,Y); //膨胀
for(p=0;p<N;p++)
{
produce_particle1(); //在圆上产生种子
while(1) //单个粒子的生命周期
{
d=sqrt((x-X)*(x-X)+(y-Y)*(y-Y));
if(d>R) //在圆外,死亡
{
p=p-1;
break;
}
movement(); //运动
if(adhere()) //粘附
{
M[x][y]=1; //记录
//expand(x,y); //膨胀
if(d>=R-1) p=N;
break;
}
}
}
mydraw();
calculate_dimension();//计算维数
}*/
void CDLAView::OnDraw(CDC* pDC)
{
CDLADoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int i,m,om=0;//(x,y)粒子位置
srand(0);//初始化随机序列
init();//初始化粒子系统缓存mat
mat[X][Y]=1;//(X,Y)为圆心,在此放置一粒种子
minx=maxx=X;miny=maxy=Y;
for(m=1000;m<=N;m*=2)
{ for(i=om;i<m;i++)//N为粒子规模
{ produce_particle(); //在接近圆的边界处随机产生粒子
while(1) //单个粒子的生命周期
{ if(x<0||x>2*R||y<0||y>2*R) //在圆外,死亡
{ i=i-1; break; }
movement(); //随机运动
if(adhere()) //判断是否粘附
{ mat[x][y]=1; //记录到粒子系统缓存mat
if(minx>x) minx=x;if(maxx<x) maxx=x;
if(miny>y) miny=y;if(maxy<y) maxy=y;
break;
}
}
}
mydraw();//画出凝聚体
save(m);
calculate_dimension(m);//计算维数
om=m;
}
}
/////////////////////////////////////////////////////////////////////////////
// CDLAView printing
BOOL CDLAView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDLAView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDLAView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CDLAView diagnostics
#ifdef _DEBUG
void CDLAView::AssertValid() const
{
CView::AssertValid();
}
void CDLAView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CDLADoc* CDLAView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDLADoc)));
return (CDLADoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDLAView message handlers
int distance(int m,int n,int x,int y)
{
int u=x-m,v=y-n;
return(sqrt(u*u+v*v));
}
void CDLAView::mydraw()
{
CClientDC p(this);
int i,j;
for(i=0;i<=2*R;i++)
for(j=0;j<=2*R;j++)
if(mat[i][j]==1)
p.SetPixelV(i,j,0);
else
p.SetPixelV(i,j,255*65536+255*256+255);
}
void produce_particle1(int *x,int *y)//产生粒子,位置为(x,y)
{
double e=0.9;
int angle=rand()%360;
*x=R+e*R*cos(angle*PI/180);
*y=R+e*R*sin(angle*PI/180);
}
void produce_particle()//产生粒子,位置为(x,y)
{
int k=rand()%4;
switch(k)
{
case 0:x=2*R-ED;y=ED+rand()%(2*R-2*ED);break;
case 1:x=ED+rand()%(2*R-2*ED);y=ED;break;
case 2:x=ED;y=ED+rand()%(2*R-2*ED);break;
case 3:x=ED+rand()%(2*R-2*ED);y=2*R-ED;
}
}
void movement()//粒子做随机运动
{
int f=rand()%8;//随机确定移动的方向
char step=1;//step为步长,通常取1
switch(f)//粒子依方向移动
{
case 0: x=x+1;break;
case 1: x=x+1;y=y-1;break;
case 2: y=y-1;break;
case 3: x=x-1;y=y-1;break;
case 4: x=x-1;break;
case 5: x=x-1;y=y+1;break;
case 6: y=y+1;break;
case 7: x=x+1;y=y+1;
}
}
bool adhere()//判断是否粘附到凝聚体
{
int i,j;
//int adhere_dist=1;//粘附距离
//double adhere_probability=0.85;//粘附几率
for(i=-1;i<=1;i++)
{
if((x+i<0)||(x+i>2*R))
continue;
for(j=-1;j<=1;j++)
{
if((y+j<0)||(y+j>2*R))
continue;
if(mat[x+i][y+j]==1)
{
//if(rand()%100/100.<=adhere_probability)
return(1);//粘附
//else
//return(0);//虽接近未粘附
}
}
}
return(0);//未粘附
}
void expand(int x,int y)
{
int i,j;
for(i=-1;i<2;i++)
{
if((x+i<0)||(x+i>2*R))
continue;
for(j=-1;j<2;j++)
{
if((y+j<0)||(y+j>2*R))
continue;
mat[x+i][y+j]=1;
}
}
}
void init()
{
int m,n;
for(m=0;m<=2*R;m++)
for(n=0;n<=2*R;n++)
mat[m][n]=0;
}
int mymax(int a,int b)
{
if(a>b) return(a);
else
return(b);
}
void calculate_dimension(int m)//计算维数
{
int t,n,num,i,j;
int size;//最大尺度
double d;//保存维数近似值
CFile fp;
CString s;
s.Format("dim%d.txt",m);
fp.Open(s,CFile::modeCreate+CFile::modeWrite);
size=mymax(maxx-minx+1,maxy-miny+1);
s.Format("规模%d 尺寸%d,%d\r\n",m,maxx-minx+1,maxy-miny+1);
fp.Write(s,s.GetLength());
s.Format("盒边长 delta 维数近似值\r\n");
fp.Write(s,s.GetLength());
for(t=8;t>1;t--)
{
n=size/t;//一行的盒数
num=0;//覆盖盒数计数器
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(cover(i,j,t))
num++;
d=log(1.*num)/log(1.*n);// 记录维数近似值
s.Format("%d %f %8f\r\n",t,1.*t/size,d);
fp.Write(s,s.GetLength());
}
fp.Close();
}
bool cover(int i,int j,int t) //判断边长为t盒(i,j)是否覆盖凝聚体的点
{ int p,q; char f=0;
for(p=i*t;p<(i+1)*t;p++)
for(q=j*t;q<(j+1)*t;q++)
if(mat[minx+p][miny+q]==1) f=1;
return(f);
}
void save(int m)
{
CFile fp;
long l;int i,j;char f;
char t;
CString s;
s.Format("dla%d.BMP",m);
fp.Open(s,CFile::modeCreate|CFile::modeWrite);
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
bf.bfType=0x4d42;
bf.bfReserved1=0;
bf.bfReserved2=0;
bf.bfOffBits=54L;
bi.biSize=40L;
bi.biWidth=(long)(maxx-minx+1);
bi.biHeight=(long)(maxy-miny+1);
bi.biPlanes=1;
bi.biBitCount=24;
bi.biCompression=BI_RGB;
bi.biXPelsPerMeter=1024L;
bi.biYPelsPerMeter=768L;
bi.biClrUsed=0L;
bi.biClrImportant=0;
fp.Write(&bf,14);
fp.Write(&bi,40);
l=0L;
for(j=maxy;j>=miny;j--)
{
for(i=minx;i<=maxx;i++)
{
t=(1-mat[i][j])*255;
fp.Write(&t,1);
fp.Write(&t,1);
fp.Write(&t,1);
l+=3;
}
while(l%4)
{f=0;fp.Write(&f,1);l++;}
}
bf.bfSize=54+l;
bi.biSizeImage=l;
fp.SeekToBegin();
fp.Write(&bf,14);
fp.Write(&bi,40);
fp.Close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -