Good morning,
I am currently developing my master thesis in MATLAB, developing an academic Multibody Systems algorithm. I am currently having some difficulties doing my debug and I was trying to code a 3D Animated Plot to try and understand what was my system behaviour.
This is my current code:
%% 3D Animation Plot
if strcmp(anigraph,'yes') == 1 || strcmp(anigraph,'YES') == 1 || strcmp(anigraph,'Yes') == 1
NPoint = Joints.NPoint; %Number of Points
origin = [0,0,0]; %Origin
%% Plot the Graphic
for f = 1:1667:c %Size of the Point StructStruct
%Plot First two Points of each iteration
strucPos = Points{1,f};
vecpos = strucPos(2).Position;
vecpos = vecpos';
%Initiate the 3D Plot
m = plot3([origin(1) vecpos(1)],[origin(2) vecpos(2)],[origin(3) vecpos(3)],'LineWidth',2);
hold on
axis auto
grid on
%Retrieve the Position Information and plot
for h = 2:NPoint
% Previous Point Pos Vector
prevecpos = strucPos(h-1).Position;
prevecpos = Impose_Column(prevecpos);
prevecpos = prevecpos';
% Foward Point Pos Vector
vecpos = strucPos(h).Position;
vecpos = Impose_Column(vecpos);
vecpos = vecpos';
%Plot These Points
plot3([prevecpos(1) vecpos(1)],[prevecpos(2) vecpos(2)],[prevecpos(3) vecpos(3)],'LineWidth',2),
hold on
pause(TimeStep);
end
end
hold off
end
I followed this code and video: Youtube
All my data for the plot is stored in a cell with multiple structs. Here is the example of one of these Structs, I desire to use only the data from the first column.
I have been trying to plot something like this for every iteration:
However, I am only being able to plot the first vector, can someone help me understand what I am missing on my code? My main difficulty is that the number of points change with the system that I try to simulate.
Thank you for all your help and attention.
Tiago
EDIT: Added a new code that is now able to plot the first iteration atleast.

 Accepted Answer

not sure witouth some example data, could you share for instance the struct holding the time history of the solution?
As a tip, I would only update the plot once at each time step. You can use plot3 to plot multiple vectors at once, just seperate them with nan's. I will add a small example below.
MyGrid = [ -0.5 0 0; 0.5 0 0; 0 0 0; 0 -2 0; -1.5 -1.5 0; 1.5 -1.5 0];
MyPoints = [1 2; 3 4; 1 5; 2 6]; % column 1 gives the start point of each vector, column 2 the stop point
figure
plot3( reshape([MyGrid(MyPoints(:,1),1)';MyGrid(MyPoints(:,2),1)';NaN(1,numel(MyPoints(:,1)))],1,[]),...
reshape([MyGrid(MyPoints(:,1),2)';MyGrid(MyPoints(:,2),2)';NaN(1,numel(MyPoints(:,1)))],1,[]),...
reshape([MyGrid(MyPoints(:,1),3)';MyGrid(MyPoints(:,2),3)';NaN(1,numel(MyPoints(:,1)))],1,[]),'r')
grid on
view([0 90])
% now plot the figure again and rotate it
figure
m = plot3( reshape([MyGrid(MyPoints(:,1),1)';MyGrid(MyPoints(:,2),1)';NaN(1,numel(MyPoints(:,1)))],1,[]),...
reshape([MyGrid(MyPoints(:,1),2)';MyGrid(MyPoints(:,2),2)';NaN(1,numel(MyPoints(:,1)))],1,[]),...
reshape([MyGrid(MyPoints(:,1),3)';MyGrid(MyPoints(:,2),3)';NaN(1,numel(MyPoints(:,1)))],1,[]),'r');
grid on
view([0 90])
% to update the figure, we can use "m" directly, say we want to rotate the
% grid by 30 degrees:
RotGrid = (rotz(30) * MyGrid')';
% note you can put this in a simple loop
m.XData = reshape([RotGrid(MyPoints(:,1),1)';RotGrid(MyPoints(:,2),1)';NaN(1,numel(MyPoints(:,1)))],1,[]);
m.YData = reshape([RotGrid(MyPoints(:,1),2)';RotGrid(MyPoints(:,2),2)';NaN(1,numel(MyPoints(:,1)))],1,[]);
m.ZData = reshape([RotGrid(MyPoints(:,1),3)';RotGrid(MyPoints(:,2),3)';NaN(1,numel(MyPoints(:,1)))],1,[]);

4 Comments

Tiago Carvalho
Tiago Carvalho on 28 Jun 2022
Edited: Tiago Carvalho on 28 Jun 2022
Hello, I never used the reshape function so I have to read more about it before I have any questions, but here it is the example struct for this specific case. Thank you for your time!
EDIT: I have read the answer I do not think that will solve my problem, since my issue is that I don't know how many points I will have for each animation since it depends on the system that I am simulating. If I knew them from the beginning then I think that your would be better suited than the one I tried.
2nd Edit: Also right now I was able to plot every iteration into the graphic but I wanted to be able to animate them instead of having all of them plotted.
based on the example data, i modified the code to a working example, see below.
note you will nee to run it locally, online it won't display the animation but only a single plot
load('examplestruct.mat')
anigraph = "yes";
Joints.NPoint = 6;
TimeStep = 2.5e-3;
%% 3D Animation Plot
if strcmp(anigraph,'yes')
NPoint = Joints.NPoint; %Number of Points
%% Initiate the 3D Plot
% first get the grid for the inital iteration
MyGrid = horzcat( Points{1,1}.Position );
% build the connectivity
MyPoints = [1:(Joints.NPoint-1); 2:Joints.NPoint];
figure
m = plot3( reshape([MyGrid(1,MyPoints(1,:));MyGrid(1,MyPoints(2,:));NaN(1,NPoint-1)],1,[]),...
reshape([MyGrid(2,MyPoints(1,:));MyGrid(2,MyPoints(2,:));NaN(1,NPoint-1)],1,[]),...
reshape([MyGrid(3,MyPoints(1,:));MyGrid(3,MyPoints(2,:));NaN(1,NPoint-1)],1,[]),'r');
axis auto
grid on
% set limits...
xlim([-1000 1000])
ylim([-500 1000])
zlim([-10 10])
%% plot the other timesteps
for f = 2:length(Points)
pause(TimeStep)
MyGrid = horzcat( Points{1,f}.Position );
m.XData = reshape([MyGrid(1,MyPoints(1,:));MyGrid(1,MyPoints(2,:));NaN(1,NPoint-1)],1,[]);
m.YData = reshape([MyGrid(2,MyPoints(1,:));MyGrid(2,MyPoints(2,:));NaN(1,NPoint-1)],1,[]);
m.ZData = reshape([MyGrid(3,MyPoints(1,:));MyGrid(3,MyPoints(2,:));NaN(1,NPoint-1)],1,[]);
end
end
Hello,
Thank you so much! This is exactly what I wanted, I will read the code more carefully to see how to adapt to my larger script!
Thank you again.
Tiago
Sorry to bother again, is there a way to save this animation into a gif file? Or to reset the animation without having to run the whole code again?

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!