Animating Vector Addition in Matlab (Looking for improvements)

  • #1
PhDeezNutz
796
553
TL;DR Summary
I eventually want to create a vector addition graphic in matlab. As in the literal "head to tail" idea.
Here is my code thus far and it seems to work (I've attached a gif as well so hopefully that works)
Matlab:
va1 = [50*cos(pi/3), 50*sin(pi/3)]; %Two different vectors both starting from the origin
vb1 = [20*cos(pi/6), 20*sin(pi/6)];

iterator = linspace(1,100,100); %100 iterations for the animation inside the for loop
vaiteratorx = linspace(0,50*cos(pi/3),100); % The ending x points for the first vector in successive animations
vaiteratory = linspace(0,50*sin(pi/3),100); % The ending y points for the first vector in successive animations

vbiteratorx = linspace(0,20*cos(pi/6),100); % The ending x points for the second vector in successive animations
vbiteratory = linspace(0,20*sin(pi/6),100);    % The ending y points for the second vector

for i = 1:length(iterator)
    clf
    
    if i <=50
        
        
        initial_point1 = [0,0];
        dp = [2*vaiteratorx(i) 2*vaiteratory(i)];
        q1 = quiver(0,0,2*vaiteratorx(i),2*vaiteratory(i),0,'color','m','linewidth',3,'MaxHeadSize',0.25);
        hold on
 
    else
      
        q1 = quiver(0,0,vaiteratorx(end),vaiteratory(end),0,'color','m','linewidth',3,'MaxHeadSize',0.25);
        hold on
        initial_point2 = [0,0];
        dp2 = [2*vbiteratorx(i-50) 2*vbiteratory(i-50)];
        q2 = quiver(0,0,dp2(1),dp2(2),0,'color','c','linewidth',3,'MaxHeadSize',50*0.25/20);
        hold on
          
            end
    
  
    xlim([0 200])
    ylim([0 ceil(9*200/16)]);
    set(gca,'color','k');
    set(gcf,'color','k');
    Ax = gca;
    Ax.XAxis.Visible = 'off';
    Ax.YAxis.Visible = 'off';
    Ax.XGrid = 'off';
    Ax.YGrid = 'off';
    Ax.Color = 'none';
    fig=gcf;
    fig.Units='normalized';
    fig.OuterPosition=[0 0 1 1];

    movieVector(i) = getframe(gcf)
end

myWriter = VideoWriter('SlideTwo','MPEG-4');
myWriter.FrameRate = 1;

open(myWriter)
writeVideo(myWriter,movieVector)
close(myWriter)

What I want to avoid doing is copying and pasting the last part of the last if block for each new else or elseif statement.

If I want to add to eventually add say 30 things to the animation then I will have to copy the last parts 30 times.How do I get around this?

Notice i had to replot "quiver1" for the "else" statement. I would hate to do this endlessly for successive parts.

Anyway I would appreciate any advice about how to approach this and here's the gif.
SlideTwo.gif


Wow that gif is slow.
 
Physics news on Phys.org
  • #2
I presume you mean something like this?

Plot vectors:
% Start with a clean slate
close all; clear all; clc;

% How many frames should be used to grow one vector
nFramesPerVector = 50;

% Just an example from quiver help to generate some vectors
% X = all x-coordinates of all vectors, likewise Y. U is
% length in X direction, likewise V.
[X,Y] = meshgrid(1:6,1:6);
U = 0.25*X;
V = 0.5*Y;

% Total amount of vectors
nvectors = numel(X);

% You need to generate the figure only once
fig = figure('Position', [0 0 1 1]);
fig.Units='normalized';
xlim([0 8])
ylim([0 9])
set(gca,'color','k');
set(gcf,'color','k');
Ax = gca;
Ax.XAxis.Visible = 'off';
Ax.YAxis.Visible = 'off';
Ax.XGrid = 'off';
Ax.YGrid = 'off';
Ax.Color = 'none';
hold on;

% A counter for the total amount of frames
iframe = 1;

% Loop over the vectors
for ivec = 1:nvectors

    % Loop over the frames to grow one vector
    for i = 1:nFramesPerVector

        % Scale factor for the vectors
        scaleFactor = i/nFramesPerVector;

        % Plot the vector
        q1 = quiver(X(ivec),Y(ivec), ...
            scaleFactor*U(ivec),scaleFactor*V(ivec),0,'color','m',...
            'linewidth',2,'MaxHeadSize',0.25);

        % Save frame
        movieVector(iframe) = getframe(gcf);

        % Delete vector unless it is the final, full-sized vector
        if i ~= nFramesPerVector
            delete(q1)
        end

        % Increase frame counter
        iframe = iframe + 1;
    end
end

myWriter = VideoWriter('SlideTwo');
myWriter.FrameRate = 24;

open(myWriter)
writeVideo(myWriter,movieVector)
close(myWriter)
 
  • Like
Likes PhDeezNutz
  • #3
I will try it as soon as I get home from thanksgiving dinner! Thank you very much for your response!
 
  • #4
It was a simple fix. The overall structure was a bunch of if, elseif, else statements nested in a for loop. The problem was that I wasn't retaining the plots to update as the script goes to the next if statement. This was because the plotting was inside the if statements and therefore limited to that scope.

The fix was updating the variables inside the if block and plotting it outside of the if block (before the end of the for loop) while invoking the command "hold on".

The script is as follows and it produces exactly what I want. @Arjan82 's ideas helped me realize that I needed to think about scope.

Fixed Vector Addition Animation:
va1 = [50*cos(pi/3), 50*sin(pi/3)]; %Two different vectors both starting from the origin
vb1 = [20*cos(pi/6), 20*sin(pi/6)];

iterator = linspace(1,150,150); %100 iterations for the animation inside the for loop
vaiteratorx = linspace(0,50*cos(pi/3),150); % The ending x points for the first vector in successive animations
vaiteratory = linspace(0,50*sin(pi/3),150); % The ending y points for the first vector in successive animations

vbiteratorx = linspace(0,20*cos(pi/6),150); % The ending x points for the second vector in successive animations
vbiteratory = linspace(0,20*sin(pi/6),150);    % The ending y points for the second vector

% vabiteratorx = linspace(0,-(20*cos(pi/6) - 50*cos(pi/3)),150);
% vabiteratory = linspace(0,-(20*sin(pi/6) - 50*cos(pi/3)),150);

dp = [0,0];
dp2 = [0,0];
dp3 = [0,0];

for i = 1:length(iterator)
    clf
 
 
    
    if i <=50
        dp = [3*vaiteratorx(i), 3*vaiteratory(i)];
    elseif i <= 100
        dp2 = [3*vbiteratorx(i-50) 3*vbiteratory(i-50)];
    else
        dp3  = [3*(vaiteratorx(i-100) - vbiteratorx(i-100)), 3*(vaiteratory(i-100) - vbiteratory(i-100))];
    end
    
    q1 = quiver(0,0,dp(1),dp(2),0,'color','m','linewidth',3,'MaxHeadSize',0.25);
    hold on
    
    q2 = quiver(0,0,dp2(1),dp2(2),0,'color','c','linewidth',3,'MaxHeadSize',50*0.25/20);
    hold on
    
    q3 = quiver(20*cos(pi/6),20*sin(pi/6),dp3(1),dp3(2),0,'color','c','linewidth',3,'MaxHeadSize',0.25);
    hold on
 
    xlim([0 200])
    ylim([0 ceil(9*200/16)]);
    set(gca,'color','k');
    set(gcf,'color','k');
    Ax = gca;
    Ax.XAxis.Visible = 'off';
    Ax.YAxis.Visible = 'off';
    Ax.XGrid = 'off';
    Ax.YGrid = 'off';
    Ax.Color = 'none';
    fig=gcf;
    fig.Units='normalized';
    fig.OuterPosition=[0 0 1 1];

    movieVector(i) = getframe(gcf)
end

myWriter = VideoWriter('SlideTwoTwo','MPEG-4');
myWriter.FrameRate = 1;

open(myWriter)
writeVideo(myWriter,movieVector)
close(myWriter)
 
  • #5
Well, you've asked how to do this when you have 30 vectors without all of the copy-pasting. Your solution still does a lot of unnecessary copy pasting and has lots of double code (try doing this for 30 vectors).

But if it works for you it's fine I guess :).
 

FAQ: Animating Vector Addition in Matlab (Looking for improvements)

How can I animate vector addition in MATLAB?

To animate vector addition in MATLAB, you can use the `plot` function to draw vectors and the `pause` function to create the animation effect. Start by plotting the initial vectors and then update the plot in a loop to show the addition process step-by-step. You can also use the `quiver` function for a more precise representation of vectors.

What functions are useful for animating vectors in MATLAB?

Useful functions for animating vectors in MATLAB include `plot`, `quiver`, `hold on`, `axis`, and `pause`. The `plot` and `quiver` functions are used to draw the vectors, `hold on` allows multiple plots on the same figure, `axis` sets the plotting limits, and `pause` introduces a delay between frames to create the animation effect.

How can I improve the visual quality of my vector animation?

To improve the visual quality of your vector animation, you can adjust the line width, color, and marker styles using properties like `LineWidth`, `Color`, and `Marker`. Additionally, using `axis equal` ensures that the scaling is uniform, and `grid on` can make the background clearer. Enhancing annotations with `text` and `legend` can also make the animation more informative.

How do I handle dynamic updates in the animation loop?

In the animation loop, you can handle dynamic updates by clearing the previous frame using `cla` (clear axes) before plotting the new vectors. This prevents old vectors from cluttering the animation. Alternatively, you can update the `XData` and `YData` properties of existing plot objects to change their positions without redrawing them entirely.

Can I save the vector addition animation as a video file?

Yes, you can save the vector addition animation as a video file using the `VideoWriter` class in MATLAB. Create a `VideoWriter` object, open it, and then write each frame of the animation to the file within the loop using the `writeVideo` function. Finally, close the `VideoWriter` object to complete the video file.

Similar threads

Replies
1
Views
4K
Replies
4
Views
4K
Back
Top