假设猎人发现一只猴子在不远处的树上,想要举枪瞄准打掉猴子,但是猴子发现自己受到威胁,又只能从书上向下逃生,这个过程可以看作是自由落体运动。因为子弹在飞行过程中会受到重力作用,弹道向下偏离,因此猴子能不能被准确打中?忽略空气阻力与风力。
我们用matlab来实现这个过程。
设置场景
首先设想有不同的树,就可以设定不同的树。
输入编号,从1、2、3、4中选:
tree=input('请输入你设想的猴子所在树的编号(1~4)=');
%绘制树
plot([300 300],[0,150]);
plot([350 350],[0,150]);
plot([410 410],[0,150]);
plot([450 450],[0,150]);
然后设置猴子所在树的高度:
height=input('请输入你设想的猴子所在的高度,单位为米(小于等于150m)=');
为了防止输入无效的数值会导致程序无法运行,需要加入额外的代码来判断输入是否正确:
while tree>0
if tree==1||tree==2||tree==3||tree==4
switch tree
case 1
distance=300;
case 2
distance=350;
case 3
distance=410;
case 4
distance=450;
end
break;
else
tree=input('重新输入编号,别装怪=');
end
end
%判断编号是否正确
while height>0
if height>150
height=input('重新输入高度,别装怪=');
else
break;
end
end
%判断猴子高度是否正确
除此之外,还要画上猎人的枪管,用两根直线与圆形来表示,还要根据猴子的位置来计算且设置枪口能抬多高,还要瞄准:
%绘制猎人的枪管
k=height/distance;
x1=0:0.1:9;
x2=0:0.1:10;
y1=k*x1+1;
y2=k*x2-1;
theta=0:pi/400:2*pi;
R=sqrt(2)/2;
y3=(k*9+1+k*10-1)/2;
circle_x=9.5+R*cos(theta);
circle_y=y3+R*sin(theta);
hold on;
plot(x1,y1,'r-',x2,y2,'r-',circle_x,circle_y,'r-');
%绘制树
最后,用方块代表猴子,圆圈代表子弹。
开枪后实时更新子弹和猴子的位置
启用hold on指令,防止每次画图会将上一步的图给抹掉。每次迭代都会计算出新的子弹与猴子的位置,并在坐标轴旁边实时更新。
while t<=T
x=9.5+v*cos(alpha)*t;
y=y3+v*sin(alpha)*t-0.5*9.8*(t^2);
h=height-0.5*9.8*(t^2);
axis equal;
axis([0 500 0 200]);
hold on;
grid off;
plot(x,y,'bo');
plot(distance,h,'rs');%更新绘制新的位置
hold off;
drawnow;
xlabel('子弹最新位置为('+string(x)+','+string(y)+'),猴子最新位置为('+string(distance)+','+string(h)+')');%标记数据
ylabel('时刻t='+string(t)+'s');
pause(0.05);
t=t+0.05;
if round(y)==0
break;
else
continue;
end
%判断子弹是否落地
end
%开始绘图
因为要考虑子弹会落地,在此情形中如果程序继续运行就会出现子弹纵坐标为负数,子弹不可能打进地面吧,提前计算出子弹理论飞行时间T,做出判断:
T=(distance-9.5)/(v*cos(alpha));%子弹理论打中猴子总时间
t=0;
if y3+v*sin(alpha)*T-0.5*9.8*(T^2)<=0
title('子弹会落地的,打不到猴子');
else
title('子弹正在打向猴子');
end
补充说明
matlab对于子弹落地或打中猴子应该还有一个状态显示:
xlabel('子弹最新位置为('+string(x)+','+string(y)+'),猴子最新位置为('+string(distance)+','+string(h)+')');%标记数据
ylabel('时刻t='+string(t)+'s');
if round(y)==0
title('未击中猴子');
else
title('击中猴子');
end
%判断是否击中猴子
直观一点,matlab不会直接告诉我们子弹能不能打中猴子。
附上全部代码,仅作参考
clear;
close all; %清理屏幕
tree=input('请输入你设想的猴子所在树的编号(1~4)=');
height=input('请输入你设想的猴子所在的高度,单位为米(小于等于150m)=');%初始化
v=input('请输入子弹的初速度=');
%绘制场景
while tree>0
if tree==1||tree==2||tree==3||tree==4
switch tree
case 1
distance=300;
case 2
distance=350;
case 3
distance=410;
case 4
distance=450;
end
break;
else
tree=input('重新输入编号,别装怪=');
end
end
%判断编号是否正确
while height>0
if height>150
height=input('重新输入高度,别装怪=');
else
break;
end
end
%判断猴子高度是否正确
%绘制猎人的枪管
k=height/distance;
x1=0:0.1:9;
x2=0:0.1:10;
y1=k*x1+1;
y2=k*x2-1;
theta=0:pi/400:2*pi;
R=sqrt(2)/2;
y3=(k*9+1+k*10-1)/2;
circle_x=9.5+R*cos(theta);
circle_y=y3+R*sin(theta);
hold on;
plot(x1,y1,'r-',x2,y2,'r-',circle_x,circle_y,'r-');
%绘制树
plot([300 300],[0,150]);
plot([350 350],[0,150]);
plot([410 410],[0,150]);
plot([450 450],[0,150]);
%绘制猴子,用方点代替猴子
plot(distance,height,'rs');
%绘制子弹,用圆圈代替子弹
plot(9.5,y3,'bo');
text(200,3,'地面');
text(301,30,'1');
text(351,30,'2');
text(411,30,'3');
text(451,30,'4');%标记树的编号
%下面为开枪后子弹飞出的过程
alpha=atan(k);
T=(distance-9.5)/(v*cos(alpha));%子弹理论打中猴子总时间
t=0;
if y3+v*sin(alpha)*T-0.5*9.8*(T^2)<=0
title('子弹会落地的,打不到猴子');
else
title('子弹正在打向猴子');
end
%提前判断子弹是否落地
while t<=T
x=9.5+v*cos(alpha)*t;
y=y3+v*sin(alpha)*t-0.5*9.8*(t^2);
h=height-0.5*9.8*(t^2);
axis equal;
axis([0 500 0 200]);
hold on;
grid off;
plot(x,y,'bo');
plot(distance,h,'rs');%更新绘制新的位置
hold off;
drawnow;
xlabel('子弹最新位置为('+string(x)+','+string(y)+'),猴子最新位置为('+string(distance)+','+string(h)+')');%标记数据
ylabel('时刻t='+string(t)+'s');
pause(0.05);
t=t+0.05;
if round(y)==0
break;
else
continue;
end
%判断子弹是否落地
end
%开始绘图
if round(y)==0
title('未击中猴子');
else
title('击中猴子');
end
%判断是否击中猴子
大学新生作品,若代码有问题或不当的地方,恳请各位大佬斧正!