# Source code for foxes.utils.two_circles

``````import numpy as np

[docs]
def area(r1, r2, d):
"""
Calculates the intersection of two
circles with radii r1, r2 and a centre
point distance d.

Make sure that

1) r1 >= r2
2) r1 - r2 <= d <= r1 + r2

These conditions are assumed but not checked
within the function.

Source:

Parameters
----------
r1: float or numpy.ndarray
r2: float or numpy.ndarray
d: float or numpy.ndarray
The distance between the centre points
of the two circles

Returns
-------
area: float or numpy.ndarray
The intersectional area

:group: utils.two_circles

"""
d1 = (r1**2 - r2**2 + d**2) / (2 * d)
d2 = d - d1

a = np.maximum(np.minimum(d1 / r1, 1.0), -1)
b = np.maximum(r1**2 - d1**2, 0.0)
A1 = r1**2 * np.arccos(a) - d1 * np.sqrt(b)

a = np.maximum(np.minimum(d2 / r2, 1.0), -1)
b = np.maximum(r2**2 - d2**2, 0.0)
A2 = r2**2 * np.arccos(a) - d2 * np.sqrt(b)

"""
A1 = r1**2 * np.arccos(d1/r1) - d1 * np.sqrt(r1**2 - d1**2)
A2 = r2**2 * np.arccos(d2/r2) - d2 * np.sqrt(r2**2 - d2**2)
"""

return A1 + A2

[docs]
def calc_area(r1, r2, d):
"""
Calculates the intersection of two circles.

All parameters should have the same shape,
or be broadcastable to one another.

Parameters
----------
r1: numpy.ndarray
r2: numpy.ndarray
d: numpy.ndarray
The distance between the centre points
of the two circles

Returns
-------
area: numpy.ndarray
The intersectional area

:group: utils.two_circles

"""

# prepare:
out = np.zeros_like(d)

# condition d < r1 + r2:
sel0 = d < r1 + r2
if np.any(sel0):
# condition r1 >= r2:
sela = r1 >= r2
selr = sel0 & sela
if np.any(selr):
# condition d <= r1 - r2:
selb = d <= r1 - r2
seld = selr & selb
if np.any(seld):
out[seld] = np.pi * r2[seld] ** 2

# condition d > r1 - r2:
seld = selr & (~selb)
if np.any(seld):
out[seld] = area(r1[seld], r2[seld], d[seld])

# condition r1 < r2:
selr = sel0 & (~sela)
if np.any(selr):
# condition d <= r2 - r1:
selb = d <= r2 - r1
seld = selr & selb
if np.any(seld):
out[seld] = np.pi * r1[seld] ** 2

# condition d > r2 - r1:
seld = selr & (~selb)
if np.any(seld):
out[seld] = area(r2[seld], r1[seld], d[seld])

return out

``````