先上效果图,图中小球是动态下落的,下落到对应桶里会更新相应计数。

《1》建立基于单文档的应用程序,名为:GEDB。

《2》为类CDEDBView添加成员函数void CGEDBView::DrawFrame(CDC *pDC),并添加如下代码:

void CGEDBView::DrawFrame(CDC *pDC)

{

CRect rc;//定义一个矩形区域变量

GetClientRect(rc);//获取当前窗口的客户区大小

CPoint point[12] ;

point[0] = (85 ,5) ;//画图区域的左上角

point[1] = (685 ,403) ;//画图区域的右下角

//设置每个钉子的半径为12

int R = 12 ;

//绘制图形区域的边缘(灰色)

CPen pen(PS_INSIDEFRAME,1,RGB(192,192,192));//定义画笔

CPen* oldPen=pDC->SelectObject(&pen); //将pen选入设备环境

CRect recttempt(85,5,685,403) ;

pDC->Rectangle(recttempt) ;

//绘制显示小球的所在区域

CRect rect1(85 -4*R ,300-23*R ,85-2*R ,300+7*R) ;

pDC->Rectangle(rect1) ;

pDC->SetBkColor(RGB(250,250,0)) ;

CString str[2]= {"顶部","底部"};

pDC->TextOut(85 -4*R,300-25*R,str[0]) ;

pDC->TextOut(85 -4*R,300+8*R,str[1]) ;

//绘制不同桶间的分割线(蓝色)

CPen Lpen0 ;

Lpen0.CreatePen(PS_SOLID ,2 ,RGB(0,0,255)) ;

pDC->SelectObject(Lpen0) ;

for (int i = 1 ;i<12 ;i++)

{

pDC->MoveTo(100 + i*4*R ,400) ;

pDC->LineTo(100 + i*4*R ,300) ;

}

//绘制高尔顿版的边缘(肖贡土色)

CPen Lpen1 ;

Lpen1.CreatePen(PS_DASH ,5 ,RGB(197,97,20)) ;

pDC->SelectObject(Lpen1) ;

pDC->MoveTo(100,400) ;

pDC->LineTo(100 ,300) ;

pDC->MoveTo(676,400) ;

pDC->LineTo(676 ,300) ;

pDC->MoveTo(100,400) ;

pDC->LineTo(676 ,400) ;

pDC->MoveTo(100 ,300) ;

pDC->LineTo(375 ,25) ;

pDC->MoveTo(676 ,300) ;

pDC->LineTo(406 ,25) ;

pDC->MoveTo(375 ,25) ;

pDC->LineTo(375 ,10) ;

pDC->MoveTo(406 ,25) ;

pDC->LineTo(406 ,10) ;

CPen Lpen3(PS_NULL ,1 ,RGB(0,0,0)) ;//创建无边缘的画笔

pDC->SelectObject(Lpen3) ;

CBrush brush(RGB(0,255,0)) ;

CBrush *OldBrush = pDC->SelectObject(&brush) ;

for (i = 0 ;i<12;i++)

{

for (int j = 1 ;j <12-i ;j++)

{

//绘制钉子

pDC->Ellipse(100+j*4*R-R + i*2*R ,300+R - i*2*R,100+j*4*R+R+ i*2*R ,

300-R - i*2*R) ;

//绘制小球下落位置的提示球

pDC->Ellipse(85 - 4*R ,300+R - i*2*R ,85 - 2*R ,300-R - i*2*R) ;

}

}

//因为提示球的行数比钉子多三个,故还需要画3个

for (i =1 ;i<4;i++)

{

CRect rectRange;

rectRange.left = 85 - 4*R ;

rectRange.top = 300 - R ;

rectRange.right = 85 - 2*R ;

rectRange.bottom = 300 + R ;

//绘制小球下落位置的提示球

pDC->Ellipse(rectRange.left ,rectRange.top + i*2*R ,

rectRange.right ,rectRange.bottom + i*2*R) ;

}

pDC->SelectObject(OldBrush) ;

pDC->SelectObject(oldPen);//恢复原来画笔的属性

}

《3》在函数void CGEDBView::OnDraw(CDC* pDC)中添加如下代码:

void CGEDBView::OnDraw(CDC* pDC)

{

CGEDBDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

pDC->SetViewportExt(800,400);//设置视口范围

if (CGEDBView::N == CPublic::BallNumber)//实验次数大于设定的时候

{

AfxMessageBox("程序结束!") ;

Return ;

}

DrawFrame(pDC) ;//画框架

//总共有11块板

const int N = 11 ;//高尔顿版板的数目

}

