[r,t] = meshgrid(linspace(0,2*pi,361),linspace(0,pi,361));
[x,y]=pol2cart(sin(t)*cos(r),sin(t)*sin(r));
%[x,y]=pol2cart(r,t);
surf(x,y);
I played with this addon but trying to find an default function to for this. How can I do the 3D-polar-plot?
I am trying to help this guy to vizualise different integrals here.
There are several problems in your code:
You are already converting spherical coordinates to cartesian coordinates with the sin(theta)*cos(phi) and sin(theta)*sin(phi) bit. Why are you calling pol2cart on this (moreover, we're not working in polar coordinates!)?
As natan points out, there is no third dimension (i.e. z) in your plot. For unity radius, r can be omitted in the spherical domain, where it is completely defined by theta and phi, but in the cartesian domain, you have all three x, y and z. The formula for z is z = cos(theta) (for unit radius).
You didn't read the documentation for surf, which says:
surf(Z,C) plots the height of Z, a single-valued function defined over a geometrically rectangular grid, and uses matrix C, assumed to be the same size as Z, to color the surface.
In other words, your surf(x,y) line merely plots the matrix x and colors it using y as a colormap.
Here's the above code with the mistakes fixed and plotted correctly:
[f,t] = meshgrid(linspace(0,2*pi,361),linspace(0,pi,361));
x = sin(t)*cos(f);
y = sin(t)*sin(f);
z = cos(t);
surf(x,y,z)
Related
MATLAB's surf command allows you to pass it optional X and Y data that specify non-cartesian x-y components. (they essentially change the basis vectors). I desire to pass similar arguments to a function that will draw a line.
How do I plot a line using a non-cartesian coordinate system?
My apologies if my terminology is a little off. This still might technically be a cartesian space but it wouldn't be square in the sense that one unit in the x-direction is orthogonal to one unit in the y-direction. If you can correct my terminology, I would really appreciate it!
EDIT:
Below better demonstrates what I mean:
The commands:
datA=1:10;
datB=1:10;
X=cosd(8*datA)'*datB;
Y=datA'*log10(datB*3);
Z=ones(size(datA'))*cosd(datB);
XX=X./(1+Z);
YY=Y./(1+Z);
surf(XX,YY,eye(10)); view([0 0 1])
produces the following graph:
Here, the X and Y dimensions are not orthogonal nor equi-spaced. One unit in x could correspond to 5 cm in the x direction but the next one unit in x could correspond to 2 cm in the x direction + 1 cm in the y direction. I desire to replicate this functionality but drawing a line instead of a surf For instance, I'm looking for a function where:
straightLine=[(1:10)' (1:10)'];
my_line(XX,YY,straightLine(:,1),straightLine(:,2))
would produce a line that traced the red squares on the surf graph.
I'm still not certain of what your input data are about, and what you want to plot. However, from how you want to plot it, I can help.
When you call
surf(XX,YY,eye(10)); view([0 0 1]);
and want to get only the "red parts", i.e. the maxima of the function, you are essentially selecting a subset of the XX, YY matrices using the diagonal matrix as indicator. So you could select those points manually, and use plot to plot them as a line:
Xplot = diag(XX);
Yplot = diag(YY);
plot(Xplot,Yplot,'r.-');
The call to diag(XX) will take the diagonal elements of the matrix XX, which is exactly where you'll get the red patches when you use surf with the z data according to eye().
Result:
Also, if you're just trying to do what your example states, then there's no need to use matrices just to take out the diagonal eventually. Here's the same result, using elementwise operations on your input vectors:
datA = 1:10;
datB = 1:10;
X2 = cosd(8*datA).*datB;
Y2 = datA.*log10(datB*3);
Z2 = cosd(datB);
XX2 = X2./(1+Z2);
YY2 = Y2./(1+Z2);
plot(Xplot,Yplot,'rs-',XX2,YY2,'bo--','linewidth',2,'markersize',10);
legend('original','vector')
Result:
Matlab has many built-in function to assist you.
In 2D the easiest way to do this is polar that allows you to make a graph using theta and rho vectors:
theta = linspace(0,2*pi,100);
r = sin(2*theta);
figure(1)
polar(theta, r), grid on
So, you would get this.
There also is pol2cart function that would convert your data into x and y format:
[x,y] = pol2cart(theta,r);
figure(2)
plot(x, y), grid on
This would look slightly different
Then, if we extend this to 3D, you are only left with plot3. So, If you have data like:
theta = linspace(0,10*pi,500);
r = ones(size(theta));
z = linspace(-10,10,500);
you need to use pol2cart with 3 arguments to produce this:
[x,y,z] = pol2cart(theta,r,z);
figure(3)
plot3(x,y,z),grid on
Finally, if you have spherical data, you have sph2cart:
theta = linspace(0,2*pi,100);
phi = linspace(-pi/2,pi/2,100);
rho = sin(2*theta - phi);
[x,y,z] = sph2cart(theta, phi, rho);
figure(4)
plot3(x,y,z),grid on
view([-150 70])
That would look this way
I have a rational polynomial function. I find zeros of numerator and denominator of it. Now I want to draw this function and I do it with meshgrid and mesh command in matlab. How can I draw a circle in this shape? I add my result figure at first and second figure is an image that I want to be like that( draw red circle).
Create x and y for your circle:
r = 1;
theta = 0:0.1:2*pi;
x = r*cos(theta);
y = r*sin(theta);
Get the value of your function at the x and y's and plot a line in 3D with the values:
z = f(x,y);
plot3(x,y,z);
The final result may have some artefacts where the line crosses in and out of the surface. If you are not so concerned about the accuracy in the plot add a very small value to z to "lift" it above the surface.
I'm trying to plot a 2 dimensional signal on a specific plane in a 3d model. I have the matrix:
xyzp (nx3)
that contains all the points which are closest to the plane (e.g. when the plane is in the z direction, all the z coordinates are fairly similar).
and I have a vector:
signal (nx1)
that contains a value for each point in xyzp.
when I use:
"surf([xyzp(:,[1,2]),signal)" or "mesh([xyzp(:,[1,2]),signal])"
The plot I get doesn't look at all like the intersection of the plane with the model from any angle (I expected "view(2)" to show the signal in the Z direction), so I assume I didn't use the plot function correctly.
Can anyone show me an example? For instance - A circle on an xy plane with some random signal indicated by color
surf and mesh can be used when the points form a rectangular grid on the xy plane.
In the general case (points are arbitrarily placed), you can use scatter3. For purposes of illustration, consider the following example xyzp and signal:
[x y] = ndgrid(-1:.01:1);
x = x+.3*y; %// example values which do not form a rectangular grid
z = x+y; %// example z as a function of x, y
xyzp = [x(:) y(:) z(:)];
signal = z(:)+x(:)-y(:); %// example values
Then
scatter3(xyzp(:,1), xyzp(:,2), xyzp(:,3), 1, signal, '.');
produces the following figure.
Since scatter3 plots each point separately, the picture is not as smooth as it would be with surf. But this seems hard to improve if the coordinates do not a have any "structure" (as surf requires) .
I am trying to fit a B-spline to a set of ordered discrete data points which represent pixels of a contour extracted from an image.
While the below code works fine for some simple shapes, but not for others (please see attached image for examples). Why does this happen, and what would be a better way to approach this problem?
I am quite new to differential geometry, appreciate any insights or inputs. Thanks.
% data contains two columns representing x,y coordinates of pixels
x = data(:, 1);
y = data(:, 2);
plot(x, y, 'bo');
fittedmodel = fit(x, y, 'cubicinterp');
plot(fittedmodel, 'r-');
What went wrong?
You have two sets of numbers x and y with the same number of elements in both sets.
You assume:
a. That there is a function f such that f( x_i ) = y_i for all pairs x_i,y_i in your sets.
b. That the points in the set are ordered: that is, if you follow the curve of f(x) then x_i "comes before" x_{i+1}.
While these assumptions hold for the "correct fit" example you have. They are no longer valid for the "incorrect fit" example.
As you can see for yourself, the input contour on the top cannot be expressed as y = f(x) since there are values of x for which there are two possible corresponding values of y (see the definition of mathematical function). The fit you got is the closest thing to a mathematical function y = f(x) that can be given the pairs x,y you gave (the red curve has the property of each x having only one y value).
What can you do?
In most cases when you try and fit a 2D curve you search for a parametric curve: that is, you introduce an auxilary parameter t such that each point along the curve can be represented as [x(t), y(t)] for some 0<=t<=1.
Now, if assumption b holds (and by looking at your examples, I'm not certain it is), what you can do is
t = linspace( 0, 1, numel(x) ); % define the parameter t
fitX = fit( t, x, 'cubicinterp'); % fit x as a function of parameter t
fitY = fit( t, y, 'cubicinterp'); % fit y as a function of parameter t
plot( fitX, fitY, 'r-' ); % plot the parametric curve
I am trying to create a 2-D grid from a vector.
So, for example I have:
x = 1:1:10;
z = 2:2:20;
Now, I want to create a grid which has x on both side of the grid cell and z as grid cell value.
I tried doing it as :
[X,Y] = meshgrid(x, x);
newZ = griddata(x, x ,z, X, Y);
But this gives me error:
The underlying triangulation is empty - the points may be
collinear.
Need help solving this.
In a high level, griddata() takes a 2d surface with variable z-value at each point as the first part of the input, and the query points as the second part of the input. To be more specific, when we look into the definition of the function:
vq = griddata(x,y,v,xq,yq)
x and y specifies the range of x and y values, v is like z-value in a plane, and xq and yq together are query points. Here, v (in your case, z) is expected to be a 2d matrix, to be more specific, the size of v is [length(x), length(y)], whereas in your case, you put z as a vector. Matlab generates the warning since the size doesn't match.
For your reference: http://www.mathworks.com/help/matlab/ref/griddata.html?refresh=true