raw math

Similarly to the article about intersection points of two circles we're now interested in the area that is formed by the intersection of two overlapping circles. We could formulate cases to step through the same as in the other article, but I will do it a little shorter this time.

We can see that when the distance measure \(d\) is zero, the intersection area is \(\pi r^2\) with \(r\) being the smaller radius of both circles. If \(d\) is greater than the sum of both radii, the area of intersection is zero.

Calculate the actual overlapping

The idea is quite simple. When you look at the piece of cake which can be extracted on both circles, you have way too much of the area you want to calculate. But subtracting the triangle on each side gives you the area of the overlapping section.

We use the same equations as previously derived:




Area of the circle sector

The goal is to calculate the area of the sector of the circle, which is a fraction of the whole. As a circle has 360°, the actual fraction is \(\frac{\theta_A}{2\pi}\)

Calculating \(\theta_A\) can be done either by the points \(\vec{P}_{1,2}\) we calculated already, or much simpler by using the sine of the half of the triangle and multiplying it by two:

\[\theta_A = 2\cos^{-1}\left(\frac{A_r^2 + d^2 - B_r^2}{2 A_r d}\right)\]

The same can be applied for the second circle:

\[\theta_B = 2\cos^{-1}\left(\frac{B_r^2 + d^2 - A_r^2}{2 B_r d}\right)\]

The area of the two circle sectors is then:

\[\text{area}_{s,1} = \frac{\theta_A}{2\pi} \pi A_r^2 = \frac{1}{2} \theta_A A_r^2\]

\[\text{area}_{s,2} = \frac{\theta_B}{2\pi} \pi B_r^2 = \frac{1}{2} \theta_B B_r^2\]

All we still need is the area of the two triangles. We have all information to do that:

\[\text{area}_{t,1} = \frac{1}{2}A_r^2 sin(\theta_A)\]

\[\text{area}_{t,2} = \frac{1}{2}B_r^2 sin(\theta_B)\]

The final area then is

\[ \begin{array}{rl} \text{area} &= \text{area}_{s,1} + \text{area}_{s,2} - \text{area}_{t,1} - \text{area}_{t,2}\\ &= \frac{1}{2} (A_r^2 (\theta_A - \sin(\theta_A)) + B_r^2 (\theta_B - \sin(\theta_B)))\\ \end{array} \]

Give me some code

All the math can be packed in a quite nice (unit tested) function

double area(A, B) {

  d = hypot(B.x - A.x, B.y - A.y)

  if (d < A.r + B.r) {

    Arr = A.r * A.r
    Brr = B.r * B.r

    if (d <= abs(B.r - A.r)) {
      return PI * min(Arr, Brr)

    tA = 2 * acos((Arr + d * d - Brr) / (2 * d * A.r))
    tB = 2 * acos((Brr + d * d - Arr) / (2 * d * B.r))

    return 0.5 * (Arr * (tA - sin(tA)) + Brr * (tB - sin(tB)))
  return 0