Reputation: 690
I want to plot a two-dimensional function of the polar coordinates r
and theta
in three-dimensional cartesian coordinates. I have that (sorry about bad maths formatting, LaTeX not compatible, it seems)
f(r,theta) = r/2 * (cos(theta - pi/4) + sqrt(1 + 1/2 * cos(2*theta)))
Converting r
and theta
to cartesian coordinates
x = r * cos(theta), y = r * sin(theta)
Further, the domain is -1<r<1
and 0<theta<2 * pi
, which I define by
r = -1:2/50:1;
and
theta = 0:2*pi/50:2*pi;
giving me two vectors of the same dimensions.
I can define the x
and y
values used for plotting as row vectors by
x = r. * cos(theta);
and
y = r. * sin(theta);
So now I need to define the z
values, which will depend on the values of x
and y
. I thought I should make a 101x101 where each matrix element contains a data point of the final surface. But how should I do this? I thought about using a double for
loop:
for i=1:numel(r)
for j=1:numel(theta)
z(i,j) = r(i)/2 .* cos(theta(j) - pi/4) + r(i).*sqrt(1 + 1/2 * cos(2.*theta(j)));
end
end
Then simply surf(z)
While this definitely gives me a surface, it gives me the incorrect surface! I don't know what is happening here. The incorrect surface is given in Figure 1, while the correct one is given in Figure 2. Can anyone help me out? For reference, the correct surface was plotted with GeoGebra, using
A = Function[<expression 1>, <Expresison 2>, <Expression 3>, <var 1>, <start>, <stop>, <var 2>, <start>, <stop>]
Figure 1. Incorrect surface.
Figure 2. Correct surface.
Upvotes: 2
Views: 388
Reputation: 106
As others have said, you can use meshgrid
to make this work.
Here's your example using gridded r
and theta
and an anonymous function to replace the double loop:
r = -1:2/50:1;
theta = 0:2*pi/50:2*pi;
% define anonymous function f(r,theta)
f = @(r,theta) r/2 .* (cos(theta - pi/4) + sqrt(1 + 1/2 .* cos(2.*theta)));
% generate grids for r and theta
[r, theta] = meshgrid(r,theta);
% calculate z from gridded r and theta
z = f(r,theta);
% convert r,theta to x,y and plot with surf
x = r.*cos(theta);
y = r.*sin(theta);
surf(x,y,z);
Upvotes: 1
Reputation: 4262
You need to use meshgrid
to get matrix coordinates if you want to use surf
. Taking your x
and y
(lower case), call
[X,Y] = meshgrid(x,y);
Then X
and Y
(upper case) will have the same values as you gave it, but laid out in the two-dimensional array as expected by surf
. Loop over the indices here and compute your Z
, which should have all(size(Z) == size(X))
.
https://www.mathworks.com/help/matlab/ref/meshgrid.html
Upvotes: 0