找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2866|回复: 0

2个二维运动图形方面的模拟程序

[复制链接]
发表于 2014-2-20 00:51:41 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
寒假写的代码第一个是模拟泊松运动
poison.rar (24.15 KB, 下载次数: 4)
QQ图片20140220004947.jpg

核心代码:
  1. BOOL CCollisionaDlg::OnInitDialog()
  2. {
  3.         CDialog::OnInitDialog();

  4.         // Set the icon for this dialog. The framework does this automatically
  5.         // when the application's main window is not a dialog
  6.         SetIcon(m_hIcon, TRUE); // Set big icon
  7.         SetIcon(m_hIcon, FALSE); // Set small icon

  8.         // TODO: Add extra initialization here
  9.         ShowWindow(SW_MAXIMIZE);
  10.         CClientDC tempdc(this);
  11.         MYDC.CreateCompatibleDC(&tempdc);
  12.         RECT rt;
  13.         GetClientRect(&rt);
  14.         bmp.CreateCompatibleBitmap(&tempdc,rt.right,rt.bottom);
  15.         MYDC.SelectObject(&bmp);
  16.         CBrush brush;
  17.         brush.CreateSolidBrush(RGB(255,255,255));
  18.         MYDC.FillRect(&rt,&brush);

  19.         srand(time(NULL));
  20.         //初始化小球
  21.         for(int i=0;i<BALLNUM;i++)
  22.         {
  23.                 ball[i].x=rand()%rt.right;
  24.                 ball[i].y=rand()%rt.bottom;
  25.                 ball[i].deltax=rand()%11-5;
  26.                 ball[i].deltax+=(ball[i].deltax>0)?1:-1;
  27.                 ball[i].deltay=rand()%11-5;
  28.                 ball[i].deltay+=(ball[i].deltay>0)?1:-1;
  29.                 ball[i].deltay=1;
  30.                 ball[i].xcount=0;
  31.                 ball[i].ycount=0;
  32.                 ball[i].radius=rand()%MAXRADIU+40;
  33.                 ball[i].color=RGB(rand()&0xff,rand()&0xff,rand()&0xff);
  34.                 ball[i].iscollision=FALSE;
  35.         }

  36.         // ball[0].x=200;
  37.         // ball[1].x=200;
  38.         // ball[0].y=100;
  39.         // ball[1].y=500;
  40.         // ball[0].deltax=100;
  41.         // ball[1].deltax=100;
  42.         // ball[0].deltay=1;
  43.         // ball[1].deltay=2;
  44.         // ball[0].xcount=0;
  45.         // ball[0].ycount=0;
  46.         // ball[1].xcount=0;
  47.         // ball[1].ycount=0;
  48.         // ball[0].radius=20;
  49.         // ball[1].radius=20;
  50.         // ball[0].color=RGB(255,0,0);
  51.         // ball[1].color=RGB(0,255,0);
  52.         // ball[0].iscollision=FALSE;
  53.         // ball[1].iscollision=FALSE;

  54.         SetTimer(0,10,NULL);

  55.         return TRUE; // return TRUE unless you set the focus to a control
  56. }

  57. void CCollisionaDlg::OnSysCommand(UINT nID, LPARAM lParam)
  58. {
  59.         CDialog::OnSysCommand(nID, lParam);
  60. }

  61. // If you add a minimize button to your dialog, you will need the code below
  62. // to draw the icon. For MFC applications using the document/view model,
  63. // this is automatically done for you by the framework.

  64. void CCollisionaDlg::OnPaint()
  65. {
  66.         if (IsIconic())
  67.         {
  68.                 CPaintDC dc(this); // device context for painting

  69.                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  70.                 // Center icon in client rectangle
  71.                 int cxIcon = GetSystemMetrics(SM_CXICON);
  72.                 int cyIcon = GetSystemMetrics(SM_CYICON);
  73.                 CRect rect;
  74.                 GetClientRect(&rect);
  75.                 int x = (rect.Width() - cxIcon + 1) / 2;
  76.                 int y = (rect.Height() - cyIcon + 1) / 2;

  77.                 // Draw the icon
  78.                 dc.DrawIcon(x, y, m_hIcon);
  79.         }
  80.         else
  81.         {
  82.                 CDialog::OnPaint();
  83.                 RECT rt;
  84.                 GetClientRect(&rt);
  85.                 CBrush nulbrush(RGB(255,255,255));
  86.                 MYDC.FillRect(&rt,&nulbrush);

  87.                 CClientDC dc(this);

  88.                 for(int i=0;i<BALLNUM;i++)
  89.                 {
  90.                         CBrush brush(ball[i].color);
  91.                         MYDC.SelectObject(&brush);
  92.                         MYDC.Ellipse(ball[i].x-ball[i].radius,ball[i].y-ball[i].radius,ball[i].x+ball[i].radius,ball[i].y+ball[i].radius);
  93.                         brush.DeleteObject();
  94.                 }

  95.                 dc.BitBlt(0,0,rt.right,rt.bottom,&MYDC,0,0,SRCCOPY);
  96.         }
  97. }

  98. // The system calls this to obtain the cursor to display while the user drags
  99. // the minimized window.
  100. HCURSOR CCollisionaDlg::OnQueryDragIcon()
  101. {
  102.         return (HCURSOR) m_hIcon;
  103. }

  104. void CCollisionaDlg::OnTimer(UINT nIDEvent)
  105. {
  106.         // TODO: Add your message handler code here and/or call default
  107.         RECT rt;
  108.         GetClientRect(&rt);
  109.         int i,j;

  110.         //做移动
  111.         for(i=0;i<BALLNUM;i++)
  112.         {
  113.                 ball[i].xcount++;
  114.                 ball[i].ycount++;
  115.                 if(ball[i].deltax > 0)
  116.                 {
  117.                         if(ball[i].xcount >= ball[i].deltax)
  118.                         {
  119.                                 ball[i].x+=2;
  120.                                 ball[i].xcount=0;
  121.                         }
  122.                 }
  123.                 else
  124.                 {
  125.                         if(ball[i].xcount >= -ball[i].deltax)
  126.                         {
  127.                                 ball[i].x-=2;
  128.                                 ball[i].xcount=0;
  129.                         }
  130.                 }
  131.                 if(ball[i].deltay > 0)
  132.                 {
  133.                         if(ball[i].ycount >= ball[i].deltay)
  134.                         {
  135.                                 ball[i].y+=2;
  136.                                 ball[i].ycount=0;
  137.                         }
  138.                 }
  139.                 else
  140.                 {
  141.                         if(ball[i].ycount >= -ball[i].deltay)
  142.                         {
  143.                                 ball[i].y-=2;
  144.                                 ball[i].ycount=0;
  145.                         }
  146.                 }

  147.                 //判断边界
  148.                 #define MARGIN 0
  149.                 if(ball[i].x-ball[i].radius < MARGIN)
  150.                 {
  151.                         ball[i].x=MARGIN+ball[i].radius;
  152.                         if(ball[i].deltax<0)
  153.                                 ball[i].deltax=-ball[i].deltax;
  154.                 }
  155.                 else if(ball[i].x+ball[i].radius > rt.right-MARGIN)
  156.                 {
  157.                         ball[i].x=rt.right-MARGIN-ball[i].radius;
  158.                         if(ball[i].deltax>0)
  159.                                 ball[i].deltax=-ball[i].deltax;
  160.                 }
  161.                 if(ball[i].y-ball[i].radius < MARGIN)
  162.                 {
  163.                         ball[i].y=MARGIN+ball[i].radius;
  164.                         if(ball[i].deltay<0)
  165.                                 ball[i].deltay=-ball[i].deltay;
  166.                 }
  167.                 else if(ball[i].y+ball[i].radius > rt.bottom-MARGIN)
  168.                 {
  169.                         ball[i].y=rt.bottom-MARGIN-ball[i].radius;
  170.                         if(ball[i].deltay>0)
  171.                                 ball[i].deltay=-ball[i].deltay;
  172.                 }
  173.         }

  174.         //判断碰撞

  175.         for(i=0;i < BALLNUM;i++)
  176.         {
  177.                 int count=0;
  178.                 for(j=0;j != i && j < BALLNUM;j++)
  179.                 {
  180.                         if((ball[i].x-ball[j].x)*(ball[i].x-ball[j].x)+(ball[i].y-ball[j].y)*(ball[i].y-ball[j].y) <= (ball[i].radius+ball[j].radius)*(ball[i].radius+ball[j].radius))
  181.                         {        //碰撞以后利用水平方向以及垂直方向动量守恒定律和能量守恒定律
  182.                                 //f1'=(R1*R1*R1*f2+2*R2*R2*R2*f1-R2*R2*R2*f2)/[f1*f2*(R1*R1*R1+R2*R2*R2)]
  183.                                 //f2'=(2*R1*R1*R1*f2-R1*R1*R1*f1+2*R2*R2*R2*f1)/[f1*f2*(R1*R1*R1+R2*R2*R2)]
  184.                                 if(!ball[i].iscollision || !ball[j].iscollision)
  185.                                 {
  186.                                         int r31=ball[i].radius*ball[i].radius*ball[i].radius;//R1*R1*R1
  187.                                         int r32=ball[j].radius*ball[j].radius*ball[j].radius;//R2*R2*R2
  188.                                         double newxcount1=(ball[i].deltax*ball[j].deltax*(r31+r32))/float(r31*ball[j].deltax+2*r32*ball[i].deltax-r32*ball[j].deltax);
  189.                                         double newycount1=(ball[i].deltay*ball[j].deltay*(r31+r32))/float(r31*ball[j].deltay+2*r32*ball[i].deltay-r32*ball[j].deltay);
  190.                                         double newxcount2=(ball[i].deltax*ball[j].deltax*(r31+r32))/float(2*r31*ball[j].deltax-r31*ball[i].deltax+r32*ball[i].deltax);
  191.                                         double newycount2=(ball[i].deltay*ball[j].deltay*(r31+r32))/float(2*r31*ball[j].deltay-r31*ball[i].deltay+r32*ball[i].deltay);
  192.                                         if(newxcount1 > 100)
  193.                                         {
  194.                                                 ball[i].deltax=100;
  195.                                         }
  196.                                         else if(newxcount1 >= 1)
  197.                                         {
  198.                                                 ball[i].deltax=newxcount1;
  199.                                         }
  200.                                         else if(newxcount1 >= 0)
  201.                                         {
  202.                                                 ball[i].deltax=1;
  203.                                         }
  204.                                         else if(newxcount1 > -1)
  205.                                         {
  206.                                                 ball[i].deltax=-1;
  207.                                         }
  208.                                         else if(newxcount1 >= -100)
  209.                                         {
  210.                                                 ball[i].deltax=newxcount1;
  211.                                         }
  212.                                         else
  213.                                         {
  214.                                                 ball[i].deltax=-100;
  215.                                         }

  216.                                         if(newycount1 > 100)
  217.                                         {
  218.                                                 ball[i].deltay=100;
  219.                                         }
  220.                                         else if(newycount1 >= 1)
  221.                                         {
  222.                                                 ball[i].deltay=newycount1;
  223.                                         }
  224.                                         else if(newycount1 >= 0)
  225.                                         {
  226.                                                 ball[i].deltay=1;
  227.                                         }
  228.                                         else if(newycount1 > -1)
  229.                                         {
  230.                                                 ball[i].deltay=-1;
  231.                                         }
  232.                                         else if(newycount1 >= -100)
  233.                                         {
  234.                                                 ball[i].deltay=newycount1;
  235.                                         }
  236.                                         else
  237.                                         {
  238.                                                 ball[i].deltay=-100;
  239.                                         }

  240.                                         if(newxcount2 > 100)
  241.                                         {
  242.                                                 ball[j].deltax=100;
  243.                                         }
  244.                                         else if(newxcount2 >= 1)
  245.                                         {
  246.                                                 ball[j].deltax=newxcount2;
  247.                                         }
  248.                                         else if(newxcount2 >= 0)
  249.                                         {
  250.                                                 ball[j].deltax=1;
  251.                                         }
  252.                                         else if(newxcount2 > -1)
  253.                                         {
  254.                                                 ball[j].deltax=-1;
  255.                                         }
  256.                                         else if(newxcount2 >= -100)
  257.                                         {
  258.                                                 ball[j].deltax=newxcount2;
  259.                                         }
  260.                                         else
  261.                                         {
  262.                                                 ball[j].deltax=-100;
  263.                                         }

  264.                                         if(newycount2 > 100)
  265.                                         {
  266.                                                 ball[j].deltay=100;
  267.                                         }
  268.                                         else if(newycount2 >= 1)
  269.                                         {
  270.                                                 ball[j].deltay=newycount2;
  271.                                         }
  272.                                         else if(newycount2 >= 0)
  273.                                         {
  274.                                                 ball[j].deltay=1;
  275.                                         }
  276.                                         else if(newycount2 > -1)
  277.                                         {
  278.                                                 ball[j].deltay=-1;
  279.                                         }
  280.                                         else if(newycount2 >= -100)
  281.                                         {
  282.                                                 ball[j].deltay=newycount2;
  283.                                         }
  284.                                         else
  285.                                         {
  286.                                                 ball[j].deltay=-100;
  287.                                         }
  288.                                         ball[i].iscollision=TRUE;
  289.                                         ball[j].iscollision=TRUE;
  290.                                 }
  291.                                 break;
  292.                         }
  293.                         else
  294.                         {
  295.                                 count++;
  296.                         }
  297.                 }
  298.                 if(count < BALLNUM-1)
  299.                         ball[i].iscollision=TRUE;
  300.                 else
  301.                         ball[i].iscollision=FALSE;
  302.         }

  303.         Invalidate(FALSE);

  304.         CDialog::OnTimer(nIDEvent);
  305. }
