2
votes

I'm trying to write a matlab code that will answer the following question:

Using functions linspace,meshgrid,surf and dot operations, plot the surface of the cones: z=sqrt(x^2+y^2) and z=-sqrt(x^2+y^2). Use the vector form of the coordinate transformation x=rcos(θ),y=rsin(θ), where 0 ≤ θ ≤ 2π and 0 ≤ r ≤ 2. Make the partition composed of 10 values of r and 22 values of θ.

So, my code looks like this:

clear all
clc

theta = linspace(0,2*pi,22); r = linspace(0,2,10);
[R,T] = meshgrid(r,theta);
x = R.*cos(T); y = R.*sin(T);
z = R;
X = [x x]; Y = [y y]; Z = [z -z];
surf(X,Y,Z);

I'm getting the following figure: enter image description here

I don't know how to explain why the upper cone is colored that way.

Is there any way to fix it? Please help, thanks!

2

2 Answers

4
votes

You are putting multiple z values for same x,y. In fact, I am surprised it even worked in this way.

Try plotting the two parts separately:

clear all
clc

theta = linspace(0,2*pi,22); r = linspace(0,2,10);
[R,T] = meshgrid(r,theta);
x = R.*cos(T); y = R.*sin(T);
z = R;
X = [x]; Y = [y]; Z = [z];
figure();
surf(X,Y,Z);

hold on;
surf(X,Y,-Z);

enter image description here

1
votes

As for explaining why it is colored this way, the answer is Z-fighting. surf creates a contiguous quadrangulation assuming a fixed grid topology. How faces are created is a hard-coded property of surf, which assumes the first two arguments to specify the points of a grid: the four grid coordinates that make up a face with index (i,j) are obtained as

[X(i); Y(j)], [X(i); Y(j+1)], [X(i+1); Y(j)], [X(i+1); Y[(j+1)]

for i in the range 1:length(X)-1 and j in 1:length(Y)-1.

The way coordinates are given in the question, additional degenerate triangle-shaped quads are generated connecting the upper boundary edges of the cone with z > 0 with the origin. These faces overlap more or less exactly with the quadrangular patches that represent the positive half of the cone: Rounding errors in the coordinates of the smaller quads result in imperfect alignment with the triangular patches, which in turn causes irregularities for the depth test involved when drawing the patches.

You can easily see these additional faces when flipping the order of coordinates for the second cone around, which results in an additional "cylinder" built from quads that connect corresponding boundary edges:

surf([x fliplr(x)], [y fliplr(y)], [z -fliplr(z)]);
alpha 0.5

Cone with extra quads

Alternatively, the original problem stated in the question can be solved with a single call to surf by flipping the upper half around, drawing the whole figure from top to bottom, and (optionally) skipping the redundant columns of zeros, which would result in degenerate patches with all coordinates zero:

surf([fliplr(x) x(:,2:end)], [fliplr(y) y(:,2:end)], [fliplr(z) -z(:,2:end)]);