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:
https://diego.assencio.com/?index=8d6ca3d82151bad815f78addf9b5c1c6
Parameters
----------
r1: float or numpy.ndarray
The radius of circle 1
r2: float or numpy.ndarray
The radius of circle 2
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
The radius of circle 1
r2: numpy.ndarray
The radius of circle 2
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