Animating a circle inside a rectangle

The goal is to create an animation that represents an animated (separate successive images separated by a time 'dt') particle (28*R pt, 'R' is the radius, and the position of its center is r=[x;y]) during a time interval 'deltat' within a rectangle (width=a and height=b), with a certain velocity v=[vx;vy]. This particle collides with the 'walls' of the rectangle and conserves its kinetic energy. The collision with the wall x=0 happens in a deltat=(R-r(1))/v(1), and the collision with the wall x=a happens in a deltat=(a-R-r(1))/v(1).
I tried to represent this, but there's always something wrong with the code.
[MY CODE]
/////////////////////////////////////////
a=20
b=10
R=0.5
v=[10;10]
r=[10;5]
vx=v(1)
vy=v(2)
x0=r(1)
y0=r(2)
dt=0.1
deltat=5
X=zeros(1,500)
%x to the right
xright=((a-R-x))/vx
x0 = a/2;
y = b/2;
for i=2:1:deltat
%rectangle
plot([0,a],[0,0],'r-',[a,a],[0,b],'r-',[0,0],[0,b],'r-',[0,a],[b,b],'r-')
hold on
%circle
X(i) = x(i-1) + vx*dt
plot(X, y,'ro','MarkerSize',28*R);
axis ([-10,30,-10,20])
hold off
pause(0.05)
end
/////////////////////////////////////////
My logic was to literally trace the circle's movement (first from the center to the right wall, then to the center again towards the left wall (...) ). Nonetheless, the code does not work.
Thank you.

 采纳的回答

Mistake:
Mistake
Also you shoud have conditions when ball collides:
if (x<0)||(a<x)
vx = -vx; % change sign
end
the same for vy
Add line (similar to yours)
Y(i) = Y(i-1) + vy*dt;
You can also add gravity
vy = vy - 9.8*dt;

14 个评论

You don't have to draw the box each loop
Thank you so much for your help.
Though, I tried what you said, but there are 3 questions that popped up:
  1. Whenever I change the velocity, the less positions the circle has... Shouldn't velocity not have any effect on that?
  2. The circle shows 'dragging' (not only 1 circle appears). Could that be a result of the 'hold on' // 'hold off'? Also, there is a circle on (0,0), I can't find the reason why...
  3. While running the code, the circle stops after getting to x=14 , y=9 , and it doesn't return - shouldn't the sign change on the equation?
Thank you once more. Here's how the code is currently:
a=20
b=10
R=0.5
v=[10;10]
r=[10;5]
vx=v(1)
vy=v(2)
x=r(1)
y=r(2)
dt=0.1
deltat=5
X=[x zeros(1,deltat)]
Y=[y zeros(1,deltat)]
%x to the right
xdireita=((a-R-x))/vx
%rectangle
plot([0,a],[0,0],'r-',[a,a],[0,b],'r-',[0,0],[0,b],'r-',[0,a],[b,b],'r-')
hold on
for i=2:1:deltat
X(i) = X(i-1) + vx*dt
Y(i) = Y(i-1) + vy*dt
if (X(i)<0)||(a<(X(i))
vx = -vx;
end
if (Y(i)<0)||(b<Y(i))
vy = -vy;
end
plot(X, Y,'ro','MarkerSize',28*R);
axis ([-10,30,-10,20])
pause(0.05)
end
hold off
Here are some tips
  • Tip 1: make you trajectory longer
  • TIp 2: remove dragging effect - draw circle, wait, delete
Also i have some warnings:
Do you know what do they mean?
There is just a little detail that I'm missing... it's the fact that the particle goes past the rectangle (it only changes position when the center of the circle hits the x=a (...) ).
Even if I write
if ((X(i)-R)<0)||(a<(X(i)-R))
vx = -vx;
end
It doesn't change anything. What could be reason for that?
I believe the warnings are due to the semicolons I am not used to put... That's something I have to change in the future.
When ball bounces the wall you need to move X(i) a bit
Sometimes next position stil outside the box. Any ideas?
My first idea would be to subtract the radius to the X(i) or Y(i) in the condition, because technically the ball has to change the sign of vx or vy whenever it has reached the X-R position, right? But it doesn't seem to work...
Maybe a command to eliminate all the values that are <0 or >a?
When the ball bounces (outside box) next position should be corrected
something like
X(i) = X(i) - dx;
Thank you so much for the help. It finnally worked!
Here is the final code:
clear all
close all
clc
a=20;
b=10;
R=0.5;
v=[10;10];
r=[10;5];
vx=v(1);
vy=v(2);
x=r(1);
y=r(2);
dt=0.1;
deltat=1000;
X=[x zeros(1,deltat)];
Y=[y zeros(1,deltat)];
plot([0,a],[0,0],'r-',[a,a],[0,b],'r-',[0,0],[0,b],'r-',[0,a],[b,b],'r-')
hold on
for i=2:1:deltat
X(i) = X(i-1) + vx*dt;
Y(i) = Y(i-1) + vy*dt;
if (X(i)-R<=0)||(a<=X(i)+R)
vx = -vx;
end
if (Y(i)-R<=0)||(b<=Y(i)+R)
vy = -vy;
end
if (X(i)>a) || (Y(i)>b)
X(i+1)= X(i)-X(i-1);
Y(i+1)= Y(i)-Y(i-1)
end
particle = plot(X(i), Y(i),'ro','MarkerSize',28*R);
axis ([-10,30,-10,20])
pause(0.05)
delete(particle)
end
hold off
You created conditions for right and top boundaries. What about left one?
Good point. Corrected it already. Thank you so much!
Hello again!
Is there any way I can get the array X and the array Y not depend on 'deltat' and still make the animation work?
function animacao(r,v,a,b,R,deltat,dt)
vx=v(1);
vy=v(2);
x=r(1);
y=r(2);
plot([0,a],[0,0],'r-',[a,a],[0,b],'r-',[0,0],[0,b],'r-',[0,a],[b,b],'r-')
hold on
X=[x zeros(1,deltat)]; %here
Y=[y zeros(1,deltat)];
for i=2:dt:deltat
X(i) = X(i-1) + vx*dt;
Y(i) = Y(i-1) + vy*dt;
if (X(i)-R<=0)||(a<=X(i)+R)
vx = -vx;
end
if (Y(i)-R<=0)||(b<=Y(i)+R)
vy = -vy;
end
if (X(i)>a) || (Y(i)>b) || (X(i)<0) || (Y(i)<0)
X(i+1)= X(i)-X(i-1)
Y(i+1)= Y(i)-Y(i-1)
end
particula = plot(X(i), Y(i),'go','MarkerSize',28*R,'MarkerFaceColor','g');
axis ([-10,a+10,-10,b+10])
pause(0.05)
delete(particula)
end
hold off
Why can't you declare deltat inside function?
Basically, some steps ahead in the main script the deltat (the time a particle takes to collide with a wall, or with another particle) is calculated for each cycle the code does, and the animation will draw the movement for that deltat. The problem is that sometimes deltat isn't an integer number (it's decimal), and therefore the instruction zeros gives an error.

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Animation 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by