function points = intersectLineCircle(line, circle)
%INTERSECTLINECIRCLE Intersection point(s) of a line and a circle
%
%   INTERS = intersectLineCircle(LINE, CIRCLE);
%   Returns a 2-by-2 array, containing on each row the coordinates of an
%   intersection point. If the line and circle do not intersect, the result
%   is filled with NaN.
%
%   Example
%   % base point
%   center = [10 0];
%   % create vertical line
%   l1 = [center 0 1];
%   % circle
%   c1 = [center 5];
%   pts = intersectLineCircle(l1, c1)
%   pts = 
%       10   -5
%       10    5
%   % draw the result
%   figure; clf; hold on;
%   axis([0 20 -10 10]);
%   drawLine(l1);
%   drawCircle(c1);
%   drawPoint(pts, 'rx');
%   axis equal;
%
%   See also
%   lines2d, circles2d, intersectLines, intersectCircles
%
%   References
%   http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/
%   http://mathworld.wolfram.com/Circle-LineIntersection.html
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-01-14,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

%   HISTORY
%   2011-06-06 fix bug in delta test


% local precision
eps = 1e-14;

% center parameters
center = circle(:, 1:2);
radius = circle(:, 3);

% line parameters
dp = line(:, 1:2) - center;
vl = line(:, 3:4);

% coefficient of second order equation
a = sum(line(:, 3:4).^2, 2);
b = 2*sum(dp .* vl, 2);
c =  sum(dp.^2, 2) - radius.^2;

% discriminant
delta = b .^ 2 - 4 * a .* c;

if delta > eps
    % find two roots of second order equation
    u1 = (-b - sqrt(delta)) / 2 ./ a;
    u2 = (-b + sqrt(delta)) / 2 ./ a;
    
    % convert into 2D coordinate
    points = [line(1:2) + u1 * line(3:4) ; line(1:2) + u2 * line(3:4)];

elseif abs(delta) < eps
    % find unique root, and convert to 2D coord.
    u = -b / 2 ./ a;    
    points = line(1:2) + u*line(3:4);
    
else
    % fill with NaN
    points = NaN * ones(2, 2);
    return;
end

