İnvisible plots and a error

Guys what is wrong with my matlab codes? I could not take plots from first two figure and i take 'Array indices must be positive integers or logical values.' error from last two for loops.
clear;
clc;
y0=3;
x0=1:5;
for i=1:5
l(i)=sqrt(x0(i)^2+y0.^2);
Q(i)= atan(y0/x0(i));
end
plot(x0(i),l)
hold on
plot(x0(i),Q)
hold on
figure(1)
l1=3.5;
l2=3.5;
for a=1:5
q2(a)=acos((x0(a)^2+y0^2-l1^2-l2^2)/(2*l1*l2));
q1(a)=atan(y0/x0(a))-atan((l2*sin(q2)/(l1+l2*cos(q2))));
end
plot(x0(a),q1)
hold on
plot(x0(a),q2)
hold on
figure(2)
c2=45;
i1=2;
i2=3;
i3=1.5;
c1=0:180;
for k=0:180
x(k)=(i2+i3)*cos(c2)*cos(c1(k));
y(k)=(i2+i3)*cos(c2)*sin(c1(k));
z(k)=i1+(i2+i3)*sin(c2);
end
plot(c1(k),x)
hold on
plot(c1(k),y)
hold on
plot(c1(k),z)
hold on
figure(3)
i3_1=0.5:2;
c1_1=0:360;
for b=0:360
x(b)=(i2+i3_1)*cos(c2)*cos(c1(b));
y(b)=(i2+i3_1)*cos(c2)*sin(c1(b));
z(b)=i1+(i2+i3_1)*sin(c2);
end
plot(c1(b),x)
hold on
plot(c1(b),y)
hold on
plot(c1(b),z)
hold on
figure(4)

 Risposta accettata

clear;
clc;
y0=3;
x0=1:5;
for i=1:5
l(i)=sqrt(x0(i)^2+y0.^2);
Q(i)= atan(y0/x0(i));
end
figure(1)
plot(x0, l, 'DisplayName', 'l')
hold on
plot(x0, Q, 'DisplayName', 'Q')
hold on
legend show
figure(2)
l1=3.5;
l2=3.5;
for a=1:5
q2(a)=acos((x0(a)^2+y0^2-l1^2-l2^2)/(2*l1*l2));
q1(a)=atan(y0/x0(a))-atan((l2*sin(q2)/(l1+l2*cos(q2))));
end
plot(x0, q1, 'DisplayName', 'q1')
hold on
plot(x0, q2, 'DisplayName', 'q2')
hold on
legend show
figure(3)
c2=45;
i1=2;
i2=3;
i3=1.5;
c1=0:180;
clear x y z
for k=0:180
x(k+1)=(i2+i3)*cos(c2)*cos(c1(k+1));
y(k+1)=(i2+i3)*cos(c2)*sin(c1(k+1));
z(k+1)=i1+(i2+i3)*sin(c2);
end
plot(c1, x, 'DisplayName', 'x')
hold on
plot(c1, y, 'DisplayName', 'y')
hold on
plot(c1, z, 'DisplayName', 'z')
hold on
legend show
figure(4)
i3_1=0.5:2;
c1_1=0:360;
clear x y z
for b=0:360
x(b+1,:)=(i2+i3_1)*cos(c2)*cos(c1_1(b+1));
y(b+1,:)=(i2+i3_1)*cos(c2)*sin(c1_1(b+1));
z(b+1,:)=i1+(i2+i3_1)*sin(c2);
end
plot(c1_1, x, 'DisplayName', 'x')
hold on
plot(c1_1, y, 'DisplayName', 'y')
hold on
plot(c1_1, z, 'DisplayName', 'z')
hold on
legend show
The last of those is a bit odd because your i3_1 is a vector consisting of [0.5, 1.5] since you have 0.5:2 but the default increment is 1.
In all of your other plots, the i3 or equivalent is a scalar; this is the only plot where it is a vector.

7 Commenti