《4》为类CGEDBViw添加成员变量public:

CButton m_MyButton1;

CButton m_MyButton2;//用于创建两个按钮

CButton m_MyButton3;

添加消息响应函数OnInitialUpdate,并添加如下代码:

void CGEDBView::OnInitialUpdate()

{

CView::OnInitialUpdate();

//创建开始按钮

m_MyButton1.Create("开始试验",WS_CHILD|BS_DEFPUSHBUTTON,CRect(700,0,800,50),

this,ID_MyButton1);

m_MyButton1.ShowWindow(SW_SHOWNORMAL);

//创建终止按钮

m_MyButton2.Create("暂停试验",WS_CHILD|BS_DEFPUSHBUTTON,CRect(850,0,950,50),

this,ID_MyButton2);

m_MyButton2.ShowWindow(SW_SHOWNORMAL);

//创建退出按钮

m_MyButton3.Create("退出",WS_CHILD|BS_DEFPUSHBUTTON,CRect(850,370,950,420),

this,ID_MyButton3);

m_MyButton3.ShowWindow(SW_SHOWNORMAL);

}

《5》为类CGEDBViw添加消息响应函数OnDestroy,并添加如下代码:

void CGEDBView::OnDestroy()

{

CView::OnDestroy();

// TODO: Add your message handler code here

//此函数可以删除

//KillTimer(1) ;//清除定时器

}

《6》为类CGEDBViw添加消息响应函数OnTimer,并添加如下代码:

void CGEDBView::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (CGEDBView::N == CPublic::BallNumber) //实验进行了设定的次数

{

KillTimer(1) ;//销毁计时器

return ;

}

CDC *pDC = GetDC() ;

CGEDBView::OnDrawBall(pDC) ;//画球

CView::OnTimer(nIDEvent);

}

《7》在CGEDBViw类中添加成员变量数组;

public:

static int Backet[12] ;//统计各个区间的珠子的数目

static int N ;//定义实验次数

static int BallRound;

并在CGEDBViw.Cpp中初始化,在其构造函数CGEDBView::CGEDBView()前添加初始化语句,int CGEDBView::Backet[12]={0,0,0,0,0,0,0,0,0,0,0,0};

int CGEDBView::N = 0 ;//初始化计数器

int CGEDBView::BallRound = 0 ;

《8》为类CGEDBView添加成员函数OnDrawBall,并添加如下代码:

//绘制小球下落轨迹

void CGEDBView::OnDrawBall(CDC *pDC)

