钱塘烟雨

长风破浪会有时,直挂云帆济沧海! Free Website Counter 在线人数:

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  24 随笔 :: 0 文章 :: 43 评论 :: 0 引用

        上学期选修了一门课《现代数学方法选讲》,包含两部分内容:模糊数学和分形几何。觉得分形几何中的论点新颖有趣,其中比较基础的就是朱里叶集和曼得布罗特集了。这两种集合的图形体现了无限可分的概念,往往带给人们意想不到的震撼和不同凡响的美感。恰好那时侯正在自学MFC,感觉该做些什么练练手,所以做了这个画这两种集合的程序。使用了内存缓冲绘图法,以提高绘图效率。可任意放大缩小,能够观察到分形图形无限可分的特性。
 



奇妙的分形几何图形
   
主要代码如下:


朱里叶集的绘制:

void CJuliaView::OnDraw(CDC* pDC/*pDC*/)
{
 CJuliaDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);

 // TODO: 在此处为本机数据添加绘制代码
 int i,j,k;
 CDC dcMem;
 CBitmap* pOldBitmap = NULL;
 if(b_Change==TRUE)
 {
  double lx,ly,x,y,m,n,r,a,b;
  const int kmax=256,M=4,iColor[19]={0x800000,0x8000,0x808000,0x80,0x800080,0x8080,0xc0c0c0,0xc0dcc0,0xa6caf0,0xfffbf0,0xa0a0a4,0x808080,0xff0000,0xff00,0xffff00,0xff,0xff00ff,0xffff,0xffffff};
  CRect rect;
  GetClientRect(rect);
  cxClient=rect.right-rect.left;
  cyClient=rect.bottom-rect.top;
  lx=(m_Xmax-m_Xmin)/cxClient;
  ly=(m_Ymax-m_Ymin)/cyClient;
  a=pDoc->m_ParamA;
  b=pDoc->m_ParamB;
  dcMem.CreateCompatibleDC(pDC);
  pDoc->m_bmpBuffer.DeleteObject();
  pDoc->m_bmpBuffer.CreateCompatibleBitmap(pDC,cxClient,cyClient);
  pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuffer);
  ::SetCursor(::LoadCursor(NULL,IDC_WAIT));
  for(i=0;i<cxClient;i++)
  {
   for(j=0;j<cyClient;j++)
   {
    x=m_Xmin+i*lx;
    y=m_Ymax-j*ly;
    k=0;
    while(TRUE)
    {
     m=x*x-y*y+a;
     n=2*x*y+b;
     k++;
     r=m*m+n*n;
     if(r>M)
     {
      dcMem.SetPixel(i,j,iColor[(k-1)%19]);
      break;
     }
     if(k==kmax)
     {
      dcMem.SetPixel(i,j,0);
      break;
     }
     x=m;
     y=n;
    }
   }
  }
  b_Change=FALSE;
  pDC->BitBlt(0,0,cxClient,cyClient,&dcMem,0,0,SRCCOPY);
 }
 else
 {
  dcMem.CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC
  pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuffer);//我们调入了我们bitmap目标
  pDC->BitBlt(0,0,cxClient,cyClient,&dcMem,0,0,SRCCOPY);
 }
 dcMem.SelectObject(pOldBitmap);
 dcMem.DeleteDC();
}


曼得布罗特集的绘制:

void CMandelbrotView::OnDraw(CDC* pDC/*pDC*/)
{
 CMandelbrotDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);

 // TODO: 在此处为本机数据添加绘制代码
 int i,j,k;
 CDC dcMem;
 CBitmap* pOldBitmap = NULL;
 if(b_Change==TRUE)
 {
  double lx,ly,x,y,m,n,r,a,b;
  const int kmax=256,M=4,iColor[19]={0x800000,0x8000,0x808000,0x80,0x800080,0x8080,0xc0c0c0,0xc0dcc0,0xa6caf0,0xfffbf0,0xa0a0a4,0x808080,0xff0000,0xff00,0xffff00,0xff,0xff00ff,0xffff,0xffffff};
  CRect rect;
  GetClientRect(rect);
  cxClient=rect.right-rect.left;
  cyClient=rect.bottom-rect.top;
  lx=(m_Xmax-m_Xmin)/cxClient;
  ly=(m_Ymax-m_Ymin)/cyClient;
  dcMem.CreateCompatibleDC(pDC);
  pDoc->m_bmpBuffer.DeleteObject();
  pDoc->m_bmpBuffer.CreateCompatibleBitmap(pDC,cxClient,cyClient);
  pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuffer);
  ::SetCursor(::LoadCursor(NULL,IDC_WAIT));
  for(i=0;i<cxClient;i++)
  {
   for(j=0;j<cyClient;j++)
   {
    a=m_Xmin+i*lx;
    b=m_Ymax-j*ly;
    k=0;
    x=0;
    y=0;
    while(TRUE)
    {
     m=x*x-y*y+a;
     n=2*x*y+b;
     k++;
     r=m*m+n*n;
     if(r>M)
     {
      dcMem.SetPixel(i,j,iColor[(k-1)%19]);
      break;
     }
     if(k==kmax)
     {
      dcMem.SetPixel(i,j,0);
      break;
     }
     x=m;
     y=n;
    }
   }
  }
  b_Change=FALSE;
  pDC->BitBlt(0,0,cxClient,cyClient,&dcMem,0,0,SRCCOPY);
 }
 else
 {
  dcMem.CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC
  pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuffer);//我们调入了我们bitmap目标
  pDC->BitBlt(0,0,cxClient,cyClient,&dcMem,0,0,SRCCOPY);
 }
 dcMem.SelectObject(pOldBitmap);
 dcMem.DeleteDC();
}

两者大同小异,仅在算法部分略有不同。

posted on 2005-05-04 19:56 钱塘烟雨 阅读(668) 评论(1)  编辑 收藏 网摘 所属分类: 海纳百川

评论

#1楼  2006-08-16 09:25 芹紫 [未注册用户]
不懂!
  回复  引用    





标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-05-08 22:36 编辑过
Google站内搜索

相关文章:

相关链接: