Matlab模拟乒乓球发球动画

利用Matlab编写一个模拟乒乓球发球的动画,输入发球的速度,角度,计算乒乓球的轨迹并显示。

GUI界面设计

设计GUI窗体界面如下:

首先在按钮(运行的回调中)获取GUI中的输入的参数:

function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
t1=str2double(get(handles.edit1,'String'))/180*pi;
t2=str2double(get(handles.edit2,'String'))/180*pi;
v=str2double(get(handles.edit3,'String'));
% 乒乓球初速度和初始位置
x=0;y=0;z=1083-760;vx=v*sin(t1);vy=v*cos(t1)*cos(t2);vz=v*cos(t1)*sin(t2);
R=20;% 小球半径
g=9.8;% 重力加速度;
k=0.5*0.5*1.29*(3.14*0.02*0.02);% 空气阻力系数
f=0.00432;% 空气浮力
m= 0.0027; % 乒乓球质量

% 时间步长
dt=0.01;
Time=0;

绘制乒乓球的桌面

   % 绘制桌面
   xtable=[-1 -1 1 1 -1]*1525/2;
   ytable=[0 1 1 0 0]*2740;
   ztable=[0 1 0 0 0];
   axes(handles.axes1)
   patch(xtable,ytable,ztable,'k')
   hold on
   view(-130,30)
   % 绘制球网
   xw=[-1 -1 1 1 -1]*1525/2;
   yw=[1 1 1 1 1]*2740/2;
   zw=[0 1 1 0 0]*152.5;
   patch(xw,yw,zw,'b')

乒乓球运动轨迹计算

考虑重力,空气浮力和空气阻力计算乒乓球的加速度,采用向前欧拉法近似计算乒乓球的轨迹

% 绘制小球
   [X,Y,Z]=sphere;
   X=X*R+x;
   Y=Y*R+y;
   Z=Z*R+z;
   surf(-X,Y,Z,'edgecolor','r','facecolor','r')
   % 更新小球位置
   x=x+vx*dt*1000;
   y=y+vy*dt*1000;
   z=z+vz*dt*1000;
   % 更新小球速度
   ax=-sign(vx)*k*vx*vx/m;
   ay=-sign(vy)*k*vy*vy/m;
   az=-sign(vz)*k*vz*vz/m-g+f/m;
   vx=vx+ax*dt;
   vy=vy+ay*dt;
   vz=vz+az*dt;
   axis equal
   axis([-800 800 -200 3000 -10 1000])
   % 判断仿真结束
   if abs(x)>1525/2 || y>2740 || y<0 || z<0
      break 
   end
   if abs(y-2740/2)<1 && z<152.5
       break
   end
   Time=Time+dt;
   pause(0.1)
   surf(-X,Y,Z,'edgecolor','g','facecolor','g')

给定乒乓球落点,迭代计算乒乓球的发射方式

% 获取落点位置
xe=str2double(get(handles.edit4,'String'));
ye=str2double(get(handles.edit5,'String'));

flag=0;
R=20;% 小球半径
g=9.8;% 重力加速度;
k=0.5*0.5*1.29*(3.14*0.02*0.02);% 空气阻力系数
f=0.00432;% 空气浮力
m= 0.0027; % 乒乓球质量
for t1=-30/180*pi:0.005:30/180*pi
    if flag==1
         break
    end
    for t2=-20/180*pi:0.01:40/180*pi
         if flag==1
             break
         end
         for v=0:0.01:12
                x=0;y=0;z=1083-760;vx=v*sin(t1);vy=v*cos(t1)*cos(t2);vz=v*cos(t1)*sin(t2);
                % 时间步长
                dt=0.01;Time=0;
                while(1)
                    % 更新小球位置
                    x=x+vx*dt*1000;
                    y=y+vy*dt*1000;
                    z=z+vz*dt*1000;
                    % 更新小球速度
                    ax=-sign(vx)*k*vx*vx/m;
                    ay=-sign(vy)*k*vy*vy/m;
                    az=-sign(vz)*k*vz*vz/m-g+f/m;
                    vx=vx+ax*dt;
                    vy=vy+ay*dt;
                    vz=vz+az*dt;
                    % 判断仿真结束
                   if abs(x)>1525/2 || y>2740 || y<0 || z<0
                      break 
                   end
                   if abs(y-2740/2)<1 && z<152.5
                       break
                   end
                    if abs(x-xe)<5 && abs(y-ye)<5 && abs(z)<5
                        flag=1;
                        T1=t1;
                        T2=t2;
                        V=v;
                        break
                    end
                end
         end
    end
end
if flag==0
    set(handles.text9,'string','落地点无法到达')
    set(handles.text10,'string','')
    set(handles.text11,'string','')
else
    set(handles.text9,'string',['摆角为:',num2str(T1/pi*180)])
    set(handles.text10,'string',['俯仰角为',num2str(T2/pi*180)])
    set(handles.text11,'string',['速度为',num2str(v)])
    %text(-700,2740/2,300,['摆角为:',num2str(T1/pi*180),';俯仰角为',num2str(T2/pi*180),';速度为',num2str(v)])

t1=T1;t2=T2;v=V;
x=0;y=0;z=1083-760;vx=v*sin(t1);vy=v*cos(t1)*cos(t2);vz=v*cos(t1)*sin(t2);
R=20;% 小球半径
g=9.8;% 重力加速度;
k=0.5*0.5*1.29*(3.14*0.02*0.02);% 空气阻力系数
f=0.00432;% 空气浮力
m= 0.0027; % 乒乓球质量

% 时间步长
dt=0.01;
Time=0;
while(1)
   
   
   % 绘制桌面
   xtable=[-1 -1 1 1 -1]*1525/2;
   ytable=[0 1 1 0 0]*2740;
   ztable=[0 1 0 0 0];
   axes(handles.axes1)
   patch(xtable,ytable,ztable,'k')
   hold on
   view(-130,30)
   % 绘制球网
   xw=[-1 -1 1 1 -1]*1525/2;
   yw=[1 1 1 1 1]*2740/2;
   zw=[0 1 1 0 0]*152.5;
   patch(xw,yw,zw,'b')
   % 绘制小球
   [X,Y,Z]=sphere;
   X=X*R+x;
   Y=Y*R+y;
   Z=Z*R+z;
   surf(-X,Y,Z,'edgecolor','r','facecolor','r')
   % 更新小球位置
   x=x+vx*dt*1000;
   y=y+vy*dt*1000;
   z=z+vz*dt*1000;
   % 更新小球速度
   ax=-sign(vx)*k*vx*vx/m;
   ay=-sign(vy)*k*vy*vy/m;
   az=-sign(vz)*k*vz*vz/m-g+f/m;
   vx=vx+ax*dt;
   vy=vy+ay*dt;
   vz=vz+az*dt;
   axis equal
   axis([-800 800 -200 3000 -10 1000])
   % 判断仿真结束
   if abs(x)>1525/2 || y>2740 || y<0 || z<0
      break 
   end
   if abs(y-2740/2)<1 && z<152.5
       break
   end
   Time=Time+dt;
   pause(0.01)
   surf(-X,Y,Z,'edgecolor','g','facecolor','g')
   end
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢小黑屋的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值