2
votes

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>]

Incorrect surface

Figure 1. Incorrect surface.

Correct surface

Figure 2. Correct surface.

2
You're trying to convert from polar (spherical) to cartesian? Or cylindrical to cartesian? - toshiomagic
Try to see if this helps you. I succeeded in plotting only the upper half of the surface with it. - EBH

2 Answers

1
votes

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);
0
votes

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