100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > matlab小球水平抛出 如何用Matlab制作小球自由落体运动的动画

matlab小球水平抛出 如何用Matlab制作小球自由落体运动的动画

时间:2019-01-12 16:38:03

相关推荐

matlab小球水平抛出 如何用Matlab制作小球自由落体运动的动画

第一堂课布置了一个Mission Impossible作业,要求学生们用Matlab制作一个动画,模拟小球的自由落体运动。

以下将整个任务的问题解决的过程分享如下:

步骤一,这是一个动画的制作过程,以 “Matlab” + "动画"为关键词先问一声度娘,得到线索“怎样用Matlab做动画演示”。

这个资料里有提到一种制作动画的方法getframe,每画一幅图片就getframe一次赋给一个变量,比如说M,最后的时候用movie(M,1)播放这个动画,或者用movie2avi函数将动画保存成一个avi文件。

步骤二,这时候问题转移到,如何制作每一帧图片。我们需要画一个画布,同时在画布上生成一个坐标对象,并且借助坐标把一个实心或者空心圆画上去。以 “Matlab” + "画图"为关键词再度娘,得到两个线索,第一个是Figure的机制,第二个是类似火星十一郎-张朋飞写的“Matlab绘图”,通过这些线索可以了解画图一般都会先设置一个Figure,然后在规定好X轴和Y轴的axis的指定位置上plot一个实心或者空心圆。

很显然,这一步是非常难的,因为大部分分享Matlab信息的网友很难从一个Matlab初学者的角度来思考,经常一上来就大谈特谈plot函数,很少有人会一开始就讲Figure机制(我们是需要一个画布的呀!),在Matlab里边作图需要借助特定的对象axis,然后才是plot函数的使用。

代码写出来会很简单:

figure;

axis([0 20 0 20]);

plot(10, 10, '-or');%坐标轴X为10,和Y为10的位置,画一个实线的(用'-'来表示)空心圆(用'o'来表示),颜色为红色(用'r'来表示)

这个坐标轴是动态的,需要借助一个set函数,将当前的axis的坐标轴属性固定住,代码如下:

set(gca,'nextplot','replacechildren','box','off','color','w','xgrid','off')

步骤三,掌握了画单个图片的方法,接下来就是要画自由落体的每一帧的图片了。这里的X可以固定起来,设为定值10;Y一开始是在最高的位置,设为H0 = 20,当球开始下落的时候这个Y值是随着时间t的变化而变化的,变化的速度又和加速度a有关,它具体指向自由落体的小球的高度:currentHeight = H0 - 0.5 * a * t * t。这部分是高中物理知识,假定不考虑空气摩擦力的话,这里的加速度就可以用重力加速度g来表示,一般可以简单设为定值10。

这样,整个程序就写出来了:

% FileName is :: movieExample.m

% clear

clc; clear; close all;

figure('toolbar','none','menubar','none','NumberTitle','off','name','自由落体动画录制');

axis([0 20 0 20])

set(gca,'nextplot','replacechildren','box','off','color','w','xgrid','off')

%initialize, based on about 2s movie, 20 frame/s

tEnd = 2;

frameN_s = 20;

nFrame = tEnd * frameN_s;

zyltMovie = moviein(nFrame, gcf);%初始化一个zyltMovie的矩阵

g = 10;

v0 = 0;

t0 = 0;

dt = 0.05;

h0 = 20;

% LOOP

for iFrame = 1:nFrame

t = t0 + dt * iFrame;

v = v0 + g * t;

currentHeight = h0 - 1/2 * v * t;

plot(10, currentHeight, '-or');

zyltMovie(:,iFrame) = getframe(gcf);

end

movie2avi(zyltMovie, 'AnimateEllipse.avi', 'compression', 'None');

如果能够让小球触地后反弹,动画会更生动有趣。在算法上,它只是涉及到对高中物理知识的运用,(1)当小球下落的时候,当高度currentH < 0 的时候,说明小球已经触地,需要将作用于小球的加速度反向,a = -g,同时小球的速度也要重新初始化,比如设 v0 = -0.67v;(2)当小球上升的时候,当速度 v > 0 的时候,说明小球已经到达最高点并开始下落,这个时候加速度再次变成 a = g。

修改过的版本如下:

% FileName is :: movieExample.m

% clear

clc; clear; close all;

figure('toolbar','none','menubar','none','NumberTitle','off','name','自由落体动画录制');

axis equal;

axis([0 20 0 20]);

set(gca,'nextplot','replacechildren','box','off','color','w','xgrid','off')

%initialize, based on about 8s movie, 20 frame/s

tEnd = 10;

frameN_s = 20;

nFrame = tEnd * frameN_s;

zyltMovie = moviein(nFrame, gcf);

g = 10;

a = g;

dt = 0.05;

v0 = 0;

t0 = 0;

h0 = 20;

Flag_Down = 1;

Flag_Up = 0;

currentFlag = Flag_Down;

for iFrame = 1:nFrame

if currentFlag == Flag_Down

t = dt * iFrame - t0;

v = v0 + a * t;

currentH = h0 - 0.5 * v * t;

if currentH < 0

plot(10, currentH, '.r', 'markersize', 50);

zyltMovie(:,iFrame) = getframe(gcf);

currentFlag = Flag_Up;

a = -g;

t0 = dt * iFrame;

v0 = -0.67 * v;

continue;

else

plot(10, currentH, '.r', 'markersize', 50);

zyltMovie(:,iFrame) = getframe(gcf);

end

end

if currentFlag == Flag_Up

t = dt * iFrame - t0;

v = v0 - a * t;

currentH = -v0 * t + 0.5 * a * t * t;

if v > 0

plot(10, currentH, '.r', 'markersize', 50);

zyltMovie(:,iFrame) = getframe(gcf);

currentFlag = Flag_Down;

a = g;

t0 = dt * iFrame;

v0 = 0;

h0 = currentH;

continue;

else

plot(10, currentH,'.r', 'markersize', 50);

zyltMovie(:,iFrame) = getframe(gcf);

end

end

end

movie2avi(zyltMovie, 'AnimateEllipse.avi', 'compression', 'None');

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。