ring (annulis) patch?

Dear friends,
How do I make a 2D ring (annulus) patch? Is it possible to make it as a single patch with a single object handle?
I want plot several 2D objects in a figure. The objects behind the ring should be visible trough the hole, and I want to control the properties of the ring, e.g. with respect to transperancy, color and line style.
Sincerely, Peter.

 Respuesta aceptada

Matt Fig
Matt Fig el 21 de Mzo. de 2011

2 votos

This might serve your purpose. The function creates an annulus object and allows you to set the linestyle and edgecolor while preserving the correct look of the annulus.
function [P] = annulus(r,R,xf,Xf,yf,Yf)
% Creates a annulus patch object and returns the handle. Input arguments
% are the inner radius, outer radius, inner x offset, outer x offset, inner
% y offset and outer Y offset. Changes to the edgecolor and linestyle are
% allowed, and will preserve the correct look of the annulus
t = linspace(0,2*pi,200);
x = xf + r*cos(t);
y = yf + r*sin(t);
X = Xf + R*cos(t);
Y = Yf + R*sin(t);
P = patch([x X],[y Y],[1,.5,.5],'linestyle','non','facealph',.5);
L(1) = line(x,y,'color','k');
L(2) = line(X,Y,'color','k');
axis equal
plistener(P,'edgecolor',@edgec) % listeners for changes to props.
plistener(P,'linestyle',@lnstl)
function [] = plistener(ax,prp,func)
% Sets the properties. From proplistener by Yair Altman.
psetact = 'PropertyPostSet';
hC = handle(ax);
hSrc = hC.findprop(prp);
hl = handle.listener(hC, hSrc, psetact, {func,ax});
p = findprop(hC, 'Listeners__');
if isempty(p)
p = schema.prop(hC, 'Listeners__', 'handle vector');
set(p,'AccessFlags.Serialize', 'off', ...
'AccessFlags.Copy', 'off',...
'FactoryValue', [], 'Visible', 'off');
end
hC.Listeners__ = hC.Listeners__(ishandle(hC.Listeners__));
hC.Listeners__ = [hC.Listeners__; hl];
end
function [] = edgec(varargin)
St = get(varargin{3},'edgecolor');
set(L,'color',St)
end
function [] = lnstl(varargin)
St = get(varargin{3},'linestyle');
set(varargin{3},'linestyle','none')
set(L,'linestyle',St)
end
end

6 comentarios

Walter Roberson
Walter Roberson el 21 de Mzo. de 2011
Yikes!
Matt Fig
Matt Fig el 21 de Mzo. de 2011
Yikes indeed! Yet it works, at least on 2006b and 2007b...
Matt Tearle
Matt Tearle el 21 de Mzo. de 2011
MATLAB: it's a programming environment *and* an obsessive disorder. Order your copy today!
Walter Roberson
Walter Roberson el 21 de Mzo. de 2011
@Matt Fig: I wonder if linkprop() might have been easier?
@Matt Tearle: Shouldn't that be *copies*, not *copy* ? ;-)
Peter
Peter el 21 de Mzo. de 2011
Dear Matt Fig, thanks a lot – the function is brilliant! And it taught me a lot. Sincerely, Peter.
Matt Fig
Matt Fig el 21 de Mzo. de 2011
@Walter, LINKPROP will not work as I understand it. This problem calls for the properties to NOT be identical.

Iniciar sesión para comentar.

Más respuestas (2)

Matt Tearle
Matt Tearle el 20 de Mzo. de 2011

2 votos

How's this? The patch is a single object, but you have to add the edge lines separately in this approach (otherwise you see the "branch cut" in the annulus).
% Make a plot to add the ring to
x = rand(100,1);
y = rand(100,1);
plot(x,y,'o')
% Make inner and outer boundaries
t = linspace(0,2*pi);
rin = 0.1;
rout = 0.25;
xin = 0.5 + rin*cos(t);
xout = 0.5 + rout*cos(t);
yin = 0.5 + rin*sin(t);
yout = 0.5 + rout*sin(t);
% Make patch
hp = patch([xout,xin],[yout,yin],'g','linestyle','none','facealpha',0.25);
hl1 = line(xin,yin,'color','k');
hl2 = line(xout,yout,'color','k');

6 comentarios

Peter
Peter el 20 de Mzo. de 2011
Dear Matt Tearle, thank you for your answer - it looks beautiful! This is very close to what I asked for. I guess it is impossible to make pure hollow patches … Thanks, Peter.
Walter Roberson
Walter Roberson el 20 de Mzo. de 2011
Try putting a NaN between xout and xin, and between yout and yin.
Peter
Peter el 20 de Mzo. de 2011
Dear Walter Roberson, thank you for taking your time. The NaN trick is clever! However, if I put in NaNs before and between the x and y terms ([nan,xin,nan,xout] and [nan,yin,nan,yout]), I get a single patch without face color. Do not know why the face disappeared, but I could use this patch instead of the two lines that was proposed by Matt Tearle (two handles is better than three). Sincerely, Peter.
Walter Roberson
Walter Roberson el 21 de Mzo. de 2011
I suspect this is due to the face color interpolation method that is set, especially with the leading nan (which you do not need, but a trailing nan might not hurt.) I cannot test out my speculations at the moment as I do not have graphic access right now.
Matt Tearle
Matt Tearle el 21 de Mzo. de 2011
Yes, I thought of trying it with NaN, but that seems to confuse patch -- I think it's unable to work out where the "inside" of the region is. But I feel like a total idiot for not using the same trick for the boundary line.
Anyway, Peter, what's still missing/lacking from this approach? What do you mean by "pure hollow patches"?
Peter
Peter el 21 de Mzo. de 2011
Matt Tearle, I was naive thinking that it is possible to make any geometric shape with a singe patch. From yours and others answers I conclude that it is not that simple (though I wish it was). Thank you, Peter.

Iniciar sesión para comentar.

Sean de Wolski
Sean de Wolski el 19 de Mzo. de 2011

0 votos

2d or 3d?
For the 2d case just subtract circles. Learn how to make circles here: http://matlab.wikia.com/wiki/FAQ#How_do_I_create_a_circle.3F
You could use the same logic for the 3d "donut" using a formula found on wikipedia.

1 comentario

Peter
Peter el 19 de Mzo. de 2011
Thank you for your answer! I want plot several 2D objects in a figure. The objects behind the ring should be visible trough the hole. Peter.

Iniciar sesión para comentar.

Categorías

Más información sobre Graphics Performance en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 19 de Mzo. de 2011

Community Treasure Hunt

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

Start Hunting!

Translated by