What is wrong with my for loop
2 views (last 30 days)
Show older comments
Hello all,
so im trying to plot a projectile and this is a condition where the projectile hits a wall and then stops in that place
this is the code that i have currently:
if Ox == 0 && Oy == 0
xlim([0, max(x)+0.5])
ylim([0, max(y)+0.5])%if the obstacle condition is not on (values are 0) then this condition runs
axis('equal')
hold('on')
grid on %ensures following commands are added to the same plot
plot([0 max(x)],0)
comet(x,y,0.1) %plots the projectile as a comet
plot(x(y==max(y)),y(y==max(y)),'ro') %displays the point of max height
text(x(y==max(y)),y(y==max(y)),'\leftarrow MAX HEIGHT') %pointer to the max height
else %if the values for the obstacle are not 0 then this condition will run
rectangle('Position',[Ox 0 Ot Oy],'FaceColor',[0.6353 0.0784 0.1843]) %obstacle plot
hold on %ensures following commands are added to the same plot
axis equal
grid on
disp('im here')
if max(x)>=Ox
to = Ox/v0x %time until reaches obstacle
disp('im working btw')
xlim([0, Ox+Ot+0.5])
ylim([0, max(y)+0.5])
hold on
for i=0:length(to)
plot(x(i+1),y(i+1),'ko')
pause(0.1)
disp('here now')
end
%else
%comet(x,y,0.1) %plots the projectile as a comet animation
%plot(x(y==max(y)),y(y==max(y)),'ro') %displays the point of max height
%text(x(y==max(y)),y(y==max(y)),'\leftarrow MAX HEIGHT') %pointer to the max height
end
end
this is what the graph looks like for values v0=10 theta0=35 y0=2 Ox=7 Oy=5 Ot=0.5
why do i only have 2 points plotted? how can i get the full projectile?
4 Comments
Accepted Answer
Walter Roberson
on 6 Jan 2021
Edited: Walter Roberson
on 6 Jan 2021
v0 = input('v0: ');
theta0 = input('theta: ');
We do not know the size of value the user is entering. You are not doing any testing to verify that a scalar was entered, so we must assume that v0 and theta0 can be vectors or arrays until proven otherwise.
v0x = v0*cosd(theta0); % x comp of initial speed
If the user entered scalar v0 then v0x will be the same size as theta0. If the user entered non-scalar v0 but scalar theta0 then v0x will be the same size as v0 . If the user entered non-scalar v0 and non-scalar theta0 then if the number of columns of v0 happens to match the number of rows of theta0 then the operation can proceed, probably giving a non-scalar v0x . The only thing we can rule out here is the possibility that v0 and theta0 were both non-scalar and that one of them had 3 or more dimensions -- the * operation would not be defined for that case.
v0y = v0*sind(theta0); % y comp of initial speed
That will be the same size as v0x, whatever that turned out to be.
a = 0.5*g; %a=1/2*acceleration
b = v0y; %b=initial (y-comp) speed
c = y0; %c=initial vertical height
a is scalar, b is potentially non-scalar, c is from an input() so it is unknown size.
tFinal = roots([a, b, c]); %CHANGE THIS TO LESS ADVANCED!!
The [] operation would fail if a, b, and c do not all have the same number of rows. We know that a is scalar, so in order to get past the [] operation, b (which is y0y) must not have more than one row. In order to get one row out of non-scalar multiplication of v0 and sind(theta0) then v0 must have been either scalar or else had only one row. For example v0 could have been a 1 x 3 array, and theta could have been a 3 x 7 array, which would give a y0y of 1 x 7. If y0 were scalar then that would be roots() of a vector of legnth 1+7+1 = 9, which would be valid, giving 8 roots as output. If y0 were row vector then that would be roots of something even longer, giving 7+length(y0) outputs.
tFinal = max(tFinal); %takes the largest root as t
There is a bug there. max() ignores complex components, but you are likely to get complex roots -- with roots of a polynomial of degree 8 you are unlikely to be able to avoid complex components. The max() that you find may be associated with a value that has a non-zero complex component, which is not at all likely to be the tFinal that you want. You should be eliminating tFinal values with non-zero complex component (that is larger than round-off error) before taking the max(), and you should be taking into account the possibility that there will be no roots with non-zero complex component.
vfinaly = v0y + g*tFinal; % y comp of final speed
Remember that tFinal might be positive or negative. max() can act to select among the least-negative of a series of negative values.
if Ox == 0 && Oy == 0
We do not know what those are. We do, however, know that they are scalar, as otherwise the && would fail.
to = Ox/v0x %time until reaches obstacle
We know that 0x is scalar (otherwise the && would fail.) We do not know the size of v0x, but we have established that it must be either scalar or row vector (otherwise the [] in the roots() call would have failed.) But -- with scalar numerator, if v0x is a non-scalar row vector, the / operation will fail. Therefore in order to get past this line, v0x must be a scalar value, and to would be scalar / scalar giving a scalar result.
for i=0:length(to)
We just demonstrated that to must be a scalar in order to reach this point. length() of a scalar is 1. So i will run from 0 to 1
plot(x(i+1),y(i+1),'ko')
Resulting in exactly 2 points being plotted.
to = Ox/v0x %time until reaches obstacle
Reminder that a time is not the same as an index .
You need to search x to find the first entry that is >= to and plot to that point.
... and you need to validate the results of each input() call. You can see how much effort had to go into proving the size of the variables due to the lack of input validation.
You might want to consider using input with the 's' option and str2double() that: it will give a nan result for anything other than scalar input, and you can reject that nan easily.
3 Comments
Walter Roberson
on 6 Jan 2021
With the inputs being scalar, roots() is going to give you either two real values or two complex values.
idx = find(x < Ox, 1, 'last');
for i = 0 : idx
More Answers (0)
See Also
Categories
Find more on Graphics Performance in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!