How to plot spheres on top of scattered stars in MATLAB? - matlab

I would like to make a scattered stars and plot multiple spheres on top of it? I tried doing this:
x = rand(100,1); y = rand(100,1); z = rand(100,1);
scatter(x,y,z,'c*')
After this I tried plotting sphere but the sphere pushes the stars to the side. How do I fix this?
vec = [1;1;1]; rads = 1;
[x y z] = sphere;
x = rads*x+vec(1); y = rads*y+vec(2);
z = rads*z+vec(3);
surf(x, y, z, 'Edgecolor', 'none')
colormap colorcube
As you can see it pushed the stars to the side
Thank you.

Its pushing the scatter plot to the side because the range of the 'stars' is [0 1] because the command rand(...) generates values between 0 and 1. On the other hand, the sphere goes from 0 to 2 in all 3 directions.
To fix the problem, you can simply multiply the data used to generate the scatter plot by 2, so they will be in the range [0 2].
Doing so results in the following:
And the code. Note that I used scatter3 instead of scatter.
clear
clc
close all
xs = 2*rand(100,1); ys = 2*rand(100,1); zs = 2*rand(100,1);
hScatter = scatter3(xs,ys,zs,'c*')
hold on
vec = [1;1;1]; rads = 1;
[x y z] = sphere;
x = rads*x+vec(1); y = rads*y+vec(2);
z = rads*z+vec(3);
surf(x, y, z, 'Edgecolor', 'none')
colormap colorcube
rotate3d on

Related

Applying 3D rotation matrix to x, y, z values obtained from surface function

Applying 3D rotation matrix to the x,y,z values obtained from surface function object. The error I get is due to the matrix not being nonconforment but how can I adjust the matrix correctly?
I know hgtransform / makehgtform can do rotations but I need to use rotation matrices since I plan on testing it using matrices created from quaternions.
I've created a little plane out of cylinders and the surface functions.
See code below:
clear all,clf
ax=axes('XLim',[-2 2],'YLim', [-2 10],'ZLim',[-1.5 1.5]);
grid on;
%axis equal;
xlabel('x');
ylabel('y');
zlabel('z');
ax
% rotate around
rot_mat = [.707 -.707 0;.707 .707 0; 0 0 1] %rotation matrix
[xc yc zc] = cylinder([0.1 0.0]); %cone
[x y z]= cylinder([0.2 0.2]);
h(1) = surface(xc,zc,-yc,'FaceColor', 'red'); %noise cone
h(2) = surface(z,y,0.5*x,'FaceColor', 'blue'); %right wing
h(3) = surface(-z,y,0.5*x,'FaceColor', 'yellow');%left wing
h(4) = surface(x,-1.5*z,0.5*y,'FaceColor', 'green'); %main body
h(5) = surface(xc,(1.5*yc)-1.3,z*.5,'FaceColor', 'red'); %tail
view(3);
x_temp = get(h(1),'xdata'); % get x values
y_temp = get(h(1),'ydata');
z_temp =get(h(1),'zdata');
xc_new=x_temp.*rot_mat;
%zc_new=
%yc_new=
I can get the x,y, and z value by using the commands
x_temp = get(h(1),'xdata');
y_temp = get(h(1),'ydata');
z_temp = get(h(1),'zdata');
The error I get is due to the matrix being nonconforment but how can I adjust the matrix correctly?
error: test_object_matrix_rot: product: nonconformant arguments (op1 is 2x21, op2 is 3x3).
The error is with the line xc_new=x_temp.*rot_mat;
PS: I'm using Octave 5.0.91 which is like Matlab
YOu are messing up a lot of things......in fact I would say, you have made your work complex. YOu should straight away work on matrices to rotate to new positons instead of arrays and picking them from the figure.
This line:
x_temp = get(h(1),'xdata'); % get x values
giving you a 2*21 array and your rot_mat is 3X3.....you cannot multiply them. YOu need to pick (x,y,z) and multiply this point with rotation matrix to get the point shifted. Check the below pseudo code.....yo can develop your logic with the below example code.
t = 0:0.1:1;
[X,Y,Z] = cylinder((t));
%% Rotation
th = pi/2 ;
Rx = [1 0 0 ; 0 cos(th) -sin(th) ; 0 sin(th) cos(th)] ;
P0 = [X(:) Y(:) Z(:)] ;
P1 = P0*Rx ;
X1 = reshape(P1(:,1),size(X)) ;
Y1 = reshape(P1(:,2),size(X)) ;
Z1 = reshape(P1(:,3),size(X)) ;
figure
hold on
surf(X,Y,Z)
surf(X1,Y1,Z1)
view(3)

Multiple colors in the same line

