What is wrong with my for loop

조회 수: 2 (최근 30일)
Anon
Anon 2021년 1월 6일
댓글: Anon 2021년 1월 6일
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
Rik
Rik 2021년 1월 6일
Where do you define x and y? Are they scalars? Are you using this code in a loop?
Anon
Anon 2021년 1월 6일
this is all of the code preceeding the code posted above:
v0 = input('v0: ');
theta0 = input('theta: ');
v0x = v0*cosd(theta0); % x comp of initial speed
v0y = v0*sind(theta0); % y comp of initial speed
y0 = input('y0: ');; %initial vertical height
g = -9.81;%acceleration due to gravity (taking down as negative) for the
%user selected option and converts the string into a double 'the value'
Ox = input('Ox: ');
Oy = input('Oy: ');
O = input('Ot(cm): '); %converts the cm into m to be plotted
Ot = O/100;
%----------Calculates t by s=ut+1/2at^2 where: ----------------------------
a = 0.5*g; %a=1/2*acceleration
b = v0y; %b=initial (y-comp) speed
c = y0; %c=initial vertical height
tFinal = roots([a, b, c]); %CHANGE THIS TO LESS ADVANCED!!
tFinal = max(tFinal); %takes the largest root as t
%----------Calculation of final speed: ---------------------------------
vfinalx = v0x; % x comp of final speed
vfinaly = v0y + g*tFinal; % y comp of final speed
vfinal = sqrt(vfinalx^2 + vfinaly^2); %resolved final speed (pythagoras)
%----------Calculation of points to be plotted: ---------------------------
t = linspace(0,tFinal,100) %creates an array of time with 100 elements
x = v0x.*t %calculates the range (x)
y = y0 + v0y.*t+0.5*g*t.^2 %calculates the height (y)
y(y < 0) = 0; %the y-axis cannot go below 0!
x and y are defined in this

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2021년 1월 6일
편집: Walter Roberson 2021년 1월 6일
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
Walter Roberson
Walter Roberson 2021년 1월 6일
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
Anon
Anon 2021년 1월 6일
amazing thank you so much Walter, thats done it! :)

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Graphics Performance에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by