Animation

From ComputingForScientists

Jump to: navigation, search

In scientific visualization, animation usually requires these steps:

  1. Generate a baseline image.
  2. View all images in a sequence by creating a loop that produces one image per iteration by modifying something in the baseline image.
  3. Adjust labels, axes limits, etc. based on what is observed in previous step.
  4. Run the loop and write out one image per iteration (usually in PNG or JPEG format).
  5. Use an external program to concatenate the images into a movie (e.g., FFmpeg).

Notes:

  • I usually keep the image files after creating the movie. Often during a presentation one wants to show only a single frame or two. It is easier to just grab a single image. In addition, if you ever want to recreate the movie, you can start with the original frames instead of converting from an existing movie (and there may be less loss of quality).
  • MATLAB has a function called animate that you may use to create an animation. The approach given in the example below does not use this function.

The following is a set of MATLAB commands that change the color of a line based on the frame number and creates and writes a file after each step.

Contents

  1. MATLAB Example
  2. FFmpeg
    1. Windows
    2. Linux
  3. Problems
    1. Animating a Point I
    2. Animating a Point II
    3. Animating a Line I
    4. Animating a Line II
    5. Particle Trajectory

1. MATLAB Example

The key to any animation program is a part that depends on the frame number (or the index variable in the outer-most loop). In this case, the index variable is named frame and the part that depends on this is the line color.

Note that the following program creates the frames but does not create the movie.

clear;clf

x = [1:10];
y = [1:10];
for frame = 1:10
   
   % Ca is a three-element (rgb) array used as an argument to
   % plot for the line color.
   Ca = [frame/10 frame/10 frame/10];
   plot(x,y*frame,'-','LineWidth',3,'Color',Ca);

   % hold on tells MATLAB to not clear figure when next plot command issued.
   hold on; 

   % drawnow tells MATLAB to render immediately.  If this is not done,
   % and plots happen quickly, MATLAB may wait until things slow down
   % before rendering on the screen - an you may only see the last frame.
   drawnow; 

   % Uncomment the following to make MATLAB wait until you 
   % hit enter to show the next plot.  Useful for debugging.
   %input('Continue?');

   % Set axis limits.  See help axis.
   axis([1 10 0 100]);

   % Create a filename for the image.  %02d means "a 2 digit integer that is
   % zero padded, e.g., 01, 02, 03, ...".  No semicolon is given at end
   % so file that is being written is displayed in the console.
   fname = sprintf('lines_%02d.png',frame)

   % "print" the image to a file in png format (the -d means "device").
   % Both words "print" and "device" are anachronisms.
   print('-dpng',fname);
end

2. FFmpeg

Once the frames are created, a separate program can be used to combine them into a video. The most versatile program for this is FFmpeg. Many other programs exist (many are easier to install!), but this is the one you probably want to use.

First, install FFmpeg, then execute the following command in the directory where your images are located:

2.1. Windows

First, download FFmpeg.

Unzip the file (you may need to install 7z, which can unzip file with the .7z extension). Then, copy ffmpeg.exe to the directory where your images are located. Open a MS-DOS shell, cd to that directory, and enter

ffmpeg.exe -start_number 0 -i "lines_%02d.png" lines.mp4

2.2. Linux

First, open a terminal and then cd to the directory where your images are located. Then download the program by entering on the command line:

wget http://johnvansickle.com/ffmpeg/builds/ffmpeg-git-32bit-static.tar.xz

Extract it (xz is like the zip file format)

tar xvf ffmpeg-git-32bit-static.tar.xz

Execute the program (the ffmpeg-2.8-32bit-static is a directory name that was created when you extracted the xz file).

ffmpeg-2.8-32bit-static/ffmpeg -start_number 0 -i "lines_%02d.png" lines.mp4

You should be able to open the video lines.mp4 in a file broswer.

3. Problems

3.1. Animating a Point I

Write a for loop that does the equivalent of the following commands:

 plot(0,0,'.','MarkerSize',10)
 fname = sprintf('lines_%02d.png',0)
 print('-dpng',fname);

 plot(1,1,'.','MarkerSize',10)
 fname = sprintf('lines_%02d.png',1)
 print('-dpng',fname);

 plot(2,2,'.','MarkerSize',10)
 fname = sprintf('lines_%02d.png',2)
 print('-dpng',fname);

 ...

 plot(9,9,'.','MarkerSize',10)
 fname = sprintf('lines_%02d.png',9)
 print('-dpng',fname);

3.2. Animating a Point II

Modify the program that you wrote for the previous problem so that the size of the dot increases for each image.

Modify the program that you wrote in the previous problem so that the axis limits are always 0-10 in the x and 0-10 in the y.

3.3. Animating a Line I

Write a program that creates a sequence of images showing

  1. a line from (x,y) = (0,0) to (x,y) = (1,1)
  2. a line from (x,y) = (1,1) to (x,y) = (2,2)
  3. a line from (x,y) = (2,2) to (x,y) = (3,3)
  4. ...
  5. a line from (x,y) = (9,9) to (x,y) = (10,10)

Note that in each case, only a single line segment should be shown. (For example, in the second frame, there should only be a line between (1,1) and (2,2)).

3.4. Animating a Line II

  1. Modify the program in the previous problem so that it keeps the previously drawn lines.
  2. Modify the program so the lines drawn are from (and previously drawn lines are kept):
  • (x,y) = (0,0) to (x,y) = (1,1)
  • (x,y) = (1,1) to (x,y) = (4,4)
  • (x,y) = (4,4) to (x,y) = (9,9)
  • ...
  • (x,y) = (81,81) to (x,y) = (100,100)

3.5. Particle Trajectory

The mathematical representation of the position of ball launched at t=0 and an angle of 45 degrees is x(t) = 2t and y(t) = 2t - 4.9t2. According to this equation, at t = 0.4082 seconds, the ball will hit the ground.

Write a program that creates an array Xpos with elements that are the x-position of the ball at times of t = 0, 0.01, 0.02, ..., 0.41. Create an array Ypos that has the y-position of the ball at those times.

Use these arrays to create a sequence of images where the first image has a dot at the position of the ball at t = 0, the second image has a dot at the position of the ball at t = 0.05 t = 0.01, etc. Each frame should have only one dot on it and you should choose a size of 20 for the dot (using MarkerSize).

Save your program as Midterm_3.m. When I execute your code, I should see PNG images in my directory, one per time instant. Each PNG image should only have one dot, and the x- and y-axes should be labeled as "x position" and "y position", respectively.

Personal tools