元始天尊 发表于 2014-2-20 00:51:41

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

寒假写的代码第一个是模拟泊松运动



核心代码:BOOL CCollisionaDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

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

        // TODO: Add extra initialization here
        ShowWindow(SW_MAXIMIZE);
        CClientDC tempdc(this);
        MYDC.CreateCompatibleDC(&tempdc);
        RECT rt;
        GetClientRect(&rt);
        bmp.CreateCompatibleBitmap(&tempdc,rt.right,rt.bottom);
        MYDC.SelectObject(&bmp);
        CBrush brush;
        brush.CreateSolidBrush(RGB(255,255,255));
        MYDC.FillRect(&rt,&brush);

        srand(time(NULL));
        //初始化小球
        for(int i=0;i<BALLNUM;i++)
        {
                ball.x=rand()%rt.right;
                ball.y=rand()%rt.bottom;
                ball.deltax=rand()%11-5;
                ball.deltax+=(ball.deltax>0)?1:-1;
                ball.deltay=rand()%11-5;
                ball.deltay+=(ball.deltay>0)?1:-1;
                ball.deltay=1;
                ball.xcount=0;
                ball.ycount=0;
                ball.radius=rand()%MAXRADIU+40;
                ball.color=RGB(rand()&0xff,rand()&0xff,rand()&0xff);
                ball.iscollision=FALSE;
        }

        // ball.x=200;
        // ball.x=200;
        // ball.y=100;
        // ball.y=500;
        // ball.deltax=100;
        // ball.deltax=100;
        // ball.deltay=1;
        // ball.deltay=2;
        // ball.xcount=0;
        // ball.ycount=0;
        // ball.xcount=0;
        // ball.ycount=0;
        // ball.radius=20;
        // ball.radius=20;
        // ball.color=RGB(255,0,0);
        // ball.color=RGB(0,255,0);
        // ball.iscollision=FALSE;
        // ball.iscollision=FALSE;

        SetTimer(0,10,NULL);

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

void CCollisionaDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
        CDialog::OnSysCommand(nID, lParam);
}

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

void CCollisionaDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // device context for painting

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

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

                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialog::OnPaint();
                RECT rt;
                GetClientRect(&rt);
                CBrush nulbrush(RGB(255,255,255));
                MYDC.FillRect(&rt,&nulbrush);

                CClientDC dc(this);

                for(int i=0;i<BALLNUM;i++)
                {
                        CBrush brush(ball.color);
                        MYDC.SelectObject(&brush);
                        MYDC.Ellipse(ball.x-ball.radius,ball.y-ball.radius,ball.x+ball.radius,ball.y+ball.radius);
                        brush.DeleteObject();
                }

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

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

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

        //做移动
        for(i=0;i<BALLNUM;i++)
        {
                ball.xcount++;
                ball.ycount++;
                if(ball.deltax > 0)
                {
                        if(ball.xcount >= ball.deltax)
                        {
                                ball.x+=2;
                                ball.xcount=0;
                        }
                }
                else
                {
                        if(ball.xcount >= -ball.deltax)
                        {
                                ball.x-=2;
                                ball.xcount=0;
                        }
                }
                if(ball.deltay > 0)
                {
                        if(ball.ycount >= ball.deltay)
                        {
                                ball.y+=2;
                                ball.ycount=0;
                        }
                }
                else
                {
                        if(ball.ycount >= -ball.deltay)
                        {
                                ball.y-=2;
                                ball.ycount=0;
                        }
                }

                //判断边界
                #define MARGIN 0
                if(ball.x-ball.radius < MARGIN)
                {
                        ball.x=MARGIN+ball.radius;
                        if(ball.deltax<0)
                                ball.deltax=-ball.deltax;
                }
                else if(ball.x+ball.radius > rt.right-MARGIN)
                {
                        ball.x=rt.right-MARGIN-ball.radius;
                        if(ball.deltax>0)
                                ball.deltax=-ball.deltax;
                }
                if(ball.y-ball.radius < MARGIN)
                {
                        ball.y=MARGIN+ball.radius;
                        if(ball.deltay<0)
                                ball.deltay=-ball.deltay;
                }
                else if(ball.y+ball.radius > rt.bottom-MARGIN)
                {
                        ball.y=rt.bottom-MARGIN-ball.radius;
                        if(ball.deltay>0)
                                ball.deltay=-ball.deltay;
                }
        }

        //判断碰撞

        for(i=0;i < BALLNUM;i++)
        {
                int count=0;
                for(j=0;j != i && j < BALLNUM;j++)
                {
                        if((ball.x-ball.x)*(ball.x-ball.x)+(ball.y-ball.y)*(ball.y-ball.y) <= (ball.radius+ball.radius)*(ball.radius+ball.radius))
                        {        //碰撞以后利用水平方向以及垂直方向动量守恒定律和能量守恒定律
                                //f1'=(R1*R1*R1*f2+2*R2*R2*R2*f1-R2*R2*R2*f2)/
                                //f2'=(2*R1*R1*R1*f2-R1*R1*R1*f1+2*R2*R2*R2*f1)/
                                if(!ball.iscollision || !ball.iscollision)
                                {
                                        int r31=ball.radius*ball.radius*ball.radius;//R1*R1*R1
                                        int r32=ball.radius*ball.radius*ball.radius;//R2*R2*R2
                                        double newxcount1=(ball.deltax*ball.deltax*(r31+r32))/float(r31*ball.deltax+2*r32*ball.deltax-r32*ball.deltax);
                                        double newycount1=(ball.deltay*ball.deltay*(r31+r32))/float(r31*ball.deltay+2*r32*ball.deltay-r32*ball.deltay);
                                        double newxcount2=(ball.deltax*ball.deltax*(r31+r32))/float(2*r31*ball.deltax-r31*ball.deltax+r32*ball.deltax);
                                        double newycount2=(ball.deltay*ball.deltay*(r31+r32))/float(2*r31*ball.deltay-r31*ball.deltay+r32*ball.deltay);
                                        if(newxcount1 > 100)
                                        {
                                                ball.deltax=100;
                                        }
                                        else if(newxcount1 >= 1)
                                        {
                                                ball.deltax=newxcount1;
                                        }
                                        else if(newxcount1 >= 0)
                                        {
                                                ball.deltax=1;
                                        }
                                        else if(newxcount1 > -1)
                                        {
                                                ball.deltax=-1;
                                        }
                                        else if(newxcount1 >= -100)
                                        {
                                                ball.deltax=newxcount1;
                                        }
                                        else
                                        {
                                                ball.deltax=-100;
                                        }

                                        if(newycount1 > 100)
                                        {
                                                ball.deltay=100;
                                        }
                                        else if(newycount1 >= 1)
                                        {
                                                ball.deltay=newycount1;
                                        }
                                        else if(newycount1 >= 0)
                                        {
                                                ball.deltay=1;
                                        }
                                        else if(newycount1 > -1)
                                        {
                                                ball.deltay=-1;
                                        }
                                        else if(newycount1 >= -100)
                                        {
                                                ball.deltay=newycount1;
                                        }
                                        else
                                        {
                                                ball.deltay=-100;
                                        }

                                        if(newxcount2 > 100)
                                        {
                                                ball.deltax=100;
                                        }
                                        else if(newxcount2 >= 1)
                                        {
                                                ball.deltax=newxcount2;
                                        }
                                        else if(newxcount2 >= 0)
                                        {
                                                ball.deltax=1;
                                        }
                                        else if(newxcount2 > -1)
                                        {
                                                ball.deltax=-1;
                                        }
                                        else if(newxcount2 >= -100)
                                        {
                                                ball.deltax=newxcount2;
                                        }
                                        else
                                        {
                                                ball.deltax=-100;
                                        }

                                        if(newycount2 > 100)
                                        {
                                                ball.deltay=100;
                                        }
                                        else if(newycount2 >= 1)
                                        {
                                                ball.deltay=newycount2;
                                        }
                                        else if(newycount2 >= 0)
                                        {
                                                ball.deltay=1;
                                        }
                                        else if(newycount2 > -1)
                                        {
                                                ball.deltay=-1;
                                        }
                                        else if(newycount2 >= -100)
                                        {
                                                ball.deltay=newycount2;
                                        }
                                        else
                                        {
                                                ball.deltay=-100;
                                        }
                                        ball.iscollision=TRUE;
                                        ball.iscollision=TRUE;
                                }
                                break;
                        }
                        else
                        {
                                count++;
                        }
                }
                if(count < BALLNUM-1)
                        ball.iscollision=TRUE;
                else
                        ball.iscollision=FALSE;
        }

        Invalidate(FALSE);

        CDialog::OnTimer(nIDEvent);
}

