Code covered by the BSD License  

Highlights from
Analytical intersection area between two circles

image thumbnail
from Analytical intersection area between two circles by Guillaume JACQUENOT
Compute the intersection area between 2 circles. The function allows to evaluate the intersection ar

area_intersect_circle_analytical(varargin)
function M = area_intersect_circle_analytical(varargin)
% Compute the overlap area between 2 circles defined in an array.
% Computation is vectorized, and intersection area are computed an
% analytical way.
%   
% Input: Circles data presented in an array G of three columns.
%        G contains parameters of the n circles
%           . G(1:n,1) - x-coordinate of the center of circles,
%           . G(1:n,2) - y-coordinate of the center of circles,
%           . G(1:n,3) - radii of the circles 
%        Each row of the array contains the information for one circle.
% 
%        Input can also be provided in three different vectors. These
%        vectors can be row or column vectors. The 1st one corresponds to
%        x-coordinate of the center of circles, the 2nd one to the
%        y-cooridnate and the 3rd one to the radii of the circles.
% 
% 
% Output: Square matrix M(n,n) containing intersection areas between
% circles
%         M(i,j) contains the intersection area between circles i & j
%         By definition, M(i,i) corresponds to the area of circle i.
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% For 2 circles i & j, three cases are possible depending on the distance
% d(i,j) of the centers of the circles i and j.
%   Case 1: Circles i & j do not overlap, there is no overlap area M(i,j)=0;
%             Condition: d(i,j)>= ri+rj
%             M(i,j) = 0;
%   Case 2: Circles i & j fully overlap, the overlap area has to be computed.
%             Condition: d(i,j)<= abs(ri-rj)
%            M(i,j) = pi*min(ri,rj).^2
%   Case 3: Circles i & j partially overlap, the overlap area has to be computed
%            decomposing the overlap area.
%             Condition: (d(i,j)> abs(ri-rj)) & (d(i,j)<(ri+rj))
%            M(i,j) = f(xi,yi,ri,xj,yj,rj)
%                   = ri^2*arctan2(yk,xk)+ ...
%                     rj^2*arctan2(yk,d(i,j)-xk)-d(i,j)*yk
%             where xk = (ri^2-rj^2+d(i,j)^2)/(2*d(i,j))
%                   yk = sqrt(ri^2-xk^2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Guillaume JACQUENOT
% guillaume.jacquenot@gmail.com
% 2007_06_08

% Some explanations, comments were added. Input arguments are detailed.
% Verifications of input arguments are performed.
% The number of calculations has been divided by two.
 




if nargin==0
    % Performs an example
    % Creation of 5 circles
    x = [0,1,5,3,-5];    
    y = [0,4,3,7,0];    
    r = [1,5,3,2,2];   
elseif nargin==1
    temp = varargin{1};
    x = temp(:,1);
    y = temp(:,2);
    r = temp(:,3);    
elseif nargin==3
    x = varargin{1};
    y = varargin{2};
    r = varargin{3};    
else
    error('The number of arguments must 0, 1 or 3')
end

% Inputs are reshaped in 
size_x = numel(x);
size_y = numel(y);
size_r = numel(r);

x = reshape(x,size_x,1);
y = reshape(y,size_y,1);
r = reshape(r,size_r,1);

% Checking if the three input vectors have the same length
if (size_x~=size_y)||(size_x~=size_r)
    error('Input of function must be the same length')
end

% Checking if there is any negative or null radius
if any(r<=0)
    disp('Circles with null or negative radius won''t be taken into account in the computation.')
    temp = (r>0);
    x = x(temp);
    y = y(temp);
    r = r(temp);
end

% Checking the size of the input argument
if size_x==1
    M = pi*r.^2;
    return
end

% Computation of distance between all circles, which will allow to
% determine which cases to use.
[X,Y] = meshgrid(x,y);
D     = sqrt((X-X').^2+(Y-Y').^2);
% Since the resulting matrix M is symmetric M(i,j)=M(j,i), computations are
% performed only on the upper part of the matrix
D = triu(D,1);

[R1,R2] = meshgrid(r);
sumR    = triu(R1+R2,1);
difR    = triu(abs(R1-R2),1);


% Creating the resulting vector
M = zeros(size_x*size_x,1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Case 2: Circles i & j fully overlap
% One of the circles is inside the other one.
C1    = triu(D<=difR);
M(C1) = pi*min(R1(C1),R2(C1)).^2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Case 3: Circles i & j partially overlap
% Partial intersection between circles i & j
C2 = (D>difR)&(D<sumR);
% Computation of the coordinates of one of the intersection points of the
% circles i & j
Xi(C2,1) = (R1(C2).^2-R2(C2).^2+D(C2).^2)./(2*D(C2));
Yi(C2,1) = sqrt(R1(C2).^2-Xi(C2).^2);
% Computation of the partial intersection area between circles i & j
M(C2,1) = R1(C2).^2.*atan2(Yi(C2,1),Xi(C2,1))+...
          R2(C2).^2.*atan2(Yi(C2,1),(D(C2)-Xi(C2,1)))-...
          D(C2).*Yi(C2,1);
      
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      
% Compute the area of each circle. Assign the results to the diagonal of M      
M(1:size_x+1:size_x*size_x) = pi.*r.^2; 

% Conversion of vector M to matrix M      
M = reshape(M,size_x,size_x);

% Creating the lower part of the matrix
M = M + tril(M',-1);


% Display results if no argument is provided
if nargin==0
    f = figure;
    hAxs = axes('Parent',f);
    hold on, box on, axis equal
    xlabel('x')
    ylabel('y','Rotation',0)
    title('Compute the intersection area between 2 circles a vectorized way for several cicles')
    text(-2,-2,'Numbers on lines represent the intersection')
    text(-2,-3,'area between 2 circles')
    axis([-8 9 -4 10])    
    colour = rand(size_x,3);    
    for t = 1: size_x
        plot(x(t)+r(t).*cos(0:2*pi/100:2*pi),...
             y(t)+r(t).*sin(0:2*pi/100:2*pi),'color',colour(t,:),'parent',hAxs)
        plot(x(t),y(t),'+','color',colour(t,:),'parent',hAxs)
        for u = t+1:size_x
            if M(t,u)~=0
                plot([x(t),x(u)],[y(t),y(u)],'k-','parent',hAxs)
                text((x(t)+x(u))/2,(y(t)+y(u))/2,num2str(M(t,u)),...
                    'HorizontalAlignment','center',...
                    'BackgroundColor',[1 1 1],'parent',hAxs)
            end
        end
        
    end
end

% function A=cercle_inter(G)
% % Guillaume JACQUENOT
% % guillaume.jacquenot@gmail.com
% % 2007_05_20
% % % Input: G - array, which contain parameters of the circles
% %          G(n,1) - x-coordinate,
% %          G(n,2) - y-coordinate,
% %          G(n,3) - radius of circle number n=1,2
% % Output:  A - area of the overlapping circles
% d=sqrt((G(1,1)-G(2,1))^2+(G(1,2)-G(2,2))^2);
% 
% if d>=(G(1,3)+G(2,3))
%     % No contact between circles.
%     A=0;
% elseif d<=abs(G(1,3)-G(2,3))
%     % The smaller circle is inside the big one.
%     A=pi*(min(G(1,3),G(2,3)))^2;
% else
%     xi=(G(1,3)^2-G(2,3)^2+d^2)/(2*d);
%     yi=sqrt(G(1,3)^2-xi^2);
%     A=G(1,3)^2*atan2(yi,   xi )+...
%       G(2,3)^2*atan2(yi,(d-xi))-d*yi;
% end

Contact us at files@mathworks.com