Matlab 实现 Galton knocked boards

5月写的 忘了发

事情来由:

昨天晚上兄弟突然问我会不会使用matlab来制作动画,有道题目想要我做一下

题目是这样的:

我就惊了,matlab还能用来制作动画的吗

查了一下,找到一段代码,随后开始了学习和修改的道路

原始代码是这样的:

K=100;
n=zeros(1,5);
delay=0.05;
clf;
axis([-4 4 -7 0]);
aa=sqrt(3)/2;
bb=1/2;
dd=3/2;
a=0.9*aa;
b=0.9*bb;
xx=[0,-aa,aa,-2*aa,0,2*aa,-3*aa,-aa,aa,3*aa];
yy=[0,-dd,-dd,-2*dd,-2*dd,-2*dd,-3*dd,-3*dd,-3*dd,-3*dd];
for k=1:K
   clf
   r=round(rand(1,4));
   x0=0;y0=0;
   text(1.5,-0.5,'Galton');hold on;
   text(2.5,-1,'cpw');hold on;
   for i=1:10
      x=xx(i);
      y=yy(i)-0.1;
      X=[x,x-a,x-a,x,x+a,x+a];
      Y=[y,y-b,y-b-0.9,y-1.8,y-b-0.9,y-b];
      fill(X,Y,'g');hold on;
   end
   n(sum(r)+1)=n(sum(r)+1)+1;
   plot(x0,y0,'ro');
   for j=1:4
      if r(j)==0
         x0=x0-aa;y0=y0-bb;
         plot(x0,y0,'ro');hold on;pause(delay);
         y0=y0-1;
         plot(x0,y0,'ro');hold on;pause(delay);
      else
         x0=x0+aa;y0=y0-bb;
         plot(x0,y0,'ro');hold on;pause(delay);
         y0=y0-1;
         plot(x0,y0,'ro');hold on;pause(delay);
      end
   end
   for m=1:5
      text((m-3)*sqrt(3),-6.5,num2str(n(m)));
   end
   pause(20*delay);
end

跑了一下确实不错,但是我想修改,于是就开始了一个一个函数去查询

添加注释:

K=10;  %控制实验的次数
n=zeros(1,5);  % 矩阵n为1*5的矩阵初值为0
delay=0.05;  %设置delay变量等于0.05
clf;  %清除当前窗口的图案
axis([-4 4 -7 0]);  %设置x范围-4到4 y范围-7到0
aa=sqrt(3)/2;  %aa=(根号3)/2
bb=1/2;  %bb= 1/2
dd=3/2;  %d= 3/2
a=0.9*aa;  %a= 0.9 * aa
b=0.9*bb;  %b= 0.9 * bb
xx=[0,-aa,aa,-2*aa,0,2*aa,-3*aa,-aa,aa,3*aa];  % 每个六边形顶点的坐标
yy=[0,-dd,-dd,-2*dd,-2*dd,-2*dd,-3*dd,-3*dd,-3*dd,-3*dd];  % 每个六边形顶点的坐标
for k=1:K  %循环K次
   clf  %清除当前窗口的图案
   r=round(rand(1,4));  %round函数四舍五入取整 rand函数生成一个1行4列的随机数
   x0=0;y0=0;    %
   for i=1:10  % i 循环 从1 到 10,10个六边形
      x=xx(i);  % x等于每一个六边形的顶端
      y=yy(i)-0.1;  %y等于每一个六边形的顶端
      X=[x,x-a,x-a,x,x+a,x+a];  % 标出六边形的六个点的坐标
      Y=[y,y-b,y-b-0.9,y-1.8,y-b-0.9,y-b];  % 标出六边形的六个点的坐标
      fill(X,Y,'b');hold on;  %用蓝色把XY中的部分填充
   end  
   n(sum(r)+1)=n(sum(r)+1)+1;  %
   plot(x0,y0,'ro');  %画(0,0)的红圈圈
   for j=1:4  % j 循环 从1到4
      if r(j)==0  %如果r矩阵中的第j个元素为0
         x0=x0-aa;y0=y0-bb;  % 球往左移动
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
      else  %如果r矩阵中的第j个元素为1
         x0=x0+aa;y0=y0-bb;  % 球往右移动
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
      end  
   end  
   for m=1:5  % m 循环 从1到5
      text((m-3)*sqrt(3),-6.5,num2str(n(m)));  % 最底端的位置显示字符串(掉落球的实时结果)
   end  
   pause(20*delay);  %暂停 时间20*0.05=1s
end  

这样就弄明白了这个做法的逻辑,并且对于matlab的功能有了更深的认识,随后兄弟来要求了,层数太少,结果需要比较大的样本数才能体现,于是通过计算变成了七层的图像

