How can I avoid flickering animation of multiple balls using plot3?

Hello everyone,
its the first time I post into a forum and I will start directly with my problem description. Im trying to program a small simulation of particle collisions in 3D. Just a cubic space with multiple balls/spheres in it, which can collidate with boundaries and other particles. Like already mentioned I use plot3 because with this function I can simulate much more spheres without big lagging of the caluclations, compared with the function 'spheres(x,y,z)'. The disadvantage is that the balls are flickering like you can see in the mp4 video I attached.
The concept of my program is very common:
while
  1. Plot balls
  2. Pause of 0.001 seconds
  3. Calculate Next position with velocities and program runtime
  4. Delete balls
end
The function for plotting the balls in my program looks like this:
function [balls,particlesArray_partial]=PlotBall_hom(particlesArray_partial,balls,colors)
n=size(particlesArray_partial,2);
r=particlesArray_partial(7,1);
hold on
balls(1,:)=plot3(particlesArray_partial(1,:),particlesArray_partial(2,:),particlesArray_partial(3,:),...
'o','MarkerSize',r,'MarkerEdgeColor','k','MarkerFaceColor','bl');
hold off
end
Sorry if there is already a thread like this but I didnt found some.
Your sincerely

Answers (1)

Matthias - rather than deleting the balls (on each iteration), try re-using the graphics object handle to each ball:
close all;
hBallPlots = [];
hBallPlots(1) = plot3(NaN, NaN, NaN, 'o','MarkerSize',5,'MarkerEdgeColor','g','MarkerFaceColor','g');
hold on;
hBallPlots(2) = plot3(NaN, NaN, NaN, 'o','MarkerSize',5,'MarkerEdgeColor','r','MarkerFaceColor','r');
x = [-2*pi:0.01:2*pi; 2*pi:-0.01:-2*pi];
y = sin(x);
z = cos(x);
xlim([min(x(:)), max(x(:))]);
ylim([min(y(:)), max(y(:))]);
zlim([min(z(:)), max(z(:))]);
for k = 1:length(x)
for j = 1:length(hBallPlots)
set(hBallPlots(j),'XData',x(j,k), 'YData', y(j,k), 'ZData', z(j,k));
end
pause(0.001);
end
The only reason I have the inner for loop was because the balls were being coloured the same rather than red and green (in the above example which just might be a problem with my older version of MATLAB). If all balls are the same colour, then you could simplify with just
for k = 1:length(x)
set(hBallPlots,'XData',x(:,k), 'YData', y(:,k), 'ZData', z(:,k));
pause(0.001);
end

4 Comments

Thanks for your interesting suggestion. I have tried to adapt your code, so that I can animate a lot of spheres and calculate the coordinates with the speed formulas and runtime, but I did not succeed.
Then I accidentally noticed that I can influence the flickering by changing the pause time. I changed the pause time from 0.001 to 0.0095 s. This seems to be the best compromise between the framerate and the intensity of the flickering. This solution is not very elegant.
It would be interesting to understand how the functions you use work and how I adapt them to my code.
I've tried it like this:
function hBallPlots=Plotballs(particlesArray)
n=size(particlesArray,2); %%Number of particles
hBallPlots = zeros(1,n);
hBallPlots = plot3(NaN, NaN, NaN, 'o','MarkerSize',5,'MarkerEdgeColor','g','MarkerFaceColor','g');
hold on;
x = particlesArray(1,:);
y = particlesArray(1,:);
z = particlesArray(1,:);
xlim(0, 10);
ylim(0, 10);
zlim(0, 10);
set(hBallPlots(:),'XData',x(:,:), 'YData', y(:,:), 'ZData', z(:,:));
end
*I have attached a video of my new animation
** The low framerate comes from ms powerpoint I think. In Matlab it runs very smoothly
Regards
Matthias
Matthias - you'll need to pass the hBallPlots back into the function else you will be creating new graphics objects each time you call PlotBalls (which presumably you call periodically). You could try something like
function hBallPlots=Plotballs(particlesArray, hBallPlots)
n=size(particlesArray,2); %%Number of particles
if isempty(hBallPlots)
hBallPlots = zeros(n,1);
for k = 1:n
hBallPlots(k) = plot3(NaN, NaN, NaN, 'o','MarkerSize',5,'MarkerEdgeColor','g','MarkerFaceColor','g');
hold on;
end
end
x = particlesArray(1,:);
y = particlesArray(1,:);
z = particlesArray(1,:);
xlim(0, 10);
ylim(0, 10);
zlim(0, 10);
set(hBallPlots,'XData',x, 'YData', y, 'ZData', z);
end
So the first time you call PlotBalls, the hBallPlots will be an empty array and so we'll create a handle for each of the n particles (note that this assumes that you will always have n particles; if this isn't true, then the code will need to be updated to ensure that the number of graphics objects matches the number of particles). Assuming that hBallPlots, x, y, and z are all nx1 columns, then we just change the x, y, and z data for each to be the new position.
Ok, I understand this set function now and the flickering is gone but now the animation is lagging. I think the for-loop slows the program performance down. I've tried something like this but than the flickering comes back:
function balls=Plotballs(particlesArray, balls)
n=size(particlesArray,2); %%Number of particles
grid on;
balls(:) = plot3(NaN, NaN, NaN, 'o','MarkerSize',particlesArray(7,1),'MarkerEdgeColor','k','MarkerFaceColor','g');
hold on;
x = particlesArray(1,:);
y = particlesArray(2,:);
z = particlesArray(3,:);
xlim([0 10]);
ylim([0 10]);
zlim([0 10]);
set(balls(:),'XData',x(:), 'YData', y(:), 'ZData', z(:));
end
Thanks for your help so far. Im doing this for an university project so it would be great to get this working., otherwise I could cheat with changing the pause-time
*I have predefined hBallsPlots (In my script 'balls') in my main file with balls=zeros(1,n);
**Its true that I always have the same number of particles
The for loop shouldn't be causing a lag since it is only ever called once if the hBallPlots is empty
if isempty(hBallPlots)
hBallPlots = zeros(n,1);
for k = 1:n
hBallPlots(k) = plot3(NaN, NaN, NaN, 'o','MarkerSize',5,'MarkerEdgeColor','g','MarkerFaceColor','g');
hold on;
end
end
. If it is always being called whenever your code calls Plotballs then an incorrect hBallPlots is being passed in and it should be defined as an empty array in your main script
balls = [];
so perhaps that was the problem. Please try initializing it to an empty array, put the for loop code back in, and maybe that will improve performance (fingers crossed!).

Sign in to comment.

Categories

Products

Release

R2017b

Asked:

on 7 Apr 2020

Commented:

on 8 Apr 2020

Community Treasure Hunt

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

Start Hunting!