0
votes

I've been tasked with animating a 3d helical flux tube in Matlab and I'm unsure of how to do so.

The only animation experience I've had was for plotting the 2d trajectories of 9 solar system planetary orbits, for which I used the following code (where z was a 27 column matrix whose columns were ordered in the sequence x,y,z 9 times as to represent 9 planets)

% Plot 9 empty plots
p = plot3(nan(9), nan(9), nan(9));

for k = 1:size(z, 1)
    % Update all of the plot objects at once
    set(p, {'XData'}, num2cell(z(1:k, 1:3:25), 1).', ...
           {'YData'}, num2cell(z(1:k, 2:3:26), 1).', ...
           {'ZData'}, num2cell(z(1:k, 3:3:27), 1).')
    drawnow
end

So, intuitively, I have tried to adapt this for the helical flux tube that I have as follows (where x, y and z are 21 x 301 matrices and so I assume that at each time step I must surf the rows of x,y and z accordingly up to the required time step):

p = surf(nan(21,301), nan(21,301), nan(21,301));

for k = 1:size(x,1)
    % Update all of the plot objects at once
    set(p, {'XData'}, num2cell(x(1:k, :), [1 301]), ...
           {'YData'}, num2cell(y(1:k, :), [1 301]), ...
           {'ZData'}, num2cell(z(1:k, :), [1 301]))
    drawnow
end

However, doing this i keep getting the error

Error using matlab.graphics.chart.primitive.Surface/set
Size mismatch in Param Cell / Value Cell pair.

I know I've probably made a silly mistake somewhere, but can anyone help? Or if I'm completely going about this the wrong way could anybody let me know?!

(NB If it helps, in the original script to plot the helical flux tube, the code is:)

surf(x,y,z,'facecolor', Colour, 'edgecolor',EdgeColour,...
    'facelighting','gouraud')

Thanks!!

3

3 Answers

0
votes

I am not 100% sure I get what you want but you could try:

for k = 1:size(x,1)
    surf(num2cell(x(1:k, :) ,num2cell(y(1:k, :), num2cell(z(1:k, :);
    M(i)=getframe;
end

And the display the it as a movie afterwards by:

numberofrepitions=3 % as often as you want to have it play in a row
movie(M,numberofrepetitions)

Maybe easier displayed on some random data as you didnt provide any:

x=[1 2 3; 2 3 4; 3 4 5];
y=[19 17 15; 13 11 9; 7 5 3];
z=[1 1 2; 2 1 1; 3 3 3];

for i=1:10
    surf(x,y,z);

    M(i)=getframe;
    x=x+10;
    y=y+20;
    z=z+25;
end 
movie(M,3)

The form of the created plot doesnt change but you can see the axis moving, so I guess it would work that way also for a varying form of your surface triangulation.

0
votes

You are getting that error because the following command only creates one surf object

p = surf(nan(21,301), nan(21,301), nan(21,301));

numel(p)
%   1

If that's what you want, then you don't want to use the '{XData}' notation but just the plain 'XData', etc.

However, if you do want to create multiple surf objects, you will want to do it within a loop. Then you should be able update them the way that you'd like.

0
votes

This code obtained the desired animation

p = surf(nan(21,301), nan(21,301), nan(21,301));

 for k = 1:301
     % Update all of the plot objects at once
     set(p, 'XData', x(:, 1:k), ...
            'YData', y(:, 1:k), ...
            'ZData', z(:, 1:k))

        drawnow
 end

So from the initial circle at the base point, the animation then shows the tube that forms as this initial circle rises (and twists) through time.

We no longer need the {} around the 'XData' etc since we are only needing the surf of one object, rather than the 9 before.

Thank you for all the help getting to this answer!