Plot surface in cylindrical coordinate system in matlab - matlab

I have a function and want to plot it on cylindrical coordinate.
w(z,theta)=sin(n.pi.z/a).sin(m.theta)
The limits of variables are: z=0..a , theta=0..theta_0 and radius of cylinder is R=1.
As a physical sense I can explain that if we in the Cartesian coordinate,
z & theta are x,y axis and w is surface on this rectangular domain. But in cylindrical coordinate z & theta restrict one cylindrical piece of cylinder with radius=1 that w is surface on this domain.

Plotting using cylindrical or spherical coordinates involves several steps:
Create vectors for theta and z:
theta = linspace(0,2*pi);
z = linspace(0,10);
Create a meshgrid from theta and z:
[TH,Z] = meshgrid(theta,z);
Write your function R(TH,Z):
R = sin(Z)+1+5*sin(TH); %// For cylinder it would be simply R = ones(size(Z));
Convert cylindrical coordinates to cartesian:
[x,y,z] = pol2cart(TH,R,Z);
Plot the result using surf, mesh or whatever:
mesh(x,y,z);
axis equal
This is the result you get:

Related

How to plot 2 surfaces and their intersection curve in MATLAB?

I have the equations of two surfaces and I want to plot both of them and highlight their intersection
My code looks like this
t=linspace(-1,1,100);
x=t;
y=t;
z=cos(t.^8+12);
plot3(x,y,z,'g-','linewidth',3)
hold on
[x,y]=meshgrid(-2:2,-2:2);
surf(x,y,z)
And that gives me the plot for the surface z = f(x,y) but I can not figure out how to plot the plane x=y
Subject to editing upon further question details.
Here might be an interesting starting point. Below is a script that uses the patch() function to create the rectangle plane x = y. The patch function takes corner coordinates of a rectangle to plot in the 3D case (x,y,z) coordinates. Unfortunately, I was unable to get the surface plot from the above code. So the intersection discussion is a story for another time.
Function Call:
patch(X_Coordinates,Y_Coordinates,Z_Coordinates,Colour);
%***************************************************%
%3D line plot%
%***************************************************%
x = linspace(-1,1,100);
y = linspace(-1,1,100);
z = cos(x.^8+12);
plot3(x,y,z,'g-','linewidth',3)
%***************************************************%
%3D surface plot%
%***************************************************%
hold on
[x,y] = meshgrid(-2:0.01:2,-2:0.01:2);
z = cos(x.^8+12);
% surf(x,y,z);
%***************************************************%
%Plotting the xy-plane%
%***************************************************%
Plane_Top = 255;
Plane_Bottom = -255;
Plane_Width = 4;
%Using plane attributes to set patch points%
X = [-Plane_Width/2 -Plane_Width/2 Plane_Width/2 Plane_Width/2];
Y = [-Plane_Width/2 -Plane_Width/2 Plane_Width/2 Plane_Width/2];
Z = [Plane_Bottom Plane_Top Plane_Top Plane_Bottom];
%Plotting characteristics%
Colour = [252/255 148/255 3/255];
patch(X,Y,Z,Colour);
view(3);
grid on;
xlabel("X-Axis"); ylabel("Y-Axis");
title("Plotting the XY-Plane and Line Function");
Using MATLAB version: R2019b

Interpolate surface of 3D cylinder in Matlab

