The intersection area of two circles
概要
中心 \(p_1 = (x_1, y_1)\), 半径 \(r_1\) の円1 と 中心 \(p_2 = (x_2, y_2)\), 半径 \(r_2\) の円2 の共通部分の面積 \(S\) を求める。
ここでは2つの円における扇形の面積から、 点 \(p_1, p_2\) と 2つの円の交点 \(c_1, c_2\) から成る四角形の面積を引くことで共通部分の面積を求める。
2つの円の中心同士の距離を \(d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}\) とする。
2つの円同士の交点のうちの1点 \(c_1\) に対し、 線分 \(p_1 - p_2\) と 線分 \(p_1 - c_1\) のなす角を \(\theta_1\), 線分 \(p_2 - p_1\) と 線分 \(p_2 - c_1\) のなす角を \(\theta_2\) とする。
このとき \(\displaystyle \cos \theta_1 = \frac{r_1^2 - r_2^2 + d^2}{2 r_1 d}\), \(\displaystyle \cos \theta_2 = \frac{r_2^2 - r_1^2 + d^2}{2 r_2 d}\) となる。
扇形の面積は、円1側は \(\displaystyle \frac{1}{2} r_1^2 (2 \theta_1)\), 円2側は \(\displaystyle \frac{1}{2} r_2^2 (2 \theta_2)\) となる。
また、四角形の面積は \(\displaystyle r_1 d \sin \theta_1 = \frac{\sqrt{4 r_1^2 d^2 - (r_1^2 - r_2^2 + d^2)^2}}{2}\) で求められる。
よって、共通部分の面積 \(S\) は \(\displaystyle r_1^2 \theta_1 + r_2^2 \theta_2 - \frac{\sqrt{4 r_1^2 d^2 - (r_1^2 - r_2^2 + d^2)^2}}{2}\) で計算できる。
実装
from math import pi, atan2
def circles_intersection_area(P1, r1, P2, r2):
x1, y1 = P1; x2, y2 = P2
dd = (x1 - x2)**2 + (y1 - y2)**2
if (r1 + r2)**2 <= dd:
return 0.0
if dd <= (r1 - r2)**2:
return pi*min(r1, r2)**2
p1 = (r1**2 - r2**2 + dd)
p2 = (r2**2 - r1**2 + dd)
S1 = r1**2 * atan2((4*dd*r1**2 - p1**2)**.5, p1)
S2 = r2**2 * atan2((4*dd*r2**2 - p2**2)**.5, p2)
S0 = (4*dd*r1**2 - p1**2)**.5 / 2
return S1 + S2 - S0
print(circles_intersection_area((0, 1), 1, (1, 0), 1))
# => "0.5707963267948966"
Verified
-
AOJ: "CGL_7_I: Area of Intersection between Two Circles": source (Python3, 0.03sec)