复制代码

第二个是模拟碰撞
collisiona.rar (25.8 KB, 下载次数: 2)
无标题.png
这个有bug,0xAA55可以帮我看看
核心代码:

  1. BOOL CPosonDlg::OnInitDialog()
  2. {
  3.         CDialog::OnInitDialog();

  4.         // Add "About..." menu item to system menu.

  5.         // IDM_ABOUTBOX must be in the system command range.
  6.         ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  7.         ASSERT(IDM_ABOUTBOX < 0xF000);

  8.         CMenu* pSysMenu = GetSystemMenu(FALSE);
  9.         if (pSysMenu != NULL)
  10.         {
  11.                 CString strAboutMenu;
  12.                 strAboutMenu.LoadString(IDS_ABOUTBOX);
  13.                 if (!strAboutMenu.IsEmpty())
  14.                 {
  15.                         pSysMenu->AppendMenu(MF_SEPARATOR);
  16.                         pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  17.                 }
  18.         }

  19.         // Set the icon for this dialog. The framework does this automatically
  20.         // when the application's main window is not a dialog
  21.         SetIcon(m_hIcon, TRUE); // Set big icon
  22.         SetIcon(m_hIcon, FALSE); // Set small icon

  23.         // TODO: Add extra initialization here
  24.         ShowWindow(SW_MAXIMIZE);
  25.         CClientDC tempdc(this);
  26.         MYDC.CreateCompatibleDC(&tempdc);
  27.         RECT rt;
  28.         GetClientRect(&rt);
  29.         bmp.CreateCompatibleBitmap(&MYDC,rt.right,rt.bottom);
  30.         MYDC.SelectObject(&bmp);
  31.         CBrush brush(RGB(255,255,255));
  32.         MYDC.FillRect(&rt,&brush);

  33.         for(int i=0;i<100;i++)
  34.         {
  35.                 pt[i].x=rand()%rt.right;
  36.                 pt[i].y=rand()%rt.bottom;
  37.         }
  38.         SetTimer(0,1,NULL);

  39.         return TRUE; // return TRUE unless you set the focus to a control
  40. }

  41. void CPosonDlg::OnSysCommand(UINT nID, LPARAM lParam)
  42. {
  43.         if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  44.         {
  45.                 CAboutDlg dlgAbout;
  46.                 dlgAbout.DoModal();
  47.         }
  48.         else
  49.         {
  50.                 CDialog::OnSysCommand(nID, lParam);
  51.         }
  52. }

  53. // If you add a minimize button to your dialog, you will need the code below
  54. // to draw the icon. For MFC applications using the document/view model,
  55. // this is automatically done for you by the framework.

  56. void CPosonDlg::OnPaint()
  57. {
  58.         if (IsIconic())
  59.         {
  60.                 CPaintDC dc(this); // device context for painting

  61.                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  62.                 // Center icon in client rectangle
  63.                 int cxIcon = GetSystemMetrics(SM_CXICON);
  64.                 int cyIcon = GetSystemMetrics(SM_CYICON);
  65.                 CRect rect;
  66.                 GetClientRect(&rect);
  67.                 int x = (rect.Width() - cxIcon + 1) / 2;
  68.                 int y = (rect.Height() - cyIcon + 1) / 2;

  69.                 // Draw the icon
  70.                 dc.DrawIcon(x, y, m_hIcon);
  71.         }
  72.         else
  73.         {
  74.                 //CDialog::OnPaint();
  75.                 RECT rt;
  76.                 GetClientRect(&rt);
  77.                 CBrush nulbrush(RGB(255,255,255));
  78.                 MYDC.FillRect(&rt,&nulbrush);

  79.                 CPaintDC dc(this);
  80.                 CBrush brush(RGB(0,0,0));
  81.                 MYDC.SelectObject(&brush);
  82.                 for(int i=0;i<100;i++)
  83.                 {
  84.                         MYDC.Ellipse(pt[i].x-5,pt[i].y-5,pt[i].x+5,pt[i].y+5);
  85.                 }

  86.                 dc.BitBlt(0,0,rt.right,rt.bottom,&MYDC,0,0,SRCCOPY);
  87.                 brush.DeleteObject();
  88.         }
  89. }

  90. // The system calls this to obtain the cursor to display while the user drags
  91. // the minimized window.
  92. HCURSOR CPosonDlg::OnQueryDragIcon()
  93. {
  94.         return (HCURSOR) m_hIcon;
  95. }

  96. void CPosonDlg::OnClose()
  97. {
  98.         // TODO: Add your message handler code here and/or call default
  99.         bmp.DeleteObject();

  100.         CDialog::OnClose();
  101. }


  102. void CPosonDlg::OnTimer(UINT nIDEvent)
  103. {
  104.         // TODO: Add your message handler code here and/or call default
  105.         RECT rt;
  106.         GetClientRect(&rt);

  107.         for(int i=0;i<100;i++)
  108.         {
  109.                 int len=rand()%10;
  110.                 switch(rand()%4)
  111.                 {
  112.                 case 0:
  113.                         pt[i].y-=len;
  114.                         if(pt[i].y < 0)
  115.                         {
  116.                                 pt[i].y=rand()%rt.bottom;
  117.                         }
  118.                         break;

  119.                 case 1:
  120.                         pt[i].y+=len;
  121.                         if(pt[i].y >= rt.bottom)
  122.                         {
  123.                                 pt[i].y=rand()%rt.bottom;
  124.                         }
  125.                         break;

  126.                 case 2:
  127.                         pt[i].x+=len;
  128.                         if(pt[i].x >= rt.right)
  129.                         {
  130.                                 pt[i].x=rand()%rt.right;
  131.                         }
  132.                         break;

  133.                 case 3:
  134.                         pt[i].x-=len;
  135.                         if(pt[i].x < 0)
  136.                         {
  137.                                 pt[i].x=rand()%rt.right;
  138.                         }
  139.                         break;
  140.                 }
  141.         }
  142.         Invalidate(FALSE);

  143.         CDialog::OnTimer(nIDEvent);
  144. }
复制代码
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-23 06:59 , Processed in 0.042523 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表