MATLAB Examples

アニメーションの作成

このチュートリアルでは、MATLABでアニメーションを作成する方法を学びます。 MATLABグラフのアニメーションを作成し、AVI形式のムービーやGIF形式のアニメーションを 作成します。 $x^2+e^{\pi i}$

R2014b 以降のバージョンのみで動作します。

Contents

ループを使用したアニメーション

for ループ(あるいは while ループ)を 用いることで、簡単にアニメーションを作成することができます。 各ループでそのタイムステップのグラフにアップデートします。

3D アニメーション 例:

m = 1;         % 質量
L = 1;         % リンクの長さ
theta1 = 3*pi/4; % theta 1 の初期角度(ラジアン)
theta2 = 3*pi/8; % theta 2 の初期角度(ラジアン)
t = linspace(0, 10, 300);  % 10秒300点でシミュレーション

% 二重振り子のODEを解く
[T,Y] = ode45(@(t, x) double_pendulum(t, x, m, L), ...
   t, [theta1, theta2, 0, 0]);

% アニメーション処理のために関節座標を計算
x = [ L*sin(Y(:,1)),  L*sin(Y(:,1))+L*sin(Y(:,2))];
y = [-L*cos(Y(:,1)), -L*cos(Y(:,1))-L*cos(Y(:,2))];

% ラジアンを角度に変換
ang = Y(:,1:2)*180/pi;

figure;
subplot(2,1,1);
xlabel('time (sec)'); ylabel('angle (\circ)');

tic;    % タイミングの開始
for id = 1:length(T)
   % 上部のプロットではリンク角の時系列を描画
   subplot(2,1,1);
   plot(T, ang, 'LineWidth', 2);
   line(T(id), ang(id,1), 'Marker', '.', 'MarkerSize', 20, 'Color', 'b');
   line(T(id), ang(id,2), 'Marker', '.', 'MarkerSize', 20, 'Color', [0 .5 0]);
   xlabel('time (sec)'); ylabel('angle (deg)');

   % 下部のプロットでは二重振り子のアニメーションを描画
   subplot(2,1,2);
   plot([0, x(id,1);x(id,1), x(id,2)], [0, y(id,1);y(id,1), y(id,2)], ...
      '.-', 'MarkerSize', 20, 'LineWidth', 2);
   axis equal; axis([-2*L 2*L -2*L 2*L]);
   title(sprintf('Time: %0.2f sec', T(id)));

   drawnow;
end
fprintf('Animation (Regular): %0.2f sec\n', toc);
Animation (Regular): 12.59 sec

ループを使用したアニメーション (Smart updating)

上記のような方法でアニメーションを作成することも可能ですが、 メモリと速さを考えた場合にもっと良い方法があります。

MATLAB のコマンドの中にはコマンド名以上の機能をもつ関数もあります。 例えば、 plot 関数を実行すると、Figureに描いていた 軸を消去、現在のグラフィックオブジェクトを除去、プロパティをリセットした上で 新しいグラフィックオブジェクトを作成します。 この動作をループごとにすることで、プロセスの速度が遅くなります。 特に大きいデータの場合にこの影響がでやすくなります。

この問題を避ける方法として、まずはメインのプロットを描画し、 ループを通して各データを変更します。これを実行するには、 はじめに描いたプロットのハンドルを保存しておき、そのハンドルを XDataYData を変更するために使用します。

figure;
subplot(2,1,1);
plot(T, ang, 'LineWidth', 2);
hh1(1) = line(T(1), ang(1,1), 'Marker', '.', 'MarkerSize', 20, 'Color', 'b');
hh1(2) = line(T(1), ang(1,2), 'Marker', '.', 'MarkerSize', 20, 'Color', [0 .5 0]);
xlabel('time (sec)'); ylabel('angle (deg)');

subplot(2,1,2);
hh2 = plot([0, x(1,1);x(1,1), x(1,2)], [0, y(1,1);y(1,1), y(1,2)], ...
      '.-', 'MarkerSize', 20, 'LineWidth', 2);
axis equal
axis([-2*L 2*L -2*L 2*L]);
ht = title(sprintf('Time: %0.2f sec', T(1)));

tic;     % タイミングの開始
for id = 1:length(T)
   % XData と YData のアップデート
   hh1(1).XData = T(id);
   hh1(1).YData = ang(id, 1);
   hh1(2).XData = T(id);
   hh1(2).YData = ang(id, 2);
   hh2(1).XData = [0, x(id, 1)];
   hh2(1).YData = [0, y(id, 1)];
   hh2(2).XData = x(id, :);
   hh2(2).YData = y(id, :);
   ht.String = sprintf('Time: %0.2f sec', T(id));

   drawnow;
end
fprintf('Animation (Smart update): %0.2f sec\n', toc);
Animation (Smart update): 4.89 sec

ムービー (AVI) の作成

MATLAB上で動作するアニメーションが作成できたら、 VideoWriter (R2010b-)、 avifile あるいは movie2avi を使用してムービー(AVI)を作成することができます。

% ビデオオブジェクトの作成
writerObj = VideoWriter('animation.avi');
open(writerObj);

% アニメーションフレームをビデオファイルに追加
for id = 1:length(T)
   % XData と YData のアップデート
   hh1(1).XData = T(id);
   hh1(1).YData = ang(id, 1);
   hh1(2).XData = T(id);
   hh1(2).YData = ang(id, 2);
   hh2(1).XData = [0, x(id, 1)];
   hh2(1).YData = [0, y(id, 1)];
   hh2(2).XData = x(id, :);
   hh2(2).YData = y(id, :);
   ht.String = sprintf('Time: %0.2f sec', T(id));

   % フレームを画像として取得
   frame = getframe(gcf);

   % フレームをビデオに追加
   writeVideo(writerObj, frame);
end

% ビデオファイルを閉じる
close(writerObj)
警告: このファイルにはビデオ
フレームが書き込まれていません。ファイルが無効になる可能性があります。