No BSD License  

Highlights from
gcircle

image thumbnail
from gcircle by Daniel Claxton
GCIRCLE Interactively draw a circle similar to gline

gcircle(fig)
function h = gcircle(fig)
% GCIRCLE Interactively draw a circle similar to gline
%   GCIRCLE(FIG) draws a circle by clicking the mouse at the center and at
%   some distance away in the figure FIG.
% 
%   H = GCIRCLE(FIG) Returns the handle to the line.
% 
%   GCIRCLE with no input arguments draws in the current figure.


if nargin<1, 
  draw_fig = gcf;
  fig = draw_fig;
  s = 'start'; 
end

if isstr(fig), 
   s = fig;
   draw_fig = gcbf;
   ud = get(draw_fig,'UserData');
else
   s = 'start';
   draw_fig = fig; 
end

ax = get(draw_fig,'CurrentAxes');
if isempty(ax)
   ax = axes('Parent',draw_fig);
end

gcacolor = get(ax,'Color');

switch s
   case 'start'
   oldtag = get(draw_fig,'Tag');
   figure(draw_fig);
   if any(get(ax,'view')~=[0 90]), 
     set(draw_fig, 'Tag', oldtag);
     error('stats:gcircle:NotTwoDimensional','GCIRCLE works only for 2-D plots.');
   end
   
   % Create an invisible line to preallocate the xor line color.
   xlimits = get(ax,'Xlim');
   x = (xlimits + flipud(xlimits))./2;
   ylimits = get(ax,'Ylim');
   y = (ylimits + flipud(ylimits))./2;
   hline = line(x,y,'Parent',ax,'Visible','off','eraseMode','normal');
   hcirc = line(x,y,'Parent',ax,'Visible','off','eraseMode','normal');

   bdown = get(draw_fig,'WindowButtonDownFcn');
   bup = get(draw_fig,'WindowButtonUpFcn');
   bmotion = get(draw_fig,'WindowButtonMotionFcn');
   oldud = get(draw_fig,'UserData');
   set(draw_fig,'WindowButtonDownFcn','gcircle(''down'')')
   set(draw_fig,'WindowButtonMotionFcn','gcircle(''motion'')')
   set(draw_fig,'WindowButtonupFcn','')
 
   ud.hline = hline;
   ud.hcirc = hcirc;
   ud.pts = [];
   ud.buttonfcn = {bdown; bup; bmotion};
   ud.oldud = oldud;
   ud.oldtag = oldtag;
   ud.xlimits = xlimits;
   ud.ylimits = ylimits;
   set(draw_fig,'UserData',ud);
   if nargout == 1
      h = hcirc;
   end

case 'motion'
   set(draw_fig,'Pointer','crosshair');

   if isempty(ud.pts);
      return;
   end

   set(ud.hline,'Xdata',ud.pts(:,1),'Ydata',ud.pts(:,2),'eraseMode','normal', ...
        'linestyle','-.', 'linewidth', 1, 'Color',1-gcacolor,'Visible','on');
   
   [x,y,r] = circle(ud.pts(:,1),ud.pts(:,2));
   udcirc.xc = ud.pts(1,1); 
   udcirc.yc = ud.pts(1,2);
   udcirc.r = r;
   set(ud.hcirc,'Xdata',x,'Ydata',y,'eraseMode','normal', ...
        'linestyle','-', 'linewidth', 1.5, 'Color',1-gcacolor,'Visible','on',...
        'UserData',udcirc);
   
   Pt2 = get(ax,'CurrentPoint'); 
   Pt2 = Pt2(1,1:2);    
   ud.pts(2,:) = Pt2;

   set(draw_fig,'UserData',ud);

case 'down'   
   Pt1 = get(ax,'CurrentPoint'); 
   ud.pts = [Pt1(1,1:2); Pt1(1,1:2)];
   set(ud.hline,'Xdata',ud.pts(:,1),'Ydata',ud.pts(:,2),'eraseMode','normal', ...
        'linestyle','--', 'linewidth', 1, 'Color',1-gcacolor,'Visible','on');
    
   set(ud.hcirc,'Xdata',ud.pts(:,1),'Ydata',ud.pts(:,2),'eraseMode','normal', ...
        'linestyle','-', 'linewidth', 1.5, 'Color',1-gcacolor,'Visible','on');

   set(draw_fig,'WindowButtonDownFcn','gcircle(''down2'')','UserData',ud)
   
case 'down2'
   delete(ud.hline);
   bfcns = ud.buttonfcn;
   set(draw_fig,'windowbuttondownfcn',bfcns{1},'windowbuttonupfcn',bfcns{2}, ...
         'windowbuttonmotionfcn',bfcns{3},'Pointer','arrow', ...
		 'Tag',ud.oldtag,'UserData',ud.oldud)

otherwise
   error('stats:gcircle:BadCallBack','Invalid call-back.');
end


% Make sure the axis limits don't change
set(ax,'xlim',ud.xlimits,'ylim',ud.ylimits);


function [xout,yout,r] = circle(x,y)
xc = x(1);
yc = y(1);

r = sqrt(diff(x)^2 + diff(y)^2);
npts = 1000;
res = 2*pi/(npts-1);
theta = 0:res:2*pi;

xout = r*cos(theta) + xc;
yout = r*sin(theta) + yc;

Contact us at files@mathworks.com