Search code examples
matlabplotdraw

How do I animate a single propagating pulse without showing its entire range and only the pulse itself as its x-axis changes dynamically?


The code found here implements a MATLAB script that solves and draws the 1D wave equation with boundaries at x=0 and x=90. When you run the script in MATLAB it shows a single pulse propagate from x=0 to x=90 and bounce back and forth.

This script shows the entire range of x (i.e. from x=0 to 90) even though the pulse itself is only about 20 units long in the x-direction. See image below:

enter image description here

My question: How do I construct an imaginary green box shown in the image above that only shows the pulse as it moves along instead of the entire range? The imaginary green box moves with the pulse. So when you play the movie, all you see is the pulse and the changing x-axis limits (like x=0 to 20, then x=20 to 40, then x=40 to 60, and so forth).

I think the answer to this question has something to do with the camera position or view, but I am not sure how.

Here is the code:

% 1D wave equation using boundary condition
% Mohammad Ismail Hossain
% Jacobs University Bremen
clc
clear all
c = 1;
l = 4.5;
dt = 0.06;
dx = 0.05;
ldx = 4.5/dx;
x = 1:ldx;
tm = 300;
N = 0.4/dt;
n = 1:8*N;
n0 = 4*N;
En = zeros(tm,ldx);
En0 = zeros(tm,1);
En0(1:8*N) = exp(((-(n-n0).^2)/(2*N^2)));
Ent(1:tm) = 0;
En(1,1) = En0(1);
for p = 2:tm-1
   En(p,1) = En0(p);
   for q = 2:ldx-1
       
       if (q == (ldx/9)*4)||(q == (ldx/9)*5)
           c = sqrt(0.4);
       end
       if ((q > (ldx/9)*4) && (q < (ldx/9)*5))
           c = 0.5;
       end
       if ((q < (ldx/9)*4) || (q > (ldx/9)*5))
           C = 1;
       end
       En(p+1,q) = ((c*dx)/dt)^2*(En(p,q+1)-2*En(p,q)+En(p,q-1)) + 2*En(p,q) - En(p-1,q); 
   end
   plot(En(p,:))
   title(['Time = ',num2str(p+1)]);
   YLIM([-1.5 1.5])
   pause(0.03);
   
end

Solution

  • You only need to change xlim dynamically. Ideally it should be synchronized with the speed and direction of the wave, but it's hard to tell what the code is doing (no comments, not very informative variable names).

    A more "automatic" approach is to find the position of the absolute maximum of the wave and define xlim around that position. To do this, just add the following lines at the end of the outer loop. Also change YLIM to ylim to avoid an error:

    ···
    title(['Time = ',num2str(p+1)]);
    ylim([-1.5 1.5])                    % changed line
    [~, xm] = max(abs(En(p,:)));        % new line: find position of maximum
    xlim(xm + [-20 20])                 % new line: set xlim around that value
    pause(0.03);
    ···