I want to create a graphic representation. I have a sphere with radius of 50. I need to create two different filled capacities when it is one-fourth and three-fourths of its total capacity.
What I already have is this:
[x,y,z] = sphere();
r = 50;
surf( r*x, r*y, r*z ) % sphere with radius 50 centred at (0,0,0)
You could create the spere in two parts. Take a look at the following example:
% First part -- 0 to pi/2
theta = linspace(0,pi/2);
phi = linspace(-pi/2,pi/2);
[theta, phi] = meshgrid(theta, phi);
rho = 50;
[x, y, z] = sph2cart(theta, phi, rho);
surf(x,y,z, 'EdgeColor', 'b');
% Second part -- 90 to 360
hold on;
theta = linspace(pi/2,2*pi);
[theta, phi] = meshgrid(theta, phi);
[x, y, z] = sph2cart(theta, phi, rho);
surf(x,y,z, 'EdgeColor', 'r');
hold off;
It produces a graph like the following.
Related
I am trying to draw a cone, connected to the sphere in Matlab. I have the point [x1,y1,z1] outside of the sphere [x2,y2,z2] with R radius and I want it to be the top of the cone, created out of tangents.
On this pictures you can see what I have in mind:
Below you can see what I have already done. I am using it in order to mark the part of the Earth's surface, visible from the satellite position in orbit. Unfortunately, the cone in this picture is approximate, I need to create accurate one, connected with surface. For now, it is not only inaccurate, but also goes under it.
I am creating the sphere with this simple code (I am skipping the part of putting the map on it, it's just an image):
r = 6371.0087714;
[X,Y,Z] = sphere(50);
X2 = X * r;
Y2 = Y * r;
Z2 = Z * r;
surf(X2,Y2,Z2)
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.FaceLighting = 'phong';
figure();
globe = surface(X2,Y2,Z2,props);
Let's assume that I have the single point in 3D:
plot3(0,0,7000,'o');
How can I create such a cone?
There are two different questions here:
How to calculate cone dimensions?
How to plot lateral faces of a 3D cone?
Calculating Cone Dimensions
Assuming that center of sphere is located on [0 0 0]:
d = sqrt(Ax^2+Ay^2+Az^2);
l = sqrt(d^2-rs^2);
t = asin(rs/d);
h = l * cos(t);
rc = l * sin(t);
Plotting the Cone
The following function returns coordinates of lateral faces of cone with give apex point, axis direction, base radius and height, and the number of lateral faces.
function [X, Y, Z] = cone3(A, V, r, h, n)
% A: apex, [x y z]
% V: axis direction, [x y z]
% r: radius, scalar
% h: height, scalar
% n: number of lateral surfaces, integer
% X, Y, Z: coordinates of lateral points of the cone, all (n+1) by 2. You draw the sphere with surf(X,Y,Z) or mesh(X,Y,Z)
v1 = V./norm(V);
B = h*v1+A;
v23 = null(v1);
th = linspace(0, 2*pi, n+1);
P = r*(v23(:,1)*cos(th)+v23(:,2)*sin(th));
P = bsxfun(#plus, P', B);
zr = zeros(n+1, 1);
X = [A(1)+zr P(:, 1)];
Y = [A(2)+zr P(:, 2)];
Z = [A(3)+zr P(:, 3)];
end
The Results
rs = 6371.0087714; % globe radius
A = rs * 2 * [1 1 1]; % sattelite location
V = -A; % vector from sat to the globe center
% calculating cone dimensions
d = norm(A); % distance from cone apex to sphere center
l = (d^2-rs^2)^.5; % length of generating line of cone
sint = rs/d; % sine of half of apperture
cost = l/d; % cosine of half of apperture
h = l * cost; % cone height
rc = l * sint; % cone radius
% globe surface points
[XS,YS,ZS] = sphere(32);
% cone surface points
[XC, YC, ZC] = cone3(A, V, rc, h, 32);
% plotting results
hold on
surf(XS*rs,YS*rs,ZS*rs, 'facecolor', 'b', 'facealpha', 0.5, 'edgealpha', 0.5)
surf(XC, YC, ZC, 'facecolor', 'r', 'facealpha', 0.5, 'edgealpha', 0.5);
axis equal
grid on
Animating the satellite
The simplest way to animate objects is to clear the whole figure by clf and plot objects again in new positions. But a way more efficient method is to plot all objects once and in each frame, only update positioning data of moving objects:
clc; close all; clc
rs = 6371.0087714; % globe radius
r = rs * 1.2;
n = 121;
t = linspace(0, 2*pi, n)';
% point on orbit
Ai = [r.*cos(t) r.*sin(t) zeros(n, 1)];
[XS,YS,ZS] = sphere(32);
surf(XS*rs,YS*rs,ZS*rs, 'facecolor', 'b', 'facealpha', 0.5, 'edgealpha', 0.5)
hold on
[XC, YC, ZC] = cone3(Ai(1, :), Ai(1, :), 1, 1, 32);
% plot a cone and store handel of surf object
hS = surf(XC, YC, ZC, 'facecolor', 'r', 'facealpha', 0.5, 'edgealpha', 0.5);
for i=1:n
% calculating new point coordinates of cone
A = Ai(i, :);
V = -A;
d = norm(A);
l = (d^2-rs^2)^.5;
sint = rs/d;
cost = l/d;
h = l * cost;
rc = l * sint;
[XC, YC, ZC] = cone3(A, V, rc, h, 32);
% updating surf object
set(hS, 'xdata', XC, 'ydata', YC, 'zdata', ZC);
pause(0.01); % wait 0.01 seconds
drawnow(); % repaint figure
end
Another sample with 3 orbiting satellites:
I have 4 row vectors x, y, z and s, all of them have equal sizes 1*size. x, y, z should be the three Cartesian corodinate axes and s should be represented by colors (I want figure like below image). The statement Surf does not accept row vectors. I have read several stackoverflow post, but I could not find the answer. How can I plot such a figure?
I really appreciate any help you can provide.
I can't test it because you didn't provide any data, but you could try:
trisurf(x,y,z,s)
If that doesn't work then try:
DT = delaunayTriangulation(x,y,z);
tetramesh(DT,s);
You can try with this example of a 3D cube for a 3D meshgrid and it plots the "temperature".
L = 1;
dx = 0.25;
dy = dx;
dz = dy;
Nx = L/dx; Ny = Nx; Nz = Ny;
x = dx/2:dx:L-dx/2;
y = x; z = y;
[xx, yy, zz] = meshgrid(x,y,z);
theta = NaN(size(zz));
for jj=1:4;
for ii=1:4
for kk=1:4
theta(jj,ii,kk) = 273.15 + 5.*random('normal', 0, 1)
end
end
end
clf
isosurface(xx, yy, zz, theta)
colorbar
colormap jet
[fe, ve, ce] = isocaps(x, y, z, theta, 10);
p2 = patch('Faces', fe, 'Vertices', ve, 'FaceVertexCData', ce);
p2.FaceColor = 'interp';
p2.EdgeColor = 'none' ;
grid on
xlabel('X (m)');
ylabel('Y (m)');
zlabel('Z (m)');
title('Temperatures');
set(gca, 'clim', [273.15 273.15+5])
set(get(colorbar, 'title'), 'string', 'K', 'FontW', 'bold', 'fontname', 'Times New Roman', 'fontsize', 14);
view(3)
I like to visualize conics with Matlab or Octave. The (general) conic is given by the equation 0 = ax² + bxy + cy² +dxz +eyz+f*z² for a point p=(x,y,z). How can I plot this with Matlab or octave if I know the parameters a,b,c,d,e and f? Or respectively, how can I find the points that satisfy this equation?
Since you are asking for the conics, I understand that you are probably referring to the 2D contours of the general conic equation. I will also cover how to visualize this equation in other different ways.
For all the following examples, I have set the conic constants so that I obtain a hiperboloid.
My code is written in MATLAB syntax. If you are using Octave, it might differ slightly.
Visualizing 2D Conics with CONTOUR
I have isolated z in terms of x and y, from the general conic equation:
z = (1/2)*(-d*x-e*y±sqrt(-4*a*f*x.^2-4*b*f*x.*y-4*c*f*y.^2+d^2*x.^2+2*d*e*x.*y+e^2*y.^2))/f;
Since z is a piecewise function due to (± sqrt), I need to make sure that I plot both hemispheres. I designate z1 for +sqrt, and z2 for -sqrt.
Finally, I plot the contours for z1 and z2 that will yield the set of conics in 2D. This conics will be circles of different radius.
Code:
clear all;
clc;
% Conic constants.
a = 1;
b = 0;
c = 1;
d = 0;
e = 0;
f = -1;
% Value for x and y domain.
v = 10;
% Domain for x and y.
x = linspace(-v,v);
y = linspace(-v,v);
% Generate a 2D mesh with x and y.
[x,y] = meshgrid(x,y);
% Isolate z in terms of x and y.
z1 = (1/2)*(-d*x-e*y+sqrt(-4*a*f*x.^2-4*b*f*x.*y-4*c*f*y.^2+d^2*x.^2+2*d*e*x.*y+e^2*y.^2))/f;
z2 = (1/2)*(-d*x-e*y-sqrt(-4*a*f*x.^2-4*b*f*x.*y-4*c*f*y.^2+d^2*x.^2+2*d*e*x.*y+e^2*y.^2))/f;
% Find complex entries in z.
i = find(real(z1)~=z1);
j = find(real(z2)~=z2);
% Replace complex entries with NaN.
z1(i) = NaN;
z2(j) = NaN;
figure;
subplot(1,2,1);
% Draw lower hemisphere.
contour(x,y,z1,'ShowText','on');
% Adjust figure properties.
title('2D Conics: Lower hemishphere');
xlabel('x-axis');
ylabel('y-axis');
axis equal;
grid on;
box on;
axis([-10 10 -10 10]);
subplot(1,2,2);
% Draw upper hemisphere.
contour(x,y,z2,'ShowText','on');
hold off;
% Adjust figure properties.
title('2D Conics: Upper hemishphere');
xlabel('x-axis');
ylabel('y-axis');
axis equal;
grid on;
box on;
axis([-10 10 -10 10]);
Output:
Visualizing 3D Conics with CONTOUR3
Same as on the previous example, but now we plot the set of conics in 3D.
Code:
clear all;
clc;
% Conic constants.
a = 1;
b = 0;
c = 1;
d = 0;
e = 0;
f = -1;
% Value for x and y domain.
v = 10;
% Domain for x and y.
x = linspace(-v,v);
y = linspace(-v,v);
% Generate a 2D mesh with x and y.
[x,y] = meshgrid(x,y);
% Isolate z in terms of x and y.
z1 = (1/2)*(-d*x-e*y+sqrt(-4*a*f*x.^2-4*b*f*x.*y-4*c*f*y.^2+d^2*x.^2+2*d*e*x.*y+e^2*y.^2))/f;
z2 = (1/2)*(-d*x-e*y-sqrt(-4*a*f*x.^2-4*b*f*x.*y-4*c*f*y.^2+d^2*x.^2+2*d*e*x.*y+e^2*y.^2))/f;
% Find complex entries in z.
i = find(real(z1)~=z1);
j = find(real(z2)~=z2);
% Replace complex entries with NaN.
z1(i) = NaN;
z2(j) = NaN;
% Lower hemisphere. Draw 20 conics.
contour3(x,y,z1,20);
hold on;
% Upper hemisphere. Draw 20 conics.
contour3(x,y,z2,20);
hold off;
% Adjust figure properties.
title('3D Conics');
xlabel('x-axis');
ylabel('y-axis');
zlabel('z-axis');
axis equal;
grid on;
box on;
axis([-10 10 -10 10 -10 10]);
Output:
Visualizing Quadrics with ISOSURFACE
I have isolated f in terms of x, y and z, from the general conic equation, and renamed it to f_eq:
f_eq = -(a*x.^2+b*x.*y+c*y.^2+d*x.*z+e*y.*z)./z.^2;
Finally, I obtain the set of points that satisfy the equation f_eq = f, which is in fact an isosurface that yields a quadric; in this example a hiperboloid.
Code:
clear all;
clc;
% Conic constants.
a = 1;
b = 0;
c = 1;
d = 0;
e = 0;
f = -1;
% Value for x, y and z domain.
v = 10;
% Domain for x ,y and z.
x = linspace(-v,v);
y = linspace(-v,v);
z = linspace(-v,v);
% Generate a 3D mesh with x, y and z.
[x,y,z] = meshgrid(x,y,z);
% Evaluate function (3D volume of data).
f_eq = -(a*x.^2+b*x.*y+c*y.^2+d*x.*z+e*y.*z)./z.^2;
% Draw the surface that matches f_eq = f.
p = patch(isosurface(x,y,z,f_eq,f));
isonormals(x,y,z,f_eq,p)
p.FaceColor = 'red';
p.EdgeColor = 'none';
% Adjust figure properties.
title('Quadric');
xlabel('x-axis');
ylabel('y-axis');
zlabel('z-axis');
axis equal;
grid on;
box on;
axis([-10 10 -10 10 -10 10]);
camlight left;
lighting phong;
Output:
I have a matrix that stores x, y and z values as so:
{x1, y1, z1},
{x2, y2, z2},
{x3, y3, z3},
etc...
I need to interpolate the data, and plot in on a 2d graph, with color representing the z value. (example)
Any ideas?
Thanks!
Something like griddata might help you to interpolate:
x = vector(:,1);
y = vector(:,2);
z = vector(:,3);
% Settings
xres = 800; % Resolution, the higher, the smoother
yres = 800;
cm = 'default'; % Colormap
% Axes Limits
xmin = min(x);
ymin = min(y);
xmax = max(x);
ymax = max(y);
xi = linspace(xmin, xmax, xres);
yi = linspace(ymin, ymax, yres);
% Figure
myfig = figure('Position', [200 200 800 600]);
rotate3d off
[XI, YI] = meshgrid(xi, yi);
ZI = griddata(x, y, z, XI, YI, 'cubic');
mesh(XI,YI,ZI);
than you just need to change the view of it to only display a certain plane for a fixed value of z
In addition to #Alexandrew answer you can use newer and faster TriScatteredInterp class instead of GRIDDATA. For your exampe you can use 2D IMAGESC instead of 3D MESH.
%# insert the code from #Alexandrew answer to generate meshgrid
[XI, YI] = meshgrid(xi, yi);
TSI = TriScatteredInterp(x,y,z);
ZI = TSI(XI,YI);
imagesc(ZI)
colorbar
If your input matrix is a cell array, you can convert it to a numeric matrix with a = cell2mat(a);
I have little or no experience with volumetric data in MATLAB,
I need to complete next task:
I have 3 vectors ( rows ):
x_ = vector(1:smpl:max_row,1);
y_ = vector(1:smpl:max_row,2);
z_ = vector(1:smpl:max_row,3);
that are samples from large 3 columns array vector with height max_row.
x_ , y_ , z_ are points of 3D figure - surface points of the figure ( volume ). They represent 3D body that should be drawn in matlab.
I created linear grid:
%linear grid
a = -1.1:step:(-1.1+step*(length(x_)-1));
b = -1.1:step:(-1.1+step*(length(y_)-1));
c = -1.1:step:(-1.1+step*(length(z_)-1));
[x,y,z] = meshgrid(-1.1:step:(-1.1+step*(length(x_)-1)));
and also I create array v length(x_)*length(x_)*length(x_) that contains '1' in cells that are of 3D body representation function points and '0' another.
I tryied to make interpolation:
vi = interp3(x,y,z,v,x,y,z,'nearest');
but then vi = v that I've already created.
Now I need to plot the v array on 3D and form 3D body like in
http://www.mathworks.com/help/techdoc/ref/isonormals.html
for example.
I make that next way:
%plotting:
figure
p = patch(isosurface(x,y,z,v,1e-5,'verbose'),'FaceColor','green','EdgeColor','none');
grid on;
isonormals(v,p);
daspect([1 1 1])
view(3);
axis tight;
camproj perspective;
camlight
lighting gouraud
colormap(hsv)
but I get then only small rectangles in place of function '1' that are not connected like in picture that is attached.
I expect solid body enclosed by that points to be plotted.
Does anybody know what is the problem , how to draw 3D body from the x,y,z,v arrays ?
Thanks in advance.
image:
http://imgur.com/Ulegj
Try this, which will be a nice plot (it interpolates a bit though):
x = vector(1:smpl:max_row,1);
y = vector(1:smpl:max_row,2);
z = vector(1:smpl:max_row,3);
% Settings
displaySurface = 1;
displayPoints = 0;
xres = 800; % Resolution, the higher, the smoother
yres = 800;
cm = 'default'; % Colormap
% Axes Limits
xmin = min(x);
ymin = min(y);
xmax = max(x);
ymax = max(y);
xi = linspace(xmin, xmax, xres);
yi = linspace(ymin, ymax, yres);
% Figure
myfig = figure('Position', [200 200 800 600]);
rotate3d off
[XI, YI] = meshgrid(xi, yi);
ZI = griddata(x, y, z, XI, YI, 'cubic');
mesh(XI,YI,ZI);
colormap(cm)
if(displaySurface == 1)
hold on;
surf(XI, YI, ZI, 'EdgeColor', 'none');
end
hold on;
xlabel('x');
ylabel('y');
zlabel('z');
title('Title', 'FontWeight', 'bold');
xlim([xmin xmax])
ylim([ymin ymax])
grid off;
if(displayPoints == 1)
hold on
plot3(x, y, z,'marker','p','markerfacecolor','w','linestyle','none')
hidden off
end