K=10;  %控制实验的次数
n=zeros(1,7);  % 矩阵n为1*5的矩阵初值为0
delay=0.05;  %设置delay变量等于0.05
clf;  %清除当前窗口的图案
axis([-8 8 -15 0]);  %设置x范围-4到4 y范围-7到0
aa=sqrt(3)/2;  %aa=(根号3)/2
bb=1/2;  %bb= 1/2
dd=3/2;  %d= 3/2
a=0.9*aa;  %a= 0.9 * aa
b=0.9*bb;  %b= 0.9 * bb
xx=[0,-aa,aa,-2*aa,0,2*aa,-3*aa,-aa,aa,3*aa,-4*aa,-2*aa,0,2*aa,4*aa,-5*aa,-3*aa,-aa,aa,3*aa,5*aa];  % 每个六边形顶点的坐标
yy=[0,-dd,-dd,-2*dd,-2*dd,-2*dd,-3*dd,-3*dd,-3*dd,-3*dd,-4*dd,-4*dd,-4*dd,-4*dd,-4*dd,-5*dd,-5*dd,-5*dd,-5*dd,-5*dd,-5*dd];  % 每个六边形顶点的坐标
for k=1:K  %循环K次
   clf  %清除当前窗口的图案
   r=round(rand(1,6));  %round函数四舍五入取整 rand函数生成一个1行4列的随机数
   x0=0;y0=0;    %
   for i=1:21  % i 循环 从1 到 10,10个六边形
      x=xx(i);  % x等于每一个六边形的顶端
      y=yy(i)-0.1;  %y等于每一个六边形的顶端
      X=[x,x-a,x-a,x,x+a,x+a];  % 标出六边形的六个点的坐标
      Y=[y,y-b,y-b-0.9,y-1.8,y-b-0.9,y-b];  % 标出六边形的六个点的坐标
      fill(X,Y,'b');hold on;  %用蓝色把XY中的部分填充
   end  
   n(sum(r)+1)=n(sum(r)+1)+1;  %
   plot(x0,y0,'ro');  %画(0,0)的红圈圈
   for j=1:6  % j 循环 从1到4
      if r(j)==0  %如果r矩阵中的第j个元素为0
         x0=x0-aa;y0=y0-bb;  % 球往左移动
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
      else  %如果r矩阵中的第j个元素为1
         x0=x0+aa;y0=y0-bb;  % 球往右移动
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;pause(delay);  %画红圈圈,红圈圈暂时保留,暂停0.05s
      end  
   end  
   for m=1:7  % m 循环 从1到5
      text((m-4)*sqrt(3),-9.5,num2str(n(m)));  % 最底端的位置显示字符串(掉落球的实时结果)
   end  
   pause(20*delay);  %暂停 时间20*0.05=1s
end  

并且在睡觉前设置了跑一千次,今天早上起来收结果是这样的(有点正态分布的样子了)

随后兄弟再次提要求,速度太慢,要求加快实验的速度,并且最好弄出一个柱形图来直观显示

一开始柱形图是这样的,丑出天际,随后兄弟再次提出要求,分开柱形图和球掉落的示意图,那我只能继续修改

K=1000;  %控制实验的次数
n=zeros(1,7);  % 矩阵n为1*5的矩阵初值为0
delay=0.05;  %设置delay变量等于0.05
clf;  %清除当前窗口的图案
axis([-8 8 -15 0]);  %设置x范围-4到4 y范围-7到0
aa=sqrt(3)/2;  %aa=(根号3)/2
bb=1/2;  %bb= 1/2
dd=3/2;  %d= 3/2
a=0.9*aa;  %a= 0.9 * aa
b=0.9*bb;  %b= 0.9 * bb
xxx=[-3*sqrt(3),-2*sqrt(3),-1*sqrt(3),0,1*sqrt(3),2*sqrt(3),3*sqrt(3)]; % 设定柱形图横坐标
xx=[0,-aa,aa,-2*aa,0,2*aa,-3*aa,-aa,aa,3*aa,-4*aa,-2*aa,0,2*aa,4*aa,-5*aa,-3*aa,-aa,aa,3*aa,5*aa];  % 每个六边形顶点的坐标
yy=[0,-dd,-dd,-2*dd,-2*dd,-2*dd,-3*dd,-3*dd,-3*dd,-3*dd,-4*dd,-4*dd,-4*dd,-4*dd,-4*dd,-5*dd,-5*dd,-5*dd,-5*dd,-5*dd,-5*dd];  % 每个六边形顶点的坐标
for k=1:K  %循环K次
   figure(1);
   clf  %清除当前窗口的图案
   r=round(rand(1,6));  %round函数四舍五入取整 rand函数生成一个1行4列的随机数
   x0=0;y0=0;    %
   for i=1:21  % i 循环 从1 到 10,10个六边形
      x=xx(i);  % x等于每一个六边形的顶端
      y=yy(i)-0.1;  %y等于每一个六边形的顶端
      X=[x,x-a,x-a,x,x+a,x+a];  % 标出六边形的六个点的坐标
      Y=[y,y-b,y-b-0.9,y-1.8,y-b-0.9,y-b];  % 标出六边形的六个点的坐标
      fill(X,Y,'b');hold on;  %用蓝色把XY中的部分填充
   end  
   n(sum(r)+1)=n(sum(r)+1)+1;  %
   plot(x0,y0,'ro');  %画(0,0)的红圈圈
   for j=1:6  % j 循环 从1到4
      if r(j)==0  %如果r矩阵中的第j个元素为0
         x0=x0-aa;y0=y0-bb;  % 球往左移动
         plot(x0,y0,'ro');hold on;  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;  %画红圈圈,红圈圈暂时保留,暂停0.05s
      else  %如果r矩阵中的第j个元素为1
         x0=x0+aa;y0=y0-bb;  % 球往右移动
         plot(x0,y0,'ro');hold on;  %画红圈圈,红圈圈暂时保留,暂停0.05s
         y0=y0-1;  %y0往下一单位距离,即往下走的圈圈
         plot(x0,y0,'ro');hold on;  %画红圈圈,红圈圈暂时保留,暂停0.05s
      end  
   end  
   for m=1:7  % m 循环 从1到5
      text((m-4)*sqrt(3),-9.5,num2str(n(m)));  % 最底端的位置显示字符串(掉落球的实时结果)
   end
   figure(2);
   bar(xxx,n); % 柱形图
   figure(1);  
   pause(1*delay);  %暂停 初始时间20*0.05=1s
end  

最终跑出来的样子

我觉得还算是可以接受的

最后变为matlab函数把试验次数改为一个变量让用户输入,就完成了

参考文章:

Matlab实现Galton板的动画演示

猜你喜欢

转载自blog.csdn.net/qq_39380075/article/details/80446698