{

CGEDBView::BallRound++ ;//计数器加一

//设置每个钉子的半径为12

int R = 12 ;

static CRect rc(400-2*R,50,400,25) ;

//先擦除上一个圆

CPen   pen;

pen.CreateStockObject(NULL_PEN);

CPen   *pOld   =   pDC-> SelectObject(&pen);

pDC->Ellipse(rc.left ,rc.top,rc.right ,rc.bottom);//把圆擦除

pDC->SelectObject(pOld) ;

//将显示小球位置提示球的颜色还原(还原为蓝色)

CPen Lpen3(PS_NULL ,1 ,RGB(0,0,0)) ;//创建无边缘的画笔

pDC->SelectObject(Lpen3) ;

CBrush Lbrush(RGB(0,255,0)) ;

pDC->SelectObject(&Lbrush) ;

pDC->Ellipse(85 - 4*R ,rc.top,85 - 2*R ,rc.bottom) ;

//重新绘制下一个圆

//创建画笔

CPen newpen(PS_NULL ,1 ,RGB(0,0,0)) ;

CPen *OldPen =  pDC->SelectObject(&newpen) ;

//创建画刷(画球)

CBrush brush(CPublic::Ballref) ;

CBrush *OldBrush = pDC->SelectObject(&brush) ;

//前面的12步小球都可以向左或者右运动,

//但是第13、14、15步设置的是直接下落过程

if (CGEDBView::BallRound == 13||CGEDBView::BallRound == 14)

{

rc.top += 2*R ;

rc.bottom += 2*R ;

pDC->Ellipse(rc.left ,rc.top,rc.right ,rc.bottom) ;

//将显示小球位置提示球的颜色改变

pDC->Ellipse(85 - 4*R ,rc.top,85 - 2*R ,rc.bottom) ;

pDC->SelectObject(OldBrush) ;

pDC->SelectObject(OldPen);//恢复原来画笔的属性

return ;

}

if (CGEDBView::BallRound == 15)

{

CGEDBView::N++ ;//计数器加一

//更新下落的球的总数

CString tstr ,tstr2;

tstr2.Format("%-5d" ,CGEDBView::N) ;

tstr = "下落的小球数目" ;

pDC->SetBkColor(RGB(250,250,0)) ;

pDC->TextOut(800,100,tstr) ;

pDC->TextOut(820,130,tstr2) ;

rc.top += 2*R ;

rc.bottom += 2*R ;

pDC->Ellipse(rc.left ,rc.top,rc.right ,rc.bottom) ;

pDC->Ellipse(85 - 4*R ,rc.top,85 - 2*R ,rc.bottom) ;

pDC->SelectObject(OldBrush) ;

pDC->SelectObject(OldPen);//恢复原来画笔的属性

CGEDBView::BallRound = 0 ;//计数器置零

return ;

}

//新一轮的开始,将小球置于高尔顿板进口处

if (CGEDBView::BallRound == 1)

{

rc.left = 400-2*R ;

rc.top = 50 ;

rc.right = 400;

rc.bottom = 25;

//画球(小球)

pDC->Ellipse(rc.left ,rc.top,rc.right ,rc.bottom) ;

pDC->Ellipse(85 - 4*R ,rc.top,85 - 2*R ,rc.bottom) ;

return ;

}

//参数N为该小球下落的第N步(0<=N<12);参数direction为小球下落方向

//direction=0表示向左,direction=1表示向右.

const int N = 11 ;//高尔顿版板的数目

//sum=0则落在最左边的区间,sum=N-1则落在最右边的区间

static int sum = 0 ;//小球向左一次则加零,向右一次则加一

int direction = 0 ;//小球在某一步的方向

//产生(0,1)区间上的随机数

float x = 0 ;

x = (float) (rand()%100)/100.0 ;

if (x >= 1-CPublic::RightChance)

direction = 1 ;

else

direction = 0 ;

sum += direction ;

//一个小球需要15步才能落入桶中,

//前面的12步就可以决定落入的桶的编号

if (CGEDBView::BallRound  == 12)

{

CGEDBView::Backet[sum]++ ;//对应的桶的小球数目加一

CGEDBView::InitialBallAmount();//初始化公共类的BallAmount[12]数组

sum = 0 ;

}

for (int k = 0 ;k<N+1 ;k++)

{

CString str ;

str.Format("%-4d" ,CGEDBView::Backet[k]) ;

pDC->SetBkColor(RGB(250,250,0)) ;

pDC->TextOut(110+k*50 ,405 ,str) ;

}

if (direction == 0)//向左

{

//将小球向左移动一个位置,并且向下移动一个位置

rc.left -= 2*R ;

rc.top += 2*R ;

rc.right -= 2*R ;

rc.bottom += 2*R ;

}

else if (direction == 1)//向右

{

//将小球向右移动一个位置,并且向下移动一个位置

rc.left += 2*R ;

rc.top += 2*R ;

rc.right += 2*R ;

rc.bottom += 2*R ;

}

else

{

MessageBox("程序出错!") ;

return ;

}

pDC->Ellipse(rc.left ,rc.top,rc.right ,rc.bottom) ;

pDC->Ellipse(85 - 4*R ,rc.top,85 - 2*R ,rc.bottom) ;

pDC->SelectObject(OldBrush) ;

pDC->SelectObject(OldPen);//恢复原来画笔的属性

}

《9》为类CGEDBView添加成员函数void CGEDBView::InitialBallAmount(),用于初始化公共类的数组BallAmount[12],并添加如下代码:

void CGEDBView::InitialBallAmount()

{

const int Backet = 12 ;

for (int i = 0 ;i<Backet ;i++)

{

CPublic::BallAmount[i] = CGEDBView::Backet[i] ;

}

}

并在GEDBView.cpp中包含头文件#include "Public.h"。

《10》打开资源中的“String Table”,在空白行上双击鼠标,这时会弹出一个ID属性对话框,在其中的ID编辑框中输入ID_MyButton1,标题:开始试验,其值为:61446再次添加,输入ID:ID_MyButton2,标题:暂停试验,其值为:61447。在编辑框中输入ID:ID_MyButton3,标题:退出,其值为:61448.

在GEDBView.h类的定义中添加如下代码:

protected:

//{{AFX_MSG(CGEDBView)

afx_msg void OnDestroy();

afx_msg void OnTimer(UINT nIDEvent);

//}}AFX_MSG

afx_msg void OnMybut1();

afx_msg void OnMybut2();

afx_msg void OnMybut3();

DECLARE_MESSAGE_MAP()

在GEDBView.cpp中添加如下代码:

BEGIN_MESSAGE_MAP(CGEDBView, CView)

