I am stuck with an apparently simple problem. I have to revolve of 360° a 2D curve around an axis, to obtain a 3D plot. Say, I want to do it with this sine function:
z = sin(r);
theta = 0:pi/20:2*pi;
xx = bsxfun(#times,r',cos(theta));
yy = bsxfun(#times,r',sin(theta));
zz = repmat(z',1,length(theta));
surf(xx,yy,zz)
axis equal
I now want to visualize the numerical values of the Z plane, stored in a matrix. I would normally do it this way:
ch=get(gca,'children')
X=get(ch,'Xdata')
Y=get(ch,'Ydata')
Z=get(ch,'Zdata')
If I visualize Z with
imagesc(Z)
I don't obtain the actual values of Z of the plot, but the "un-revolved" projection. I suspect that this is related to the way I generate the curve, and from the fact I don't have a function of the type
zz = f(xx,yy)
Is there any way I can obtain the grid values of xx and yy, as well as the values of zz at each gridpoint?
Thank you for your help.
Instead of bsxfun you can use meshgrid:
% The two parameters needed for the parametric equation
h = linspace(0,2) ;
th = 0:pi/20:2*pi ;
[R,T] = meshgrid(h,th) ;
% The parametric equation
% f(x) Rotation along Z
% ↓ ↓
X = sin(R) .* cos(T) ;
Y = sin(R) .* sin(T) ;
% Z = h
Z = R ;
surf(X,Y,Z,'EdgeColor',"none")
xlabel('X')
ylabel('Y')
zlabel('Z')
Which produce:
And if you want to extract the contour on the X plane (X = 0) you can use contour:
contour(Y,Z,X,[0,0])
Which produce:
I am trying to generate a semi ellipsoidal dome shape by using x, y, z values. In my code below, I define the x,y,z values but I am unable to assign those values to sphere.
How do I resolve this?
clc
x = [65 55.2125 50.8267 46.7398 42.9232 39.3476 35.9815 32.7882 29.7175 26.6833 23.4690 18.7605];
y = x;
z = [0.0,0.9,2.7,5.2,8.2,11.8,15.8,20.3,25.2,30.7,37.1,47.5]; % max height of dome is 47.5
[x,y,z] = sphere(20);
x = x(12:end,:);
y = y(12:end,:);
z = z(12:end,:);
r = 65; % radius of the dome
surf(r.*x,r.*y,r.*z);
axis equal;
It will be simpler or at least more elegant to use the parametric equations of an ellipsoide.
% semi axis parameters
a = 65; % x-axis
b = 65; % y-axis
c = 47.5; % z-axis
%% Parametrisation
%
% To reach each point of the ellipsoide we need two angle:
% phi ∈ [0,2𝜋]
% theta ∈ [0, 𝜋]
%
% But since we only need half of an ellipsoide we can set
% theta ∈ [0,𝜋/2]
[theta,phi] = ndgrid(linspace(0,pi/2,50),linspace(0,2*pi,50));
x = a*sin(theta).*cos(phi);
y = b*sin(theta).*sin(phi);
z = c*cos(theta);
%plot
surf(x,y,z)
axis equal
Result:
You can remove the bottom half of the sphere by assigning NaNs to the approptiate elements of x and y:
[x,y,z] = sphere(20);
I = (z<0);
x(I) = NaN;
y(I) = NaN;
surf(x,y,z)
I am trying to plot a circle's equation-regression on x and y, but I do not know how to proceed. Any suggestions? (I want a circle to connect the points thru least square solution)
x = [5; 4; -1; 1];
y = [3; 5; 2; 1];
% circle's equation: x^2+y^2 = 2xc1+2yc2+c3
a = [2.*x,2.*y,ones(n,3)]
b = [x.^2 + y.^2];
c = a\b;
How do I plot the circle after this
There are a couple of ways how to plot a circle in matlab:
plot a line where the data points form a circle
use the 'o' marker in plot and the 'MarkerSize' name-value pair to set the radius of the circle
you can plot a circle image using the vscircle function
In your case, I would go with the first option, since you maintain in control of the circle size.
use the rectangle(...,'Curvature',[1 1]) function [EDITED: thx to #Cris Luengo]
So here is a plotting function
function circle(x,y,r)
%x and y are the coordinates of the center of the circle
%r is the radius of the circle
%0.01 is the angle step, bigger values will draw the circle faster but
%you might notice imperfections (not very smooth)
ang=0:0.01:2*pi+.01;
xp=r*cos(ang);
yp=r*sin(ang);
plot(x+xp,y+yp);
end
So with your (corrected) code, it looks like this
x = [5; 4; -1; 1];
y = [3; 5; 2; 1];
% circle's equation: x^2+y^2 = 2xc1+2yc2+c3
a = [2.*x,2.*y,ones(length(x),1)];
b = [x.^2 + y.^2];
c = a\b;
x_m = c(1)/2;
y_m = c(2)/2;
r = sqrt(x_m^2 + y_m^2 -c(3));
% plot data points
plot(x,y,'o')
hold on
% plot center
plot(x_m,y_m,'+')
% plot circle
circle(x_m,y_m,r)
hold off
I could use this method to draw a ellipsoid in Matlab:
Xc is x-coordinate of the center, Xr is half the length of ellipsoid in x direction
Xc = 0; Xr = 1;
Yc = 0; Yr = 2;
Zc = 0; Zr = 3;
[X Y Z] = ellipsoid(Xc, Yc, Zc, Xr, Yr, Zr);
surf(X,Y,Z);
This can give me a 3-D image of the ellipsoid but if I do not know things like Xc or Xr ..., all I know is a function:
A = 5; B = 0; C =2;
D = 2; E = 1;
P = [A B;
B C];
q = [D E];
syms x y;
f = [x y] * P * [x y]' + q * [x y] + 1;
But it seems that surf won't allow to use syms variables.
ezplot(f) give only a 2-D ellipse.
How can I draw a 3-D ellipsoid with this function in Matlab using surf, mesh or anything else?
The reason I write this function f is that I want to see how the positive definiteness and negative definiteness of matrix P influence the image of function f.
Thanks!
You can draw an ellipsoid (or any other implicit surface) using isosurface. For example, the ellipsoid
2*x^2+2xy+3y^2+2yz+4z^2+4z-1=0 can be drawn using the following code:
[x,y,z]= meshgrid(-2:0.05:2); % the surface should fit in the meshgrid area
v= 2*x.^2+2*x.*y+3*y.^2+2*y.*z+4*z.^2+4*z-1; % the left side of the equation
isosurface(x,y,z,v,0); % the value 0 is the right hand side of the equation
axis tight
How do I draw an ellipse and an ellipsoid using MATLAB?
(x^2/a^2)+(y^2/b^2)=1
n=40;
a=0; b=2*pi;
c=0; d=2*pi;
for i=1:n
u=a+(b-a)*(i-1)/(n-1);
for j=1:m
v=a+(d-c)*(j-1)/(m-1);
x(i,j)=sin(u)*cos(v);
y(i,j)=sin(u)*sin(v);
z(i,j)=cos(u);
end
end
mesh(x,y,z);
But I want the shape?
Ellipse article on Wikipedia had a simple JavaScript code to draw ellipses.
It uses the parametric form:
x(theta) = a0 + ax*sin(theta) + bx*cos(theta)
y(theta) = b0 + ay*sin(theta) + by*cos(theta)
where
(a0,b0) is the center of the ellipse
(ax,ay) vector representing the major axis
(bx,by) vector representing the minor axis
I translated the code into a MATLAB function:
calculateEllipse.m
function [X,Y] = calculateEllipse(x, y, a, b, angle, steps)
%# This functions returns points to draw an ellipse
%#
%# #param x X coordinate
%# #param y Y coordinate
%# #param a Semimajor axis
%# #param b Semiminor axis
%# #param angle Angle of the ellipse (in degrees)
%#
narginchk(5, 6);
if nargin<6, steps = 36; end
beta = -angle * (pi / 180);
sinbeta = sin(beta);
cosbeta = cos(beta);
alpha = linspace(0, 360, steps)' .* (pi / 180);
sinalpha = sin(alpha);
cosalpha = cos(alpha);
X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta);
Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta);
if nargout==1, X = [X Y]; end
end
and an example to test it:
%# ellipse centered at (0,0) with axes length
%# major=20, ,minor=10, rotated 50 degrees
%# (drawn using the default N=36 points)
p = calculateEllipse(0, 0, 20, 10, 50);
plot(p(:,1), p(:,2), '.-'), axis equal
The answers from Jacob and Amro are very good examples for computing and plotting points for an ellipse. I'll address some easy ways you can plot an ellipsoid...
First, MATLAB has a built-in function ELLIPSOID which generates a set of mesh points given the ellipsoid center and the semi-axis lengths. The following creates the matrices x, y, and z for an ellipsoid centered at the origin with semi-axis lengths of 4, 2, and 1 for the x, y, and z directions, respectively:
[x, y, z] = ellipsoid(0, 0, 0, 4, 2, 1);
You can then use the function MESH to plot it, returning a handle to the plotted surface object:
hMesh = mesh(x, y, z);
If you want to rotate the plotted ellipsoid, you can use the ROTATE function. The following applies a rotation of 45 degrees around the y-axis:
rotate(hMesh, [0 1 0], 45);
You can then adjust the plot appearance to get the following figure:
axis equal; %# Make tick mark increments on all axes equal
view([-36 18]); %# Change the camera viewpoint
xlabel('x');
ylabel('y');
zlabel('z');
Also, if you want to use the rotated plot points for further calculations, you can get them from the plotted surface object:
xNew = get(hMesh, 'XData'); %# Get the rotated x points
yNew = get(hMesh, 'YData'); %# Get the rotated y points
zNew = get(hMesh, 'ZData'); %# Get the rotated z points
I've adapted this excellent ellipse plotting script from MATLAB Central for your requirement of
function plotEllipse(a,b,C)
% range to plot over
%------------------------------------
N = 50;
theta = 0:1/N:2*pi+1/N;
% Parametric equation of the ellipse
%----------------------------------------
state(1,:) = a*cos(theta);
state(2,:) = b*sin(theta);
% Coordinate transform (since your ellipse is axis aligned)
%----------------------------------------
X = state;
X(1,:) = X(1,:) + C(1);
X(2,:) = X(2,:) + C(2);
% Plot
%----------------------------------------
plot(X(1,:),X(2,:));
hold on;
plot(C(1),C(2),'r*');
axis equal;
grid;
end
Note: change N to define the resolution of your ellipse
Here's an ellipse centered at (10,10) with a = 30 and b = 10
Ellipse article on Wikipedia and Rotation matrix.
Rewrite that functions:
rotate by rotAngle counter-clockwise around (0,0)
Coordinate transform to (cx, cy)
function [X,Y] = calculateEllipse(cx, cy, a, b, rotAngle)
%# This functions returns points to draw an ellipse
%#
%# #param x X coordinate
%# #param y Y coordinate
%# #param a Semimajor axis
%# #param b Semiminor axis
%# #param cx cetner x position
%# #param cy cetner y position
%# #param angle Angle of the ellipse (in degrees)
%#
steps = 30;
angle = linspace(0, 2*pi, steps);
% Parametric equation of the ellipse
X = a * cos(angle);
Y = b * sin(angle);
% rotate by rotAngle counter clockwise around (0,0)
xRot = X*cosd(rotAngle) - Y*sind(rotAngle);
yRot = X*sind(rotAngle) + Y*cosd(rotAngle);
X = xRot;
Y = yRot;
% Coordinate transform
X = X + cx;
Y = Y + cy;
end
and an example to test it:
[X,Y] = calculateEllipse(0, 0, 20, 10, 0);
plot(X, Y, 'b'); hold on; % blue
[X,Y] = calculateEllipse(0, 0, 20, 10, 45);
plot(X, Y, 'r'); hold on; % red
[X,Y] = calculateEllipse(30, 30, 20, 10, 135);
plot(X, Y, 'g'); % green
grid on;
Create two vectors, one of the x-coordinates of the points of the circumference of the ellipsoid, one of the y-coordinates. Make these vectors long enough to satisfy your accuracy requirements. Plot the two vectors as (x,y) pairs joined up. I'd drop the for loops from your code, much clearer if you use vector notation. Also I'd format your question using the SO markup for code to make it all clearer to your audience.
The simplest way might be to use the Matlab function
pdeellip(xc,yc,a,b,phi)
For example:
pdeellip(0,0,1,0.3,pi/4)
However, this is simple solution is good to have a quick glance how the ellipse looks like. If you want to have a nice plot, look at the other solutions.
I don't know in which version of Matlab this was added, but it's available at least from version R2012b on.