function angout = npi2pi(angin,units,approach)

%NPI2PI Truncates angles into the -180 deg to 180 deg range
%
%
%  ang = NPI2PI(angin) transforms input angles into the
%  -180 to 180 degree range.
%
%  ang = NPI2PI(angin,'units') uses the units defined by the
%  input string 'units'.  If omitted, default units of 'degrees'
%  are assumed.
%
%  ang = NPI2PI(angin,'units','method') uses the method
%  defined by the corresponding input string.  Valid methods are:
%  'exact' for the exact transformation; 'inward' where all angles
%  are shifted epsilon towards the origin before the -180 to 180 degree
%  transformation; 'outward' where all angles are shifted epsilon
%  away from the origin before the -180 to 180 degree transformation.
%  If omitted, default method of 'exact' is assumed.
%
%  See also ZERO22PI, ANGLEDIM

%  Copyright 1996-1998 by Systems Planning and Analysis, Inc. and The MathWorks, Inc.
%  Written by:  E. Byrns, E. Brown
%   $Revision: 1.7 $    $Date: 1998/08/10 17:47:59 $


if nargin == 0
    error('Incorrect number of arguments')
elseif nargin == 1
    units = [];     approach = [];
elseif nargin == 2
    approach = [];
end

%  Empty argument tests

if isempty(approach);   approach = 'exact';    end
if isempty(units);      units    = 'degrees';  end

%  Convert inputs to radians

angin = angledim(angin,units,'radians');

%  Exact approach -- Eliminates the use of ATAN2 function.

%  Approximate approach -- Some inconsistencies with ATAN2 function
%  across platforms when an exact multiple of -pi is used.  Some platforms
%  atan2(-1,0) = -pi, and for some platforms atan2(-1,0) = pi;

switch lower(approach)
case 'exact'

%  Exact approach is not straightforward because of this mapping behavior:
%       -3pi maps to -pi;   -2pi maps to -pi;  -pi maps to -pi;
%        pi  maps to pi;     2pi maps to pi;   3pi maps to pi
%  Note that the mapping point changes when the sign on pi changes.

    angout = pi*((abs(angin)/pi) - ...
	         2*ceil(((abs(angin)/pi)-1)/2)) .* sign(angin);

case 'inward'

%  Move data epsilon towards (inward) the origin.  Eliminates any
%  points which start identically on a multiple of pi.  Then
%  use the atan2 function.

    epsilon = epsm('radians');
    angin   = angin*(1 - epsilon);
	angout  = atan2(sin(angin),cos(angin));

case 'outward'

%  Move data epsilon towards (away from) the origin.  Eliminates any
%  points which start identically on a multiple of pi.  Then
%  use the atan2 function.

    epsilon = epsm('radians');
    angin   = angin * (1 + epsilon);
	angout  = atan2(sin(angin),cos(angin));

otherwise
    error('Unrecognized approach string')
end

angout = angledim(angout,'radians',units);  %  Convert to the original units
