Animating the Motion of a Ball

Note: The code we developed can be found here: ball.m

In an earlier homework, we considered the one-dimensional movement of a baseball, with an initial vertical velocity of 43.81 meters/second, and with gravity as a downward force with a constant acceleration of 9.8 meters/second/second.

Based on calculus, the height at time t is equal to
h(t) = v0 t - gt2/2
and velocity at time t is equal to
v(t) = v0 - gt
We calculated the height for a range of times using vectorized operations as

g = 9.8;                              % gravity
v = 43.81;                            % initial velocity (98 mph = 43.81 m/s)

endtime = 2*v/g;                      % when it hits the ground
timestep = endtime/100;
t = 0:timestep:endtime;
height = v .* t - g .* t .^ 2 ./ 2;

animating the motion

g = 9.8;                              % gravity
v = 43.81;                            % initial velocity (98 mph = 43.81 m/s)
frames = 100;

endtime = 2*v/g;                      % when it hits the ground
timestep = endtime/frames;
t = 0:timestep:endtime;
height = v .* t - g .* t .^ 2 ./ 2;

window = [-1 1 0 max(height)];
for h = height
  plot([0], h, 'o');
  grid on;
  axis(window);                      % keep view fixed for all frames (why?)
  pause(timestep);                   % pause between frames
end

two-dimensional motion

Let's now consider the two-dimensional version of the problem, assuming that the ball's initial velocity is directed at an angle of 60-degrees from horizontal. The calculus can be applied separately on the x and y components of the motion using the formula
x(t) = vx0 t
y(t) = vy0 t - gt2/2
where
vx0 = v cos(angle)
vy0 = v sin(angle)
Here is our script animating the motion. This time, rather than clearing the plot at each step, we use hold so that we can overlay each new plot on the existing graph.

g = 9.8;      % gravity
v = 43.81;    % initial velocity (98 mph = 43.81 m/s)
angle = 60;   % measured in degrees
vx = v * cosd(angle);
vy = v * sind(angle);

endtime = 2*vy/g;
timestep = endtime/100;
t = 0:timestep:endtime;
x = vx .* t;
y = vy .* t - g .* t .^ 2 ./ 2;

window = [0 1.1*max(x) 0 1.1*max(y)];
for i = 1:length(t)
  plot(x(i), y(i), 'o');
  hold on;
  grid on;
  axis equal;                     % necessary to ensure that x and y axes are drawn with equal scale
  axis(window);
  pause(timestep);                % pause between frames
end
hold off;

saving an animated image (gif) file

Lastly, you might want to create an animated image file that does not rely on having MATLAB. One common image format (gif) supports animated images, and MATLAB can generate such images. We won't cover the steps necessary to do this in detail, but if you examine each step you'll see that we are converting the plotted graph into individual frames of the animated file. The following code between the comments "begin image write" and "end image write" only assumes that there is an active plot window, so you may copy and paste this code into other contexts as you see fit.

filename = 'ball.gif';
frames = 100;

g = 9.8;
v = 43.81;

endtime = 2*v/g;
timestep = endtime/frames;
t = 0:timestep:endtime;
heights = v.*t - g.*t.^2./2;

window = [-1 1 0 max(heights)+1];
for h = heights
    plot([0], h, 'o')
    grid on;
    axis(window);
    
    %Image code from MATLAB doc for imwrite
    %begin image write
    drawnow
    frame = getframe(1);
    im = frame2im(frame);
    [A, map] = rgb2ind(im,256);
    if h == heights(1);
        imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',timestep);
    else
    	imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',timestep);
    end
    %end image write
end


Originally by
Michael Goldwasser