There may not be a direct way to specify the z
position of the objects returned by viscircles
, but in general there is (most of the time) a way to modify properties and position of any graphic object afterwards.
Method 1: modifying circles after creation.
If you plan to do modifications of a graphic object, the first thing to do is always to retrieve its handle
. So in your case, you would have to call viscircles
by specifying a return value (which will contain the handle
you want).:
hg = viscircles(circle_pos, circle_rad);
I do not have the Image Processing Toolbox
so I do not have access to the viscircles
function. However I read from the documentation that the handle returned is an hggroup
. An hggroup
is simply a container containing one or more handles
of more primitive graphic objects. In this case the hggroup
contains the handles of 4 lines
(your 4 circles).
The easiest way to transform all the objects in an hggroup
is to use a hgtransform
object. We will define a Translation transformation and the hgtransform
will apply it to the 4 circles (all the children of the hggroup
).
To define the translation, we will use a makehgtform
object.
Here we go:
ht = hgtransform ; % create the transform object
set(hg,'Parent',ht) ; % make it a "parent" of the hggroup
zc = max(max(Z)) ; % Find by how much we want to translate the circles on the Z axis
Tz = makehgtform('translate',[0 0 zc]) ; % create the TRANSLATION transform
set(ht,'Matrix',Tz) % apply the transformation (translation) to the hggroup/hgtransform
Done, your 4 circles should now be on top of your surface. Note that you can specify any other values for zc
(not only the max of the surface).
Method 2: DIY
In case you do not want to be reliant on the image processing toolbox, or if you do not have it at all, it is relatively easy to create circles in a 3D space by yourself.
Here is a function which will create circles in a way comparable to viscircles
but it also let you specify an optional z
coordinate for the circle centre positions.
code for circles_3D.m
:
function hg = circles_3d( pos , rad , varargin )
% get current axes handle and hold state
ax = gca ;
holdState = get(ax,'NextPlot') ; % save state to reinstate after function
set(ax,'NextPlot','add') ; % equivalent of "hold off"
tt = linspace(0,2*pi) ;
hg = hggroup(ax) ;
for k = 1:numel(rad)
c = pos(k,:) ;
r = rad(k) ;
x = c(1) + r.*cos(tt) ;
y = c(2) + r.*sin(tt) ;
z = zeros(size(x)) ;
if numel(c)==3 ; z = z + c(3) ; end
plot3(hg,x,y,z,varargin{:}) ;
end
set(ax,'NextPlot',holdState) ; % restore axes hold state
You can now call this function instead of viscircles
. I used the varargin
parameter to transfer any line
property to the circles created (so you can specify the Color
, LineWidth
, and any other typical parameter you like.
For the sake of an example, I need to recreate a surface comparable to your, with 4x "zero" poles distributed around the maxima:
pc = 0.5 ; % pole centers
pw = 0.05 ; % pole widths
% surface definition
[X,Y] = meshgrid(-5:.1:5);
R = sqrt(X.^2 + Y.^2) + eps ;
Z = sin(R)./R;
% zero surface values around the defined poles
[idxPoles] = find(abs(X)>=pc-pw & abs(X)<=pc+pw & abs(Y)>=pc-pw & abs(Y)<=pc+pw ) ;
Z(idxPoles)= 0 ;
% display
hs = surf(X,Y,Z) ; shading interp
Which produces:
Now you can simply get your circles with the circles_3D
function:
zc = max(max(Z)) ;
circle_pos = [ pc pc zc ; -pc -pc zc ; -pc +pc zc ; +pc -pc zc ] ;
circle_rad = 0.2 * ones(4,1);
h = circles_3d( circle_pos , circle_rad , 'Color','r','LineWidth',2) ;
and get:
Note that I made this function so it also return an hggroup
object containing your lines (circles). So if you want to move them later, apply the same trick than in the first part of the answer.
R^2 to R
function and surface ... – Hoki[X, Y] = meshgrid(linspace(-10, 10, 500)); surf(X, Y, X.^2 + Y.^2)
– Anti Earth