I would like to plot a sine curve in Matlab. But I want it blue for the positive values and red for the negative values.
The following code just makes everything red...
x = [];
y = [];
for i = -180 : 180
x = [x i];
y = [y sin(i*pi/180)];
end
p = plot(x, y)
set(p, 'Color', 'red')
Plot 2 lines with different colours, and NaN values at the positive/negative regions
% Let's vectorise your code for efficiency too!
x = -pi:0.01:pi; % Linearly spaced x between -pi and pi
y = sin(x); % Compute sine of x
bneg = y<0; % Logical array of negative y
y_pos = y; y_pos(bneg) = NaN; % Array of only positive y
y_neg = y; y_neg(~bneg)= NaN; % Array of only negative y
figure; hold on; % Hold on for multiple plots
plot(x, y_neg, 'b'); % Blue for negative
plot(x, y_pos, 'r'); % Red for positive
Output:
Note: If you're happy with scatter plots, you don't need the NaN values. They just act to break the line so you don't get join-ups between regions. You could just do
x = -pi:0.01:pi;
y = sin(x);
bneg = y<0;
figure; hold on;
plot(x(bneg), y(bneg), 'b.');
plot(x(~bneg), y(~bneg), 'r.');
Output:
This is so clear because my points are only 0.01 apart. Further spaced points would appear more like a scatter plot.

Plotting x,y,z with intervals

How do I plot xyz In rectangular, polar, and 3-D?
for x = 0 to 35pi:
Y = x*sin(x)
Z = x*cos(x)
Using the the intervals of X which provides very smooth plots . Create three plots including tittle and labels .
This is the input I have put in so far. I'm not sure if this is correct:
x = pi*linspace(0,35);
y = pi*x,sin(pi*x);
z = pi*x,cos(pi*x);
plot3(x,y,z)
title('data analysis')
xlabel('independent x')
ylabel('dependent y')
zlabel('z')
I believe this solves the problem as you describe it:
x = linspace(0, 35*pi, 10000);
y = x .* sin(x);
z = x .* cos(x);
plot3(x, y, z);
title('data analysis');
xlabel('independent x');
ylabel('dependent y');
zlabel('z');

Graphing a Line given x,y, and z angle

I have this piece of MATLAB code that outputs x,y, and z angles and I would like draw a line using them. Can someone point me in the right direction on how to do this?
C = pi;
A = pi;
B = pi;
Z = [cos(C),-sin(C),0; sin(C),cos(C),0; 0,0,1];
X = [1,0,0;0,cos(A),-sin(A);0,sin(A),cos(A)];
Y = [cos(B),0,sin(B);0,1,0;-sin(B),0,cos(B)];
R =(X*Y)*Z;
yaw=atan2(R(2,1),R(1,1))
pitch=atan2(-R(3,1),sqrt(R(3,2)^2+R(3,3)^2))
roll=atan2(R(3,2),R(3,3))
X, Y, and Z are not angles, they are rotation matrices defined by the angles A, B, and C.
it's not clear what's the meaning of "draw a line using them", they are just used to rotate vectors in the 3D space.
here is an example of drawing a rotated vector with them:
% define rotation angles (around the axes)
C = pi/2;
A = pi/4;
B = pi/4;
% generate rotation matrices
Z = [cos(C),-sin(C),0; sin(C),cos(C),0; 0,0,1];
X = [1,0,0;0,cos(A),-sin(A);0,sin(A),cos(A)];
Y = [cos(B),0,sin(B);0,1,0;-sin(B),0,cos(B)];
R =(X*Y)*Z;
% generate a vector and rotate it
v = [1;1;1];
u = R*v;
% plot
quiver3(0,0,0,v(1),v(2),v(3));
hold on
quiver3(0,0,0,u(1),u(2),u(3));
xlim([-1 1]); ylim([-1 1]); zlim([-1 1])
axis square
legend('original','rotated')

How to plot with pcolor one 2D function with two x axis ? MATLAB

I would like to plot one function with two x axis. One on the bottom one on the top. The top is just different vector. How to add the second x axis on the top ?
X = rand(100,100);
x = linspace(1,100,100); %bottom x axis
x2 = linspace(0.1,1,100); %top x axis
y = linspace(100,200,100);
pcolor(x,y,X);
shading interp
This might help,
X = rand(100,100);
x = linspace(1,100,100);
x2 = linspace(0.1,1,100);
y = linspace(100,200,100);
h2 = axes('XAxisLocation','top','XTick',linspace(0.1,1,10),'YTick',[]);
h2_pos = get(h2,'Position');
h1 = axes('XTick',linspace(1,100,10),'YTick',[],...
'Position',h2_pos);
pcolor(x,y,X,'Parent',h1);
shading interp
which gives this,