Live Script animation 2025a
조회 수: 25 (최근 30일)
이전 댓글 표시
The folowing code produces a nice on-time animation when run from the command line. Run as a Live Script, it produces an animation with a scroll bar and an export to movie button but the animation appears broken, having just a few frames and so does the mp4 if one exports it. How can I get this and similar codes to work in Live Scripts?
%% SIMPLE_PENDULUM_ANIM.m
% Standalone, command-line animation of a simple pendulum
% Emulates the same frame-stepped loop pattern as your working animation:
% - Construct t_anim = 0:dt:tf
% - Pre-create graphics objects
% - In a for-loop: compute state -> set(XData/YData) -> drawnow -> pause(dt)
% Includes diagnostics to confirm that many distinct frames are produced.
%% Housekeeping
clearvars;
close all hidden;
clc;
%% Parameters
% Pendulum physical parameters
L = 1.0; % length in meters
g = 9.81; % gravity in m/s^2
% Display amplitude and motion
amp_deg = 10; % small angle amplitude in degrees
A = deg2rad(amp_deg); % radians
theta0 = A; % initial angle amplitude
phi = 0; % phase shift
% Timing
frame_rate = 30; % frames per second
dt = 1/frame_rate; % step between frames
T = 2*pi*sqrt(L/g); % period of small oscillations
nPeriods = 4; % number of periods to show
t_final = nPeriods * T; % total animation time
t_anim = 0:dt:t_final; % time vector for animation
Nframes = numel(t_anim); % number of frames
% Print timing diagnostics
fprintf('Simple pendulum small-angle animation\n');
fprintf(' L = %.3f m, g = %.3f m/s^2\n', L, g);
fprintf(' Small-angle period T = %.4f s\n', T);
fprintf(' frame_rate = %d fps, dt = %.6f s\n', frame_rate, dt);
fprintf(' nPeriods = %d, t_final = %.4f s, Nframes = %d\n', nPeriods, t_final, Nframes);
%% Prescribed motion (small-angle)
% theta(t) = A * cos(omega * t + phi)
omega = sqrt(g/L); % small-angle angular frequency
theta_anim = theta0 * cos(omega * t_anim + phi);
% Position of bob
x_anim = L * sin(theta_anim);
y_anim = -L * cos(theta_anim);
% Diagnostics: max per-step changes and distinct-frame count
dx = [0, diff(x_anim)];
dy = [0, diff(y_anim)];
dmax = max(abs([dx(:), dy(:)]), [], 2).';
tol_distinct = 1e-9; % anything larger than this counts as a new frame
nDistinct = 1 + sum(dmax(2:end) > tol_distinct);
fprintf(' Max |Δx| per step = %.6g, Max |Δy| per step = %.6g\n', max(abs(dx)), max(abs(dy)));
fprintf(' Distinct frames (|Δ| > %.1e): %d / %d\n', tol_distinct, nDistinct, Nframes);
%% Figure and axes
fig = figure('Position',[100,100,600,600],'Name','Simple Pendulum Animation');
axis equal;
grid on;
hold on;
% Axis limits with padding
pad = 0.2;
xlim([-L - pad, L + pad]);
ylim([-L - pad, pad]);
xlabel('X (m)');
ylabel('Y (m)');
title(sprintf('Simple Pendulum — A = %.1f°; %.0f fps; %d periods', amp_deg, frame_rate, nPeriods));
%% Graphics objects (pre-create; update via set)
% Pivot
pivot_plot = plot(0, 0, 'ko', 'MarkerSize', 6, 'MarkerFaceColor', 'k');
% Rod as a line from pivot to bob
rod_plot = plot([0, x_anim(1)], [0, y_anim(1)], 'k-', 'LineWidth', 3);
% Bob as a filled circle
bob_size = 14; % marker size
bob_plot = plot(x_anim(1), y_anim(1), 'ro', 'MarkerSize', bob_size, 'MarkerFaceColor', 'r', 'LineWidth', 1.5);
% Optional trail to visualize motion
trail_len = max(1, round(0.5*frame_rate)); % 0.5 s trail
trail_plot = plot(nan, nan, '-', 'Color', [0.2 0.6 1.0], 'LineWidth', 1);
% Time text
time_text = text(-L - 0.15, 0.05, sprintf('t = %.3f s', 0), 'FontSize', 12);
drawnow;
%% Animation loop
fprintf('Animating...\n');
for k = 1:Nframes
% Current tip coordinates
xk = x_anim(k);
yk = y_anim(k);
% Update rod
set(rod_plot, 'XData', [0, xk], 'YData', [0, yk]);
% Update bob
set(bob_plot, 'XData', xk, 'YData', yk);
% Update trail
i0 = max(1, k - trail_len + 1);
set(trail_plot, 'XData', x_anim(i0:k), 'YData', y_anim(i0:k));
% Update time text
set(time_text, 'String', sprintf('t = %.3f s', t_anim(k)));
% Draw and pace
drawnow;
if k < Nframes
pause(dt);
end
% Optional per-frame diagnostic printing (sparse)
if mod(k, round(frame_rate)) == 0 || k == 1 || k == Nframes
fprintf(' Frame %4d / %4d: (x,y) = (%.5f, %.5f), |Δ|_max = %.3g\n', ...
k, Nframes, xk, yk, dmax(k));
end
end
fprintf('Done.\n');
댓글 수: 0
답변 (1개)
Tridib
2025년 11월 3일 6:30
The code actually works fine for me both in the Command Window and in Live Scripts.
However, from what I understand, the problem in Live Scripts seems to be that for-loops with "drawnow" or "pause" do not run in real time. Instead, the Live Editor only takes a few snapshots during the loop, so just a handful of frames are displayed. As a result, when using the "Export to Video" button in Live Scripts, the exported video contains only those few captured frames, making the animation appear choppy or incomplete.
A possible workaround could be to try capturing each frame manually using "getframe" within the loop and then saving them to a video file with "VideoWriter". For smoother playback in Live Scripts, it might help to store all frames first and then play them back using tools like "implay" or by adding a slider to move through the animation.
For more information, refer to these documentations:
Hope this helps!
참고 항목
카테고리
Help Center 및 File Exchange에서 Animation에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!