function [d,xi,yi] = roipoly(x,y,a,xi,yi)
%ROIPOLY Define polygonal region of interest (ROI).
%	[BW,Xi,Yi] = ROIPOLY prompts you to define a region of interest 
%	using the mouse.  The region of interest is returned in the 
%	binary image BW which has the same size as the current image.  
%	BW contains 0's outside the region of interest and 1's inside.  
%	Also returned are the vertices of the polygon in Xi and Yi.
%	The ROI is defined by clicking in the image to define a closed
%	polygon. Press RETURN or right mouse button (shift-click on
%	the Macintosh) when done.
%
%	BW = ROIPOLY(A,Xi,Yi) returns a binary image BW that contains 1's 
%	inside the polygon defined by the vertices (x,y) and 0's
%	outside.
%
%	BW = ROIPOLY(X,Y,A,Xi,Yi) accounts for non-default axis limits.
%
%	See also ROICOLOR.

%	Clay M. Thompson 1-28-93
%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.17 $  $Date: 1993/09/24 22:02:37 $

% Determine which IMAGE coordinate system is being used.
s = [version '    ']; k = find(s<46 & s>58);
if ~isempty(k), s = s(1:min(k)); end
[ver,count,msg,next] = sscanf(s,'%f',1);
if ver > 4.1,
  useNew = 1;
elseif ver < 4.1,
  useNew = 0;
else
  if s(next)>='a', useNew = 1; else useNew = 0; end
end
  
if nargin==0, % Get information from the current figure
  [x,y,a,hasimage] = getimage;
  if ~hasimage,
    error('The current figure must contain an image to use ROIPOLY.');
  end
  [xi,yi] = getline(gcf); % Get rect info from the user.
  xi = [xi;xi(1)]; yi = [yi;yi(1)]; % Make sure polygon is closed.

elseif nargin==1 | nargin==2 | nargin==4,
  error('Wrong number of input arguments.');

elseif nargin==3,
  yi = a(:); a = x; xi = y(:); 
  [m,n] = size(a);
  if useNew,
    x = [1 n]; y = [1 m];
  else
    x = [1 n+1]; y = [1 m+1];
  end
else
  xi = xi(:); yi = yi(:);
end

if length(xi)~=length(yi), error('XI and YI must be the same length.'); end
if length(xi)==0, error('XI and YI can''t be empty.'); end

% Make sure xi and yi don't form a closed polygon (closedness is implied).
n = length(xi); 
if xi(n)==xi(1) & yi(n)==yi(1), xi = xi(1:n-1); yi = yi(1:n-1); end

[m,n] = size(a);

if max(size(a))==1, d = a; return, end

xmin = min(min(x)); xmax = max(max(x));
ymin = min(min(y)); ymax = max(max(y));
if useNew,
  % Transform xi,yi into pixel coordinates.
  kx = n-1; ky = m-1;
  xx = max(min((xi-xmin)/(xmax-xmin)*kx+1,n),1);
  yy = max(min((yi-ymin)/(ymax-ymin)*ky+1,m),1);
else
  % Transform xi,yi into pixel coordinates.  Fix-up coordinates
  % to deal with coordinates extending from pixel boundaries rather
  % than pixel centers.
  dx = max( (xmax-xmin)/n, eps );
  dy = max( (ymax-ymin)/m, eps );
  kx = (n-1+dx); ky = (m-1+dy);
  xx = max(min((xi-xmin)/(xmax-xmin)*kx+(1-dx/2),n),1);
  yy = max(min((yi-ymin)/(ymax-ymin)*ky+(1-dy/2),m),1);
end

% Coordinates of pixels
[u,v] = meshgrid(1:n,1:m);

m = length(xx);
% Make sure polygon is traversed counter clockwise
[dum,i] = min(xx); h = rem(i+m-2,m)+1; j = rem(i,m)+1;
if det([xx([h i j]) yy([h i j]) ones(3,1)])>eps,
    xx = flipud(xx(:)); 
    yy = flipud(yy(:)); 
end

% For each triangular piece of the general polygon, find the interior
d = zeros(size(a));
while m>=3,
  imin = 1; jmin = 2; hmin = 3;% Defaults
  
  % Find triangle with minimum diagonal
  mindiag = inf;
  for i=1:m,
    h = rem(i+m-2,m)+1; j = rem(i,m)+1;
    if det([xx([h i j]) yy([h i j]) ones(3,1)])<eps,
      thisdiag = norm([xx(h)-xx(j) yy(h)-yy(j)]);
      if thisdiag<mindiag, mindiag = thisdiag; imin = i; hmin = h; jmin = j; end
    end
  end
  m = m-1;
  dd = ones(size(a));

  for k=1:3,
    dx = xx(imin)-xx(jmin); dy = yy(imin)-yy(jmin);
	dd = dd & (((u-xx(imin))*dy - (v-yy(imin))*dx) <= 1);
    sav = imin; imin = jmin; jmin = hmin; hmin = sav;
  end
  d = dd | d;

  % Remove vertex at imin
  xx(imin) = []; yy(imin) = [];
end
