function [myhandle, x_circle, y_circle] = circles(radii,centers,varargin)
% Plot multiple circles as a single line object...very fast, very efficient!
%
% circles(radii,centers) plots circles of radius values specified by RADII,
% at centers specified by CENTERS.
% circles(radii,centers,'PropertyName',propertyvalue,...)
% Will accept as inputs any valid properties
% accepted by PLOT.
% [h,x_circle,y_circle] = circles(...)
% Also provides handle to (single-plot) circle
% object, plotted x-values, and plotted y-values.
%
% NOTE: x- and y- values for each circle will be terminated
% by NaNs in the output x_circle, y_circle vectors!
%
% INPUTS:
% r A vector of n radii
% centers An n x 2 array of x,y center coordinates
%
% Optional Parameter-Value Pairs:
% Resolution: Stepsize for plotting from theta = 0 to
% theta = 360 (Default = 1)
% Any valid PV-pair accepted by PLOT
%
% EXAMPLES
%
%%% Example 1: Plot a single circle:
%
% r = 10; c = [3,5];
% circles(r,c,'color','g','linewidth',2)
%
%
%%% Example 2: Plot 200 random-sized and centered circles
%%% (Note: this is MUCH faster than drawing them one-by-one,
%%% but the speed gain is at the cost of getting a single
%%% line-object handle rather than a vector of them.)
%
% tic;
% n = 1000;
% r = rand(n,1)*100;
% c = rand(n,2)*300;
% [h,xs,ys] = circles(r,c,...
% 'color','r','linewidth',1,'resolution',1);
% axis equal
% t_allAtOnce = toc
%
%
%%% Example 3: (FOR COMPARISON ONLY!!!)
%%% (Using the r,c generated above:)
%
% tic;
% for ii = 1:numel(r)
% circles(r(ii),c(ii,:),'color','r','linewidth',1,'resolution',1);
% end
% t_oneAtATime = toc
% fprintf('Plotting %d circles was %0.2f x faster as a single object!\n',n,t_oneAtATime/t_allAtOnce)
%
% Written by Brett Shoelson, PhD 8/3/98.
% brett.shoelson@mathworks.com
%
% MODIFICATIONS:
% Vectorized 11/20/01
% Arg for resolution 03/08/08
% 12/06/11 Modified as CIRCLES to accept multiple radii and centers,
% and to vectorize all as a single line object.
%
% Copyright 2012 The MathWorks, Inc.
if nargin < 2
error('CIRCLES requires a minimum of 2 input arguments.');
end
if rem(nargin,2) ~= 0
% Odd number of inputs!
error('CIRCLES: Parameter-Values must be entered in valid pairs')
end
[PVs,resolution] = parsePVs(varargin);
theta=0:resolution:360;
x_circle = bsxfun(@times,radii,cos(theta*pi/180));
x_circle = bsxfun(@plus,x_circle,centers(:,1));
x_circle = cat(2,x_circle,nan(size(x_circle,1),1));
x_circle = x_circle';
x_circle = x_circle(:);
y_circle = bsxfun(@times,radii,sin(theta*pi/180));
y_circle = bsxfun(@plus,y_circle,centers(:,2));
y_circle = cat(2,y_circle,nan(size(y_circle,1),1));
y_circle = y_circle';
y_circle = y_circle(:);
oldhold = ishold;
hold on;
myhandle = plot(x_circle,y_circle);
% Apply PV pairs
for ii = 1:2:numel(PVs)
set(myhandle,PVs{ii},PVs{ii+1})
end
if ~oldhold,hold off;end
if nargout < 3
clear y_circle
end
if nargout < 2
clear x_circle
end
if nargout < 1
clear myhandle
end
function [PVs,resolution] = parsePVs(PVs)
resolution = 1;
for ii = 1:2:numel(PVs)
if strcmpi(PVs{ii},'resolution')
resolution = PVs{ii+1};
PVs = PVs(setdiff(1:numel(PVs),[ii,ii+1]));
return
end
end