I have a dataset that describes a point cloud of a 3D cylinder (xx,yy,zz,C):
and I would like to make a surface plot from this dataset, similar to this
In order to do this I thought I could interpolate my scattered data using TriScatteredInterp onto a regular grid and then plot it using surf:
F = TriScatteredInterp(xx,yy,zz);
max_x = max(xx); min_x = min(xx);
max_y = max(yy); min_y = min(yy);
max_z = max(zz); min_z = min(zz);
xi = min_x:abs(stepSize):max_x;
yi = min_y:abs(stepSize):max_y;
zi = min_z:abs(stepSize):max_z;
[qx,qy] = meshgrid(xi,yi);
qz = F(qx,qy);
F = TriScatteredInterp(xx,yy,C);
qc = F(qx,qy);
figure
surf(qx,qy,qz,qc);
axis image
This works really well for convex and concave objects but ends in this for the cylinder:
Can anybody help me as to how to achieve a nicer plot?
Have you tried Delaunay triangulation?
http://www.mathworks.com/help/matlab/ref/delaunay.html
load seamount
tri = delaunay(x,y);
trisurf(tri,x,y,z);
There is also TriScatteredInterp
http://www.mathworks.com/help/matlab/ref/triscatteredinterp.html
ti = -2:.25:2;
[qx,qy] = meshgrid(ti,ti);
qz = F(qx,qy);
mesh(qx,qy,qz);
hold on;
plot3(x,y,z,'o');
I think what you are loking for is the Convex hull function. See its documentation.
K = convhull(X,Y,Z) returns the 3-D convex hull of the points (X,Y,Z),
where X, Y, and Z are column vectors. K is a triangulation
representing the boundary of the convex hull. K is of size mtri-by-3,
where mtri is the number of triangular facets. That is, each row of K
is a triangle defined in terms of the point indices.
Example in 2D
xx = -1:.05:1; yy = abs(sqrt(xx));
[x,y] = pol2cart(xx,yy);
k = convhull(x,y);
plot(x(k),y(k),'r-',x,y,'b+')
Use plot to plot the output of convhull in 2-D. Use trisurf or trimesh to plot the output of convhull in 3-D.
A cylinder is the collection of all points equidistant to a line. So you know that your xx, yy and zz data have one thing in common, and that is that they all should lie at an equal distance to the line of symmetry. You can use that to generate a new cylinder (line of symmetry taken to be z-axis in this example):
% best-fitting radius
% NOTE: only works if z-axis is cylinder's line of symmetry
R = mean( sqrt(xx.^2+yy.^2) );
% generate some cylinder
[x y z] = cylinder(ones(numel(xx),1));
% adjust z-range and set best-fitting radius
z = z * (max(zz(:))-min(zz(:))) + min(zz(:));
x=x*R;
y=y*R;
% plot cylinder
surf(x,y,z)
TriScatteredInterp is good for fitting 2D surfaces of the form z = f(x,y), where f is a single-valued function. It won't work to fit a point cloud like you have.
Since you're dealing with a cylinder, which is, in essence, a 2D surface, you can still use TriScatterdInterp if you convert to polar coordinates, and, say, fit radius as a function of angle and height--something like:
% convert to polar coordinates:
theta = atan2(yy,xx);
h = zz;
r = sqrt(xx.^2+yy.^2);
% fit radius as a function of theta and h
RFit = TriScatteredInterp(theta(:),h(:),r(:));
% define interpolation points
stepSize = 0.1;
ti = min(theta):abs(stepSize):max(theta);
hi = min(h):abs(stepSize):max(h);
[qx,qy] = meshgrid(ti,hi);
% find r values at points:
rfit = reshape(RFit(qx(:),qy(:)),size(qx));
% plot
surf(rfit.*cos(qx),rfit.*sin(qx),qy)

Visualizing a toroidal surface in Matlab