Thank you so much and sorry i forgot to indicate that but is it enough to make it scatter plot with changing plot command to scatter plot?
Sure, if you want.
Sorry i was not available, i examined your answer yet but can you explain why you write the inside like that x(k+1), x(b+1,:) instead k and b?
And what is the reason of straight lines in the plots and twice of x,y,z values in the last plot?
Walter Roberson
Walter Roberson il 23 Mag 2022
Modificato: Walter Roberson il 23 Mag 2022
Your code had
for k=0:180
x(k)=(i2+i3)*cos(c2)*cos(c1(k));
Your for loop is over the values that you want for k, 0 to 180 degrees. You could imagine, for example, that you wanted half-degree offsets, then you probably would have coded for k=0:0.5:180 .
But you use c1(k) to recall a relative position within c1, and you assign to x(k) which is obviously intended to be a relative position within x. The first value for k, which you intend to be associate with 0 degrees, you want the first value for c1 and you want to assign to the first location in x . The relative index of the "first" entry is 1. So for the 0 degrees you want relative index 1. If you were working with half-degree increments, the second entry in k would be 0.5, but the relative index into c1 and the relative output into x that you would want, would be 2. If you were wanting to go from (say) -45 degrees to +45 degrees, -45:45 then the first k value would be -45 but the index you would want for c1 and the output index you would need for x would be 1.
You need to get clear the difference between relative offset (index), and the value you want to be associated with the relative offset (index)
The most general way of handling a situation like this would be something like
degrees = 0:.5:180 %or as appropriate
num_degrees = numel(degrees);
x = zeros(1, num_degrees);
y = zeros(1, num_degrees);
z = zeros(1, num_degrees);
for degrees_idx = 1 : num_degrees
current_degrees = degrees(degrees_idx);
x(degrees_idx) = (i2+i3)*cos(c2)*cos(c1(degrees_idx));
y(degrees_idx) = (i2+i3)*cos(c2)*sin(c1(degrees_idx));
z(degrees_idx) = i1+(i2+i3)*sin(c2);
end
when you use this kind of approach, you are looping over indices, not over values. With this kind of set-up the values do not need to be integers or positive or sorted or real-valued.
Now, for the special case of 0:number, if you are sure you will not be needing to alter that at some point to non-integer values, then mathematically you could do
maxdegree = 180;
x = zeros(1,maxdegree+1);
y = zeros(1,maxdegree+1);
z = zeros(1,maxdegree+1);
for k = 0:180
degrees_idx = k + 1;
x(degrees_idx) = (i2+i3)*cos(c2)*cos(c1(degrees_idx));
y(degrees_idx) = (i2+i3)*cos(c2)*sin(c1(degrees_idx));
z(degrees_idx) = i1+(i2+i3)*sin(c2);
end
since you know in this kind of case that the relative index is 1 more than the value of k.
Now, what I would of done instead, is
x = zeros(size(c1));
y = zeros(size(c1));
z = zeros(size(c1));
for k = 1 : numel(c1)
x(k) = (i2+i3)*cos(c2)*cos(c1(k));
y(k) = (i2+i3)*cos(c2)*sin(c1(k));
z(k) = i1+(i2+i3)*sin(c2);
end
Here, k is acting purely as an index, and the 0:180 is not useful information: you care only that you process all entries in c1.
Well, more correctly what I would have done is
x = zeros(size(c1));
y = zeros(size(c1));
z = zeros(size(c1));
for k = 1 : numel(c1)
x(k) = (i2+i3)*cosd(c2)*cosd(c1(k));
y(k) = (i2+i3)*cosd(c2)*sind(c1(k));
z(k) = i1+(i2+i3)*sind(c2);
end
"And what is the reason of straight lines in the plots and twice of x,y,z values in the last plot?"
In the first three plots, you have code such as
i1=2;
i2=3;
i3=1.5;
Notice those are all scalars. So when you do
x(k) = (i2+i3)*cosd(c2)*cosd(c1(k));
the i2+i3 is a scalar, and with c2 and c1(k) being a scalar, the right hand side evaluates to a scalar.
In the last plot, you have
i3_1=0.5:2;
c1_1=0:360;
for b=0:360
x(b)=(i2+i3_1)*cos(c2)*cos(c1(b));
Notice that i3_1 here is a vector containing two elements, [0.5, 1.5] . So the i2+i3_1 component gives a vector, and the two cos() terms are each scalars, so the right hand side is a vector, not a scalar.
I might suspect that you made an error and that you wanted i3_1 to be a scalar like in the other plots, but I have to presume that you coded what you actually wanted, that you want to calculate a vector in each element of the loop. And that having calculated the vector for each location, that you want to plot both elements somehow.
Side note: notice that in my version of the code, I corrected c1(b) to c1_1(b) . c1 was initialized in a previous plot as being 0:180 which would get you an error when you tried to index c1(182) when b became 181 out of 350.
This is another reason why, much of the time, you should be looping over indices rather than over values.
x = zeros(size(c1));
y = zeros(size(c1));
z = zeros(size(c1));
for k = 1 : numel(c1)
x(k) = (i2+i3)*cosd(c2)*cosd(c1(k));
y(k) = (i2+i3)*cosd(c2)*sind(c1(k));
z(k) = i1+(i2+i3)*sind(c2);
end
i used this for the figure 3.
Is there a possibility to do figure 4 as only b will be in the brackets? Because i have to explain this work in video and i am not good enough in matlab to understand your explanations sorry it is a bit complicated to me :')
for b=1:numel(c1_1)
x(b,:)=(i2+i3_1)*cos(c2)*cos(c1_1(b));
y(b,:)=(i2+i3_1)*cos(c2)*sin(c1_1(b));
z(b,:)=i1+(i2+i3_1)*sin(c2);
end

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

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

Start Hunting!

Translated by