remove sidewalls from surface plots

3 visualizaciones (últimos 30 días)
Bernhard Stroebel
Bernhard Stroebel el 22 de Jun. de 2012
Comentada: Theo el 17 de Nov. de 2014
Hi, the quad mesh algorithm underlying the shaded surface plot 'surf(x,y,z,c)' creates unnatural sidewalls at height discontinuities of natural 3d objects. Is there a way to remove these sidewalls, e.g. by making them transparent?

Respuesta aceptada

Teja Muppirala
Teja Muppirala el 22 de Jun. de 2012
There are several ways, for example by replacing points with NaN, but they often give mixed results as far as appearance. The code below is another way to do it. This method is not simple, but it should look decent for most discontinuities. It involves looking at each face in turn and if the slope of the face exceeds some threshold, set it's alpha to zero.
I hope someone can come up with something a bit easier.
[X,Y] = ndgrid(linspace(-1,1,51));
Z = atan2(Y,X) + 3*round(atan2(Y,X)/2.5);
% For comparison
figure;
surf(X,Y,Z);
% Convert the "surf" into a "patch"
figure;
h = surf(X,Y,Z);
hp = patch(surf2patch(h));
delete(h);
V = get(hp,'Vertices');
F = get(hp,'Faces');
% Set the Alpha to be zero when the "slope" of a face is beyond a threshold
A = ones(prod(size(Z)-1),1);
thresh = 1.0;
for n = 1:size(F,1)
z = V(F(n,:),3);
dz = max(max(abs(bsxfun(@minus,z,z'))));
if dz > thresh;
A(n) = 0;
end
end
set(hp,'FaceVertexAlphaData',A,'edgealpha','flat');
shading faceted;
alpha flat
  2 comentarios
Bernhard Stroebel
Bernhard Stroebel el 25 de Jun. de 2012
Hi Teja,
thanks a lot for the prompt and enlightening answer. I have meanwhile tried a slightly different solution which seems easier to me:
function d=saltus(z)
%map z discontinuities of a surface z(x,y).
%d = saltus(z)is the maximum absolute difference along the edges of each
%four-sided patch representing the surface z. The number of rows and
%columns of d is one less than those of z. If d exceeds some threshold,
%a discontinuity of z (a "saltus") can be assumed. In this case, the patch
%can be made transparent, to avoid sidewalls in the surf plot.
if ndims(z) ~= 2,error('input variable must be a matrix'),end
dx = abs(diff(z,1,2));%absolute differences along the x edges
dx = max(dx(1:end-1,:),dx(2:end,:));%max of x differences for each patch
dy = abs(diff(z,1,1));%absolute differences along the y edges
dy = max(dy(:,1:end-1),dy(:,2:end));%max of y differences for each patch
dxy = max(dx,dy);%maximum of all diffenences along the edges of each patch
d = zeros(size(dxy));
d(1:end-1,1:end-1) = dxy(2:end,2:end);%This shift is needed, reason unknown
[X,Y] = ndgrid(linspace(-1,1,51));
Z = atan2(Y,X) + 3*round(atan2(Y,X)/2.5);
% For comparison
figure(1);
surf(X,Y,Z);% Convert the "surf" into a "patch"
figure(2);
s=saltus(Z);
surf(X,Y,Z,'AlphaData',uint8(s<1),'FaceAlpha','flat');
There seem to remain some problems at the margins of the image, probably due to an error with the 'FaceAlpha' 'flat' property. (I am still using MATLAB 2006R). Anyway, the result looks great, thanks again!
Bernhard
Theo
Theo el 17 de Nov. de 2014
Bernard, I tried to give your solution a shot, but the last command
surf(X,Y,Z,'AlphaData',uint8(s<1),'FaceAlpha','flat');
doesn't seem to change anything (the s matrix looks okay). Do you know whether there was a chance in the FaceAlpha implementation so that this no longer works? My current version of Matlab is R2014b.
The solution by Teja seems to work but requires conversion to patches.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Surface and Mesh Plots en Help Center y File Exchange.

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by