MATLAB: Index exceeds the number of array elements (1).

for loopMATLAB

I want to create a movie with a for loop, but Index exceeds the number of array elements (1) is shown. Someone can tell me were is the error? The for loop without the condition works fine, but where i assign a condition, the error message appears. 🙁 I just want that when y <= 0, the angle theta0 and v0 change to theta0 = atan(y(j-2)/(x(j)-x(j-2))) and v0 = 0.8v0.
clear, clc
g=9.81; theta0=45*pi/180; v0=5;
t(1)=0;x=0;y=0;
plot(x,y,'o','MarkerFaceColor','b','MarkerSize',8)
axis([0 8 0 0.8])
M(1)=getframe;
dt=1/128;
for j = 2:1000
t(j)=t(j-1)+dt;
x=v0*cos(theta0)*t(j);
y=v0*sin(theta0)*t(j)-0.5*g*t(j)^2;
plot(x,y,'o','MarkerFaceColor','b','MarkerSize',8);
axis([0 8 0 0.8]);
M(j)=getframe;
if y<=0
theta0 = atan(y(j-2)/(x(j)-x(j-2)));
v0 = 0.8*v0;
plot(x(j),0,'o','MarkerFaceColor','b','MarkerSize',8)
M(j) = getframe;
end
end
pause
movie(M,1)

Best Answer

Right, I see what you're trying to do but the point stands that your modified code doesn't save the different values of y as time increases, it only stores the current value, so going into y(j-2) finds nothing unless j=3. Keeping them as follows would address that:
x(j) = v0*cos(theta0)*(t(j)-t_last)+x0;
y(j) = v0*sin(theta0)*(t(j)-t_last) - 0.5*g*(t(j)-t_last)^2;
I would also say the use of while in this example is well suited to the conditions set, but if you want to replace them with for, that's also possible. As you've done, if you don't require watetight conditioning (i.e. just to run a couple of examples) you can set a high number of for loops (i.e. 1000/2000/etc), but then it's also wise to have a condition that checks if it's not needed to keep on looping and exit (i.e. when the ball no longer bounches).
g = 9.81;
theta0 = 50*pi/180;
v0 = 5;
t(1) = 0;
x = 0;
y = 0;
plot(x,y,'o','MarkerFaceColor','b','MarkerSize',8)
axis([0 3 0 0.8])
M(1) = getframe;
dt = 1/128;
x0=0;
t_last = 0;
h_max = -1;
for j=2:2000
t(j) = t(j - 1) + dt;
x(j) = v0*cos(theta0)*(t(j)-t_last)+x0;
y(j) = v0*sin(theta0)*(t(j)-t_last) - 0.5*g*(t(j)-t_last)^2;
if y(j)>h_max
h_max = y(j);
end
if y(j)<= 0
theta0 = atan(y(j-2)/(x(j)-x(j-2)));
flag = 1;
v0 = 0.8*v0;
x0 = x(j);
t_last = t(j-1);
plot(x(j),0,'o','MarkerFaceColor','b','MarkerSize',8)
axis([0 8 0 0.8])
M(j) = getframe;
else
plot(x(j),y(j),'o','MarkerFaceColor','b','MarkerSize',8)
axis([0 8 0 0.8])
M(j) = getframe;
end
if x(j)==x(j-1)
break
end
end
movie(M,1)
This is one way you can do it all with one for loop. The condition:
if x(j)==x(j-1)
break
end
checks if the object is no longer moving in the x direction and exits the loop if that's the case. So for the default parameters that's 332 steps. If you double the gravitational acceleration, it only needs 170 steps and exits on its own (no point looping for the remaining 1830.)
Related Question