I have a problem which is twofold:
How do I plot a toroidal surface in MATLAB, given a major radius R and a minor radius a? To avoid confusion, it is the toroidal/poloidal coordinate system, illustrated in the picture below, that I'm talking about.
Now, in any point (phi, theta) on this surface, the minor radius will be distorted by some value that I have stored in a matrix. How do I plot this distorted surface? This might be easy once I have the answer to part 1, but this is my actual goal, so any solution to part 1 that cannot handle this is pretty useless to me.
If anyone can tell me how to make the image appear smaller here, please do =)
Addressing your first question: first you will need to define the coordinates of your torus in toroidal coordinates (seems natural!) and then convert to Cartesian coordinates, which is how MATLAB expects all plots to be constructed (unless you are making a polar plot, of course). So we start of by defining our toroidal coordinates:
aminor = 1.; % Torus minor radius
Rmajor = 3.; % Torus major radius
theta = linspace(-pi, pi, 64) ; % Poloidal angle
phi = linspace(0., 2.*pi, 64) ; % Toroidal angle
We just want a single surface of the torus, so the minor radius is a scalar. We now make a 2D mesh of these coordinates:
[t, p] = meshgrid(phi, theta);
and convert to 3D Cartesian coordinates using the formulas given on the Wikipedia page linked to in the question:
x = (Rmajor + aminor.*cos(p)) .* cos(t);
y = (Rmajor + aminor.*cos(p)) .* sin(t);
z = aminor.*sin(p);
Now we have our torus defined in 3D, we can plot it using surf:
surf(x, y, z)
axis equal
Edit: To address your second question, it depends how you have your distortions stored, but say you have a matrix defined at each toroidal and poloidal point, you will just have to multiply the constant that is the minor radius by the distortion. In the following I create a distortion matrix that is the same dimensions as my toroidal and poloidal angle coordinate matrices and that is normally distributed about a mean of 1 with a FWHM of 0.1:
distortion = 1. + 0.1 * randn(64, 64);
x = (Rmajor + aminor .* distortion .*cos(p)) .* cos(t);
y = (Rmajor + aminor .* distortion .* cos(p)) .* sin(t);
z = aminor.* distortion .* sin(p);
surf(x, y, z)
The result of which is:
You can do this with surf - just create matrices with the x,y,z coordinates. The page you linked to has the trig equations to do this (they are exactly what you'd come up with on your own - I wrote the code below before checking your link).
R = 10;
a = 3;
tx=nan(41,21);
ty=nan(41,21);
tz=nan(41,21);
for j=1:21
for i=1:41
phi = (i-1)*2*pi/40;
theta = (j-1)*2*pi/20;
tx(i,j)= cos(phi) * (R+cos(theta)*a);
ty(i,j)= sin(phi) * (R+cos(theta)*a);
tz(i,j)= sin(theta)*a;
end
end
figure
surf(tx,ty,tz)
axis equal
To distort the surface, replace the constant a with a matrix of the desired minor radius values, and index into that matrix - i.e. tz(i,j) = sin(theta)*distortion(i,j) (but in all dimensions, obviously).

MATLAB - Plot a Function Currently Expressed in Spherical Coordinates

I have a function expressed in spherical coordinates:
f(r,theta,phi) = 4*exp(-r)*cos(theta)*sin(phi)
I'd like to plot this in MATLAB in these ways:
R3
R2 Contour Plot (x-y plane or x-z plane or y-z plane)
Is there a straightforward way to do this?
Just do the conversion and plot in Cartesian coordiantes:
f = #(r, theta, phi) 4*exp(-r).*cos(theta).*sin(phi)
[XX YY ZZ] = meshgrid(x_range, y_range, z_range)
% R = sqrt(XX.^2 + YY.^2 + ZZ.^2)
% Th = acos(XX./YY)
% Phi = acos(ZZ./R)
% This is faster. . . and significantly more correct. See the comments below.
[Th,Phi,R] = cart2sph(XX,YY,ZZ)
fvals = f(R, Th, Phi)
I like isosurface to visualize 3D data like this. For the 2D slice through Z=0 you could use imagesc(fvals(:,:,N)) or contour(fvals(:,:,N))
You can use sph2cart() to convert the coordinates, then use plot()/plot3() to plot the function.

matlab 3d mesh and line plotting

I need help plotting a spiral helix on a cone. For the helix:
x = tsin(6t)
y = tcos(6t)
z = t/3
...and this helix lies on the cone:
z = sqrt(x^2+y^2)/3
I need to plot the mesh plot of the cone and the 3D line plot of the helix on the same
chart.
I think you want a surface plot of the cone first. Try
[X Y] = meshgrid(-1:.01:1);
Z = sqrt(X.^2 + Y.^2)/3;
Then, plot this surface with the surf function, and set some sort of shading and transparency
surf(X,Y,Z), caxis([-1 1]), shading flat, alpha(.5);
This should make a cone shape (you can play with the colors).
Now for the helix, define the vectors as you did
t = 0:.01:1;
x = t.*cos(6*t);
y = t.*sin(6*t);
z = t/3;
Then do
hold on;
This makes it so any other plotting you do will appear on the same figure.
Then finally,
plot3(x,y,z);