第二个是模拟碰撞


这个有bug,0xAA55可以帮我看看
核心代码:
BOOL CPosonDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

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

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

        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
                CString strAboutMenu;
                strAboutMenu.LoadString(IDS_ABOUTBOX);
                if (!strAboutMenu.IsEmpty())
                {
                        pSysMenu->AppendMenu(MF_SEPARATOR);
                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                }
        }

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

        // TODO: Add extra initialization here
        ShowWindow(SW_MAXIMIZE);
        CClientDC tempdc(this);
        MYDC.CreateCompatibleDC(&tempdc);
        RECT rt;
        GetClientRect(&rt);
        bmp.CreateCompatibleBitmap(&MYDC,rt.right,rt.bottom);
        MYDC.SelectObject(&bmp);
        CBrush brush(RGB(255,255,255));
        MYDC.FillRect(&rt,&brush);

        for(int i=0;i<100;i++)
        {
                pt.x=rand()%rt.right;
                pt.y=rand()%rt.bottom;
        }
        SetTimer(0,1,NULL);

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

void CPosonDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
                CAboutDlg dlgAbout;
                dlgAbout.DoModal();
        }
        else
        {
                CDialog::OnSysCommand(nID, lParam);
        }
}

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

void CPosonDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // device context for painting

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

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

                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                //CDialog::OnPaint();
                RECT rt;
                GetClientRect(&rt);
                CBrush nulbrush(RGB(255,255,255));
                MYDC.FillRect(&rt,&nulbrush);

                CPaintDC dc(this);
                CBrush brush(RGB(0,0,0));
                MYDC.SelectObject(&brush);
                for(int i=0;i<100;i++)
                {
                        MYDC.Ellipse(pt.x-5,pt.y-5,pt.x+5,pt.y+5);
                }

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

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

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

        CDialog::OnClose();
}


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

        for(int i=0;i<100;i++)
        {
                int len=rand()%10;
                switch(rand()%4)
                {
                case 0:
                        pt.y-=len;
                        if(pt.y < 0)
                        {
                                pt.y=rand()%rt.bottom;
                        }
                        break;

                case 1:
                        pt.y+=len;
                        if(pt.y >= rt.bottom)
                        {
                                pt.y=rand()%rt.bottom;
                        }
                        break;

                case 2:
                        pt.x+=len;
                        if(pt.x >= rt.right)
                        {
                                pt.x=rand()%rt.right;
                        }
                        break;

                case 3:
                        pt.x-=len;
                        if(pt.x < 0)
                        {
                                pt.x=rand()%rt.right;
                        }
                        break;
                }
        }
        Invalidate(FALSE);

        CDialog::OnTimer(nIDEvent);
}
页: [1]
查看完整版本: 2个二维运动图形方面的模拟程序