Repository navigation
Expand file tree
/
Copy patharea_intersect_circle_analytical.m
More file actions
201 lines (176 loc) · 6.74 KB
/
Copy patharea_intersect_circle_analytical.m
File metadata and controls
201 lines (176 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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