function hh = pie3(x,varargin)
%PIE3   3-D pie chart.
%   PIE3(X) draws a 3-D pie plot of the data in the vector X.  The
%   values in X are normalized via X/SUM(X) to determine the area of
%   each slice of pie.  If SUM(X) <= 1.0, the values in X directly
%   specify the area of the pie slices.  Only a partial pie will be
%   drawn if SUM(X) < 1.
%
%   H = PIE3(X,EXPLODE) is used to specify slices that should be 
%   pulled out from the pie.  The vector EXPLODE must be the same size 
%   as X.  The slices where EXPLODE is non-zero will be pulled out.
%
%   H = PIE3(...,LABELS) is used to label each pie slice with cell
%   array LABELS.  LABELS must be the same size as X and can only contain
%   strings.
%
%   H = PIE3(...) returns a vector containing patch, surface, and text
%   handles. 
%
%   Example
%      pie3([2 4 3 5],[0 1 1 0],{'North','South','East','West'})
%
%   See also PIE.

%   Clay M. Thompson 3-3-94
%   Copyright (c) 1984-98 by The MathWorks, Inc.
%   $Revision: 1.14 $  $Date: 1998/06/22 15:03:20 $

txtlabels={};

if nargin==0, error('Not enough input arguments.');
elseif nargin==1, explode = zeros(size(x));
elseif nargin==2 & isnumeric(varargin{1}),
   explode = varargin{1};
   explode = explode(:); % Make sure it is a vector
elseif nargin==2 & iscell(varargin{1}),
   explode = zeros(size(x));
   txtlabels = varargin{1};
elseif nargin==3 & iscell(varargin{2}),
   explode = varargin{1};
   explode = explode(:); % Make sure it is a vector
   txtlabels = varargin{2};
else error('Too many arguments or invalid string cell array.'); end

x = x(:); % Make sure it is a vector

if sum(x) > 1+sqrt(eps), x = x/sum(x); end

if length(txtlabels)~=0 & length(x)~=length(txtlabels),
  error('Cell array of strings must be the same length as X.');
end
if length(x) ~= length(explode),
  error('X and EXPLODE must be the same length.');
end

ax = newplot;
next = lower(get(ax,'NextPlot'));
hold_state = ishold;

theta0 = pi/2;
maxpts = 100;
zht = .35;

h = [];
for i=1:length(x)
  n = ceil(maxpts*x(i));
  r = [0;ones(n+1,1);0];
  theta = theta0 + [0;x(i)*(0:n)'/n;0]*2*pi;
  [xtext,ytext] = pol2cart(theta0 + x(i)*pi,1.25);
  [xx,yy] = pol2cart(theta,r);
  if explode(i),
    [xexplode,yexplode] = pol2cart(theta0 + x(i)*pi,.1);
    xtext = xtext + xexplode;
    ytext = ytext + yexplode;
    xx = xx + xexplode;
    yy = yy + yexplode;
  end
  theta0 = max(theta);
  if x(i)<.01,
    lab = '< 1';
  else
    lab = int2str(round(x(i)*100));
  end
  z = zht(ones(size(xx)));
  h = [h,patch('XData',xx,'YData',yy,'Zdata',zeros(size(xx)),...
               'CData',i*ones(size(xx)),'FaceColor','Flat'), ...
         surface([xx,xx],[yy,yy],[zeros(size(xx)),z], ...
              i*ones(size(xx,1),2)), ...
         patch('XData',xx,'YData',yy,'Zdata',z,...
         'CData',i*ones(size(xx)),'FaceColor','Flat')];
  if length(txtlabels)~=0,
     h = [h,text(xtext,ytext,zht,txtlabels{i},'HorizontalAlignment','center')];
  else
     h = [h,text(xtext,ytext,zht,[lab,'%'],'HorizontalAlignment','center')];
  end
end

if ~hold_state, 
  view(3), set(ax,'NextPlot',next); axis off, axis image
  set(ax,'xlim',[-1.2 1.2],'ylim',[-1.2 1.2])
end

if nargout>0, hh = h; end