//{{AFX_MSG_MAP(CGEDBView)

ON_WM_DESTROY()

ON_WM_TIMER()

//}}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)

ON_BN_CLICKED(ID_MyButton1, OnMybut1)

ON_BN_CLICKED(ID_MyButton2, OnMybut2)

ON_BN_CLICKED(ID_MyButton3, OnMybut3)

END_MESSAGE_MAP()

《11》在GEDBView.cpp中实现开始试验按钮与终止试验按钮的消息响应函数:

void CGEDBView::OnMybut1()

{

AfxMessageBox("程序开始!") ;

SetTimer(1,CPublic::Fallpace ,NULL) ;//安装定时器1

srand((unsigned int)time(NULL));//随机数种子

}

void CGEDBView::OnMybut2()

{

KillTimer(1) ;//清除定时器

//每个桶中的球都置空

for (int i = 0 ;i<12 ;i++)

{

CPublic::BallAmount[i] = 0 ;

CGEDBView::Backet[i] = 0 ;

}

AfxMessageBox("程序暂停!") ;

}

void CGEDBView::OnMybut3()

{

AfxMessageBox("程序结束!") ;

::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLOSE,0,0);

}

《10》效果如下所示:

《11》为MessageBox()消息框添加自动关闭功能

(1)在函数void CGEDBView::OnInitialUpdate() 中添加如下代码:

SetTimer(2,1000,NULL) ;//为MessageBox()函数添加定时器

(2)在GEDBView.cpp中定义如下变量及常量:

#define Wait_MessageBox 2 //定义自动关闭MessageBox消息框的时间

#define Message_Title "GEDB"消息框的标题,用于查找消息框的句柄

BOOL  fgMsgDlgShow = FALSE;       //消息框弹出标记

UINT  nMsgDlgTimer = 0;           //消息框计数器

(3)在void CGEDBView::OnTimer(UINT nIDEvent)中做如下修改

void CGEDBView::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC = GetDC() ;

switch(nIDEvent)

{

case 1:

if (CGEDBView::N == CPublic::BallNumber)//实验进行了设定的次数

{

KillTimer(1) ;//销毁计时器

return ;

}

CGEDBView::OnDrawBall(pDC) ;//画球

CView::OnTimer(nIDEvent);

break ;

case 2:

if(fgMsgDlgShow)

{

nMsgDlgTimer++;

if(nMsgDlgTimer >= Wait_MessageBox)

{

fgMsgDlgShow = FALSE ;//撤销标记

CWnd* hWnd;

hWnd = FindWindow(NULL,Message_Title); //根据标题,查找消息框句柄

if(hWnd) hWnd->SendMessage(WM_CLOSE, NULL, NULL); //找到后,向其发关闭消息

}

}

break ;

default:

break ;

}

}

(4)在void CGEDBView::OnMybut1()作如下修改:

void CGEDBView::OnMybut1()

{

fgMsgDlgShow = TRUE;

nMsgDlgTimer = 0;

AfxMessageBox("程序开始!") ;

CPublic::CPublic();//初始化实验设置

SetTimer(1,CPublic::Fallpace ,NULL) ;//安装定时器1

srand((unsigned int)time(NULL));//随机数种子

}

(5)在void CGEDBView::OnMybut2()中作如下修改:

void CGEDBView::OnMybut2()

{

KillTimer(1) ;//清除定时器

//每个桶中的球都置空

for (int i = 0 ;i<12 ;i++)

{

CPublic::BallAmount[i] = 0 ;

CGEDBView::Backet[i] = 0 ;

}

fgMsgDlgShow = TRUE;

nMsgDlgTimer = 0;

AfxMessageBox("程序暂停!") ;

}

(6)在void CGEDBView::OnMybut3()中作如下修改:

void CGEDBView::OnMybut3()

{

fgMsgDlgShow = TRUE;

nMsgDlgTimer = 0;

AfxMessageBox("程序结束!") ;

::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLOSE,0,0);//关闭对话框

}

MFC模拟高尔顿板实验相关推荐

  1. matlab模拟高尔顿板实验,高尔顿钉板试验模拟

    public void galton(int sumOfGrid, int sumOfBall){ int[] grid = new int[sumOfGrid]; int number = 0; / ...

  2. MATLAB模拟伽尔顿板实验

    MATLAB模拟伽尔顿板实验代码展示: clear;b=1;k=1;dxdy=0.81;r=0.1;ttt=0:pi/300:2*pi;xxx=r*exp(i*ttt);for n=1:80for m ...

  3. 拉普拉斯分布_中心极限定理:从高尔顿板到麦克斯韦分布

    ​神奇的正态分布源于"加". 撰文 | 张和持 时隔多年,或许你早就记不得16岁那年夏天高中闷热的教室,但可能会记得有一天数学老师说着要给大伙看个稀奇--一块祖传的高尔顿板.尽管班 ...

  4. matlab仿真高尔顿正态分布源码,中心极限定理:从高尔顿板到麦克斯韦分布

    神奇的正态分布源于"加". 撰文 | 张和持 时隔多年,或许你早就记不得16岁那年夏天高中闷热的教室,但可能会记得有一天数学老师说着要给大伙看个稀奇--一块祖传的高尔顿板.尽管班上 ...

  5. 模拟撞击_模玩资讯:EPOCH 汽车撞击测试用模拟假人与实验车辆

    日本著名玩具制造商 EPOCH(エポック社),最近又准备推出一款很特别的有趣主题之扭蛋玩具,就是将电视上常见的汽车撞击测试的模拟用假人,以及实验专用的测试车辆,这两项物品的实体化扭蛋玩具!预计在 20 ...

  6. 计算机网络模拟校园,计算机网络课程设计-模拟校园网组网实验

    计算机网络课程设计-模拟校园网组网实验 福建农林大学金山学院 信息工程类 课程实习报告 课程名称: 计算机网络 实习题目: 校园网组网方案 姓 名: 严夫 系: 信息与机电工程系 专 业: 计算机科学 ...

  7. 计算机网络模拟校园,计算机网络课程设计模拟校园网组网实验.doc

    计算机网络课程设计模拟校园网组网实验.doc 福建农林大学 金山 学院 信息工程 类 课程实习报告 课程名称: 计算机网络 实习题目: 校园网组网方案 姓 名: 严夫 系: 信息与机电工程系 专 业: ...

  8. 读取usb口数据_Mixly 第12课 模拟值读取实验串口使用

    第12课  模拟值读取实验--串口使用 串行通信是在实现在PC机与微控制器进行交互的最简单的办法.以常见的Arduino UNO为例,面板上只有一组串行端口,即引脚 0(RX)和1(TX).电脑与Ar ...

  9. HCIA/HCIP使用eNSP模拟VRRP配置实验(接入层 汇聚层 核心层 VLAN OSPF VRRP STP DHCP的综合应用)

    使用eNSP模拟 VRRP配置实验 接入层 汇聚层 核心层 VLAN OSPF VRRP STP DHCP的综合应用 目录 使用eNSP模拟 VRRP配置实验 拓扑预览 实验要求 知识总结 1 VRR ...

最新文章

  1. 有关定时任务的表达式--cron 详细解
  2. 【Java 网络编程】UDP 服务器 与 客户端持续交互 案例
  3. 函数09 - 零基础入门学习C语言40
  4. ERP物料采购系统需求分析与效果展示 ERP实施以失败告终的四个原因分析
  5. R语言 非中心化F分布
  6. 数字化转型生态的三个层级(平台 场景 工具/技术)
  7. FTP服务器之pure-ftpd常见问题及解决方法
  8. React开发(132):ant design学习指南之form中控制展开和关闭逻辑
  9. python第一行左对齐_关于Python的第一行语句
  10. 骨骼的动作识别数据集_基于关节数据的人体动作识别
  11. 磁盘分区命令fdisk、parted和gdisk
  12. 调频广播如何发明的?
  13. TCP模拟HTTP请求
  14. Docker - 使用Docker Compose部署应用
  15. Simultaneous Feature Learning and Hash Coding with Deep Neural Networks
  16. JS可选链操作符 (?.)
  17. STM32平台的USART串口通信
  18. 读文献——一些专有名词的学习记录
  19. 用HTML加CSS模仿的W3school的主页
  20. python清空文件_python清空文件

热门文章

  1. graylog+kafka+zookeeper(单机测试及源码),graylog收集kafka(脚本创建发布订阅方式)存储的消息(四)
  2. html win10虚拟键盘,笔记本电脑win10虚拟键盘打开的方法
  3. apollo学习之---(17)commen-math学习
  4. 苹果手机浏览器下拉会闪动的解决办法
  5. 个人开发者的项目如何接入支付宝登录功能(保姆级教学)(Java的后台为例,其他语言类似)
  6. 纯CSS3流光边框特效
  7. 用Django编写邮箱注册以及验证码
  8. postman 获取接口参数_postman 接口参数化操作
  9. Win10如何进行兼容性视图设置,教程来啦!怎么设置兼容性视图
  10. 科罗拉多州奥罗拉市用基于磁盘的ExaGrid系统取代磁带备份