FractalView.cpp
上传用户:dxkjfz
上传日期:2021-06-06
资源大小:1930k
文件大小:15k
源码类别:

分形几何

开发平台:

Visual C++

  1. // FractalView.cpp : implementation of the CFractalView class
  2. //
  3. #include "stdafx.h"
  4. #include "Fractal.h"
  5. #include "FractalDoc.h"
  6. #include "FractalView.h"
  7. #include <math.h>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. #define TREE_TIMER 10
  14. #define SIERPINSKI_TIMER 11
  15. #define FLOWER_TIMER 12
  16. #define CROWN_TIMER 13
  17. const double PI = 3.11415926;
  18. const double PI_tree=3.11415926/180;
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CFractalView
  21. IMPLEMENT_DYNCREATE(CFractalView, CView)
  22. BEGIN_MESSAGE_MAP(CFractalView, CView)
  23. //{{AFX_MSG_MAP(CFractalView)
  24. ON_COMMAND(ID_DRAWTREE, OnDrawtree)
  25. ON_WM_TIMER()
  26. ON_COMMAND(ID_DRAWSTOP, OnDrawstop)
  27. ON_COMMAND(ID_DRAWSIERPINSKI, OnDrawsierpinski)
  28. ON_COMMAND(ID_DRAWFLOWER, OnDrawflower)
  29. ON_COMMAND(ID_DRAWCROWN, OnDrawcrown)
  30. ON_COMMAND(ID_DRAWNEW, OnDrawnew)
  31. //}}AFX_MSG_MAP
  32. // Standard printing commands
  33. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  34. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  35. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  36. END_MESSAGE_MAP()
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CFractalView construction/destruction
  39. CFractalView::CFractalView()
  40. {
  41. // TODO: add construction code here
  42. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  43. m_bgColor = RGB(0, 0, 0);
  44. m_fgColor = RGB(0, 255, 0);
  45. m_dir = TRUE;
  46. tree.m_bRunning = FALSE;
  47. tree.m_Interval = 10;
  48. sier.m_bRunning = FALSE;
  49. sier.m_Interval = 10;
  50. flower.m_bRunning = FALSE;
  51. flower.m_Interval = 10;
  52. crown.m_bRunning = FALSE;
  53. crown.m_Interval = 1;
  54. crown.m_C = 9;
  55. crown.x=5;
  56. crown.y=0;  //与x,y无关
  57. crown.m_pColor= RGB(0,255,0);
  58. crown.stop=false;
  59. crown.ondraw=false;
  60. crown.cxmin=-2;
  61. crown.cxmax=(float)0.8;
  62. crown.cymin=(float)-0.3;
  63. crown.cymax=(float)0.3;
  64.     crown.cxspeed=(float)0.2;
  65. crown.cyspeed=0.25;
  66.     crown.cx=crown.cxmin;
  67.     crown.cy=0;
  68. crown.cxdirect=1;
  69. crown.cydirect=-1;
  70. crown.cnt = 0;
  71. crown.count = 0;
  72. }
  73. CFractalView::~CFractalView()
  74. {
  75. }
  76. BOOL CFractalView::PreCreateWindow(CREATESTRUCT& cs)
  77. {
  78. // TODO: Modify the Window class or styles here by modifying
  79. //  the CREATESTRUCT cs
  80. return CView::PreCreateWindow(cs);
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CFractalView drawing
  84. void CFractalView::OnDraw(CDC* pDC)
  85. {
  86. CFractalDoc* pDoc = GetDocument();
  87. ASSERT_VALID(pDoc);
  88. // TODO: add draw code for native data here
  89. static BOOL bDrawflag = true;
  90. //SetIcon(m_hIcon, TRUE); // Set big icon
  91. //SetIcon(m_hIcon, FALSE); // Set small icon
  92. if (bDrawflag){
  93. AfxGetMainWnd()->SetWindowText("分形算法演示");
  94. /************************************************************************/
  95. //获取窗口大小
  96. GetClientRect(&m_Rect);
  97. //得到物理画布
  98. m_DC.Attach(::GetDC(*this));
  99. //创建内存画布
  100. m_MemDC.CreateCompatibleDC(&m_DC);
  101. m_Bitmap.CreateCompatibleBitmap(&m_DC, m_Rect.Width(), m_Rect.Height());
  102. m_MemDC.SelectObject(&m_Bitmap);
  103. //设置画笔颜色
  104. m_Pen.CreatePen(PS_SOLID, 1, m_fgColor);
  105. m_MemDC.SelectObject(&m_Pen);
  106. //填充背景颜色
  107. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  108. m_DC.BitBlt(0, 0, m_Rect.Width(), m_Rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
  109. bDrawflag = FALSE;
  110. }
  111. /************************************************************************/
  112. /*
  113. if (IsIconic())
  114. {
  115. CPaintDC dc(this); // device context for painting
  116. //SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  117. // Center icon in client rectangle
  118. int cxIcon = GetSystemMetrics(SM_CXICON);
  119. int cyIcon = GetSystemMetrics(SM_CYICON);
  120. CRect rect;
  121. GetClientRect(&rect);
  122. int x = (rect.Width() - cxIcon + 1) / 2;
  123. int y = (rect.Height() - cyIcon + 1) / 2;
  124. // Draw the icon
  125. dc.DrawIcon(x, y, m_hIcon);
  126. }
  127. else
  128. {
  129. m_DC.BitBlt(0, 0, m_Rect.Width(), m_Rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
  130. //CFractalView::OnDraw(pDC);
  131. }*/
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CFractalView printing
  135. BOOL CFractalView::OnPreparePrinting(CPrintInfo* pInfo)
  136. {
  137. // default preparation
  138. return DoPreparePrinting(pInfo);
  139. }
  140. void CFractalView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  141. {
  142. // TODO: add extra initialization before printing
  143. }
  144. void CFractalView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  145. {
  146. // TODO: add cleanup after printing
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. // CFractalView diagnostics
  150. #ifdef _DEBUG
  151. void CFractalView::AssertValid() const
  152. {
  153. CView::AssertValid();
  154. }
  155. void CFractalView::Dump(CDumpContext& dc) const
  156. {
  157. CView::Dump(dc);
  158. }
  159. CFractalDoc* CFractalView::GetDocument() // non-debug version is inline
  160. {
  161. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFractalDoc)));
  162. return (CFractalDoc*)m_pDocument;
  163. }
  164. #endif //_DEBUG
  165. /////////////////////////////////////////////////////////////////////////////
  166. // CFractalView message handlers
  167. void CFractalView::OnDrawtree() 
  168. {
  169. // TODO: Add your command handler code here
  170. AfxGetMainWnd()->SetWindowText("摇曳的分形树");
  171. if (tree.m_bRunning) {
  172. KillTimer(TREE_TIMER);
  173. tree.m_bRunning = FALSE;
  174. } else {
  175. OnDrawstop();
  176. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  177. SetTimer(TREE_TIMER, tree.m_Interval, NULL);
  178. tree.m_bRunning = TRUE;
  179. }
  180. //CDialog::OnLButtonDown(nFlags, point);
  181. }
  182. void CFractalView::OnDrawsierpinski() 
  183. {
  184. // TODO: Add your command handler code here
  185. AfxGetMainWnd()->SetWindowText("摇摆的Sierpinski三角形");
  186. if (sier.m_bRunning) {
  187. KillTimer(SIERPINSKI_TIMER);
  188. sier.m_bRunning = FALSE;
  189. } else {
  190. OnDrawstop();
  191. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  192. SetTimer(SIERPINSKI_TIMER, sier.m_Interval, NULL);
  193. sier.m_bRunning = TRUE;
  194. }
  195. }
  196. void CFractalView::OnDrawflower() 
  197. {
  198. // TODO: Add your command handler code here
  199. AfxGetMainWnd()->SetWindowText("旋转万花筒");
  200. if (flower.m_bRunning) {
  201. KillTimer(FLOWER_TIMER);
  202. flower.m_bRunning = FALSE;
  203. } else {
  204. OnDrawstop();
  205. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  206. SetTimer(FLOWER_TIMER, flower.m_Interval, NULL);
  207. flower.m_bRunning = TRUE;
  208. }
  209. }
  210. void CFractalView::OnDrawcrown() 
  211. {
  212. // TODO: Add your command handler code here
  213. AfxGetMainWnd()->SetWindowText("王冠(Julia集)");
  214. if (crown.m_bRunning) {
  215. KillTimer(CROWN_TIMER);
  216. crown.m_bRunning = FALSE;
  217. } else {
  218. OnDrawstop();
  219. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  220. SetTimer(CROWN_TIMER, crown.m_Interval, NULL);
  221. crown.m_bRunning = TRUE;
  222. }
  223. }
  224. void CFractalView::OnDrawstop() 
  225. {
  226. // TODO: Add your command handler code here
  227. KillTimer(TREE_TIMER);
  228. tree.m_bRunning = FALSE;
  229. KillTimer(SIERPINSKI_TIMER);
  230. sier.m_bRunning = FALSE;
  231. KillTimer(FLOWER_TIMER);
  232. flower.m_bRunning = FALSE;
  233. KillTimer(CROWN_TIMER);
  234. crown.m_bRunning = FALSE;
  235. }
  236. void CFractalView::OnTimer(UINT nIDEvent) 
  237. {
  238. // TODO: Add your message handler code here and/or call default
  239. static float tree_k = 9;
  240. static float sier_k = 0;
  241. static float flower_k = 0;
  242. //在内存画布中清屏
  243. // if (CROWN_TIMER!=nIDEvent)
  244. {
  245. m_MemDC.FillSolidRect(&m_Rect, m_bgColor);
  246. }
  247. switch(nIDEvent){
  248. /* 分形树定时器 */
  249. case TREE_TIMER:
  250. int x, y;
  251. x = m_Rect.Width()/2;
  252. y = m_Rect.Height()-50;
  253. //在内存画布中绘制树
  254. drawLeaf(x, y, m_Rect.Height()/5, 270, 50, tree_k);
  255. if (m_dir) {
  256. tree_k += 0.5;
  257. if (tree_k > 18)
  258. m_dir = FALSE;
  259. } else {
  260. tree_k -= 0.5;
  261. if (tree_k < -18)
  262. m_dir = TRUE;
  263. }
  264. break;
  265. /* Sierpinski三角形定时器 */
  266. case SIERPINSKI_TIMER:
  267. if (m_dir) {
  268. sier_ifs(&m_MemDC, sier_k+=0.01);
  269. if (sier_k > 0.5)
  270. m_dir = FALSE;
  271. } else {
  272. sier_ifs(&m_MemDC, sier_k-=0.01);
  273. if (sier_k<0)
  274. m_dir =TRUE;
  275. }
  276. break;
  277. /* 万花筒定时器 */
  278. case FLOWER_TIMER:
  279. if (m_dir) {
  280. flower_ifs(&m_MemDC, flower_k+=5);
  281. if (flower_k > 500)
  282. m_dir = FALSE;
  283. } else {
  284. flower_ifs(&m_MemDC, flower_k-=5);
  285. if (flower_k<-500)
  286. m_dir =TRUE;
  287. }
  288. break;
  289. /* 王冠定时器 */
  290. case CROWN_TIMER:
  291. drawCrown();
  292. break;
  293. default:
  294. break;
  295. }
  296. //把树拷贝到物理画布中
  297. m_DC.BitBlt(0, 0, m_Rect.Width(), m_Rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
  298. CView::OnTimer(nIDEvent);
  299. }
  300. void CFractalView::drawLeaf(double x, double y, double L, double A,float B,float C){
  301. double s1, s2, s3;
  302. s1 = 2;
  303. s2 = 3;
  304. s3 = 1.3;
  305. int x1,y1,x1L,y1L,x1R,y1R,x2,y2,x2R,y2R,x2L,y2L;
  306. if(L > s1)
  307. {
  308. x2 = (int)(x + L * cos(A * PI_tree));
  309. y2 = (int)(y + L * sin(A * PI_tree));
  310. x2R = (int)(x2 + L / s2 * cos((A + B) * PI_tree));
  311. y2R = (int)(y2 + L / s2 * sin((A + B) * PI_tree));
  312. x2L = (int)(x2 + L / s2 * cos((A - B) * PI_tree));
  313. y2L = (int)(y2 + L / s2 * sin((A - B) * PI_tree));
  314. x1 = (int)(x + L / s2 * cos(A * PI_tree));
  315. y1 = (int)(y + L / s2 * sin(A * PI_tree));
  316. x1L = (int)(x1 + L / s2 * cos((A - B) * PI_tree));
  317. y1L = (int)(y1 + L / s2 * sin((A - B) * PI_tree));
  318. x1R = (int)(x1 + L / s2 * cos((A + B) * PI_tree));
  319. y1R = (int)(y1 + L / s2 * sin((A + B) * PI_tree));
  320. m_MemDC.MoveTo((int)x,(int)y);
  321. m_MemDC.LineTo(x2,y2);
  322. m_MemDC.LineTo(x2R,y2R);
  323. m_MemDC.MoveTo(x2,y2);
  324. m_MemDC.LineTo(x2L,y2L);
  325. m_MemDC.MoveTo(x1,y1);
  326. m_MemDC.LineTo(x1L,y1L);
  327. m_MemDC.MoveTo(x1,y1);
  328. m_MemDC.LineTo(x1R,y1R);
  329. drawLeaf(x2, y2, L / s3, A + C, B, C);
  330. drawLeaf(x2R, y2R, L / s2, A + B, B, C);
  331. drawLeaf(x2L, y2L, L / s2, A - B, B, C);
  332. drawLeaf(x1L, y1L, L / s2, A - B, B, C);
  333. drawLeaf(x1R, y1R, L / s2, A + B, B, C);
  334. }  
  335. }
  336. void CFractalView::sier_ifs(CDC *pDC, float k)
  337. {
  338. float x=0; // 仿射变换中的自变量
  339. float y=0;
  340. float newx, newy; //仿射变换产生的新点
  341. float a, b, c, d, e, f; //仿射变幻中的系数
  342. long n=10000;  // 迭代次数
  343. float R; //随机变量
  344. float m[7][7]={0};    // 存放IFS码
  345. //IFS码赋值
  346. m[0][0] = 0.5; m[0][1] = 0; m[0][2] = 0;  m[0][3] = k;    m[0][4] = 0;    m[0][5] = 0;   m[0][6] = 0.333;
  347. m[1][0] = 0.5; m[1][1] = 0; m[1][2] = 0;  m[1][3] = 0.5;  m[1][4] =0.5;   m[1][5] = 0;   m[1][6] = 0.333;
  348. m[2][0] = k;   m[2][1] = 0; m[2][2] = 0;  m[2][3] = 0.5;  m[2][4] = 0.25; m[2][5] = 0.5; m[2][6] = 0.334;
  349. //循环迭代,在不同的概率空间下,赋不同的IFS码值
  350. while (n > 0) {
  351.         R = (float)rand()/RAND_MAX;
  352. if (R <= m[0][6]) {
  353. a = m[0][0]; b = m[0][1]; c = m[0][2]; d = m[0][3]; e = m[0][4]; f = m[0][5];
  354. } else if (R <= m[0][6] + m[1][6]) {
  355. a = m[1][0]; b = m[1][1]; c = m[1][2]; d = m[1][3]; e = m[1][4]; f = m[1][5];
  356. } else  {
  357. a = m[2][0]; b = m[2][1]; c = m[2][2]; d = m[2][3]; e = m[2][4]; f = m[2][5];
  358. newx = (a * x) + (b * y) + e;
  359. newy = (c * x) + (d * y) + f;
  360. x = newx; y = newy;
  361. pDC->SetPixelV((1000 + 7000 * x)/15, (6500 - 6000 * y)/15, RGB(x * 500 * R, R * 100, y * 2000 * R));
  362. n--;
  363. }
  364. }
  365. void CFractalView::flower_ifs(CDC *pDC, float k){
  366. float x=0; // '仿射变换中的自变量
  367. float y=0;
  368. float newx, newy; //'仿射变换产生的新点
  369. float a, b, c, d, e, f; //'仿射变幻中的系数
  370. long n=10000;  // '迭代次数
  371. float R; //'随机变量
  372. float m[7][7]={0};    // '存放IFS码
  373. //'IFS码赋值
  374. m[0][0] = 0.2;  m[0][1] = 0.2;  m[0][2] = 0;  m[0][3] = 0;  m[0][4] = 0.7;  m[0][5] = 0;     m[0][6] = 0.2;
  375. m[1][0] = 0.2;  m[1][1] = 0.2;  m[1][2] = 0;  m[1][3] = 0;  m[1][4] =-0.7;  m[1][5] = 0;     m[1][6] = 0.2;
  376. m[2][0] = 0.2;  m[2][1] = 0.2;  m[2][2] = 0;  m[2][3] = 0;  m[2][4] = 0;    m[2][5] = 0.7;   m[2][6] = 0.2;
  377. m[3][0] = 0.2;  m[3][1] = 0.2;  m[3][2] = 0;  m[3][3] = 0;  m[3][4] = 0;    m[3][5] = -0.7;  m[3][6] = 0.2;
  378. m[4][0] = 0.85; m[4][1] = 0.85; m[4][2] = k;  m[4][3] = k;  m[4][4] = 0;    m[4][5] = 0;     m[4][6] = 0.2;
  379. //'循环迭代,在不同的概率空间下,赋不同的IFS码值
  380. while (n > 0) {
  381.         R = (float)rand()/RAND_MAX;
  382. if (R <= m[0][6]) 
  383. {
  384. a = m[0][0]; b = m[0][1]; c = m[0][2]; d = m[0][3]; e = m[0][4]; f = m[0][5];
  385. } else if (R <= m[0][6] + m[1][6]) 
  386. {
  387. a = m[1][0]; b = m[1][1]; c = m[1][2]; d = m[1][3]; e = m[1][4]; f = m[1][5];
  388. } else if (R <= m[0][6] + m[1][6] + m[2][6]) 
  389. {
  390. a = m[2][0]; b = m[2][1]; c = m[2][2]; d = m[2][3]; e = m[2][4]; f = m[2][5];
  391. } else if (R <= m[0][6] + m[1][6] + m[2][6] + m[3][6]) 
  392. {
  393. a = m[3][0]; b = m[3][1]; c = m[3][2]; d = m[3][3]; e = m[3][4]; f = m[3][5];
  394. } else 
  395. {
  396. a = m[4][0]; b = m[4][1]; c = m[4][2]; d = m[4][3]; e = m[4][4]; f = m[4][5];
  397. }
  398. newx = (a * x*cos(c/180)) - (b * y*sin(d/180)) + e;
  399. newy = (a * x*sin(c/180)) + (b * y*cos(d/180)) + f;
  400. x = newx; y = newy;
  401. pDC->SetPixelV((300 + 200 * x), (220 - 200 * y), RGB(x * 500 * R, R * 100, y * 2000 * R));
  402. n--;
  403.   }
  404. }
  405. void CFractalView::drawCrown()
  406. {
  407. static float k;
  408.     crown.count++;
  409. for(int i=0;i<12000;i++)
  410. {   
  411. k=(float)rand();
  412. crown.rnd=(float)(k/RAND_MAX);
  413. crown.wx=crown.x-crown.cx;
  414. crown.wy=crown.y-crown.cy;
  415. if(crown.wx==0){
  416. crown.theta=PI/2;
  417. }
  418. else if(crown.wx>0){
  419. crown.theta=atan(crown.wy/crown.wx);
  420. }
  421. else if(crown.wx<0){
  422. crown.theta=PI-atan(crown.wy/crown.wx); 
  423. }
  424. crown.theta=crown.theta/2;
  425. crown.r=sqrt(crown.wx*crown.wx+crown.wy*crown.wy);
  426. if(crown.rnd<0.5){
  427. crown.r=sqrt(crown.r);
  428. }else{
  429. crown.r=-sqrt(crown.r);
  430. }
  431. crown.x=crown.r*cos(crown.theta);
  432. crown.y=crown.r*sin(crown.theta);
  433. m_MemDC.SetPixel((int)(2000*crown.x/15+3500/15+0.5),(int)(2000*crown.y/15+3500/15+0.5),0x00ff00);
  434. //Invalidate(false);
  435. if(crown.count==2) 
  436. {
  437. crown.count=0;
  438. }
  439. }
  440. crown.cx=crown.cx+0.002*crown.cxdirect;
  441. if(crown.cx>crown.cxmax && crown.cxdirect==1)
  442. {
  443. crown.cxdirect=-1;
  444. crown.cnt++;
  445. }
  446. else if(crown.cx<crown.cxmin && crown.cxdirect==-1)
  447. {
  448. crown.cxdirect=1;
  449. crown.cnt++;
  450. }
  451. if(crown.cnt%3==0 &&crown.cnt!=0)
  452. {
  453. crown.cy=crown.cy+0.003*crown.cydirect;
  454. }
  455. if(crown.cy>crown.cymax && crown.cydirect==1)
  456. {
  457. crown.cydirect=-1;
  458. }
  459. else if(crown.cy<crown.cymin && crown.cydirect==-1)
  460. {
  461. crown.cydirect=1;
  462. }
  463. }
  464. void CFractalView::OnDrawnew() 
  465. {
  466. // TODO: Add your command handler code here
  467. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  468. m_bgColor = RGB(0, 0, 0);
  469. m_fgColor = RGB(0, 255, 0);
  470. tree.m_Interval = 10;
  471. sier.m_Interval = 10;
  472. flower.m_Interval = 10;
  473. crown.m_Interval = 1;
  474. crown.m_C = 9;
  475. crown.x=5;
  476. crown.y=0;  //与x,y无关
  477. crown.m_pColor= RGB(0,255,0);
  478. crown.stop=false;
  479. crown.ondraw=false;
  480. crown.cxmin=-2;
  481. crown.cxmax=(float)0.8;
  482. crown.cymin=(float)-0.3;
  483. crown.cymax=(float)0.3;
  484.     crown.cxspeed=(float)0.2;
  485. crown.cyspeed=0.25;
  486.     crown.cx=crown.cxmin;
  487.     crown.cy=0;
  488. crown.cxdirect=1;
  489. crown.cydirect=-1;
  490. crown.cnt = 0;
  491. crown.count = 0;
  492. }