Aquí es una función de JavaScript que hace exactamente lo que Chris fue después:
function areaOfIntersection(x0, y0, r0, x1, y1, r1)
{
var rr0 = r0 * r0;
var rr1 = r1 * r1;
var d = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
var phi = (Math.acos((rr0 + (d * d) - rr1)/(2 * r0 * d))) * 2;
var theta = (Math.acos((rr1 + (d * d) - rr0)/(2 * r1 * d))) * 2;
var area1 = 0.5 * theta * rr1 - 0.5 * rr1 * Math.sin(theta);
var area2 = 0.5 * phi * rr0 - 0.5 * rr0 * Math.sin(phi);
return area1 + area2;
}
Sin embargo, este método devolverá NaN si un círculo está completamente dentro del otro, o no se están tocando en absoluto. Una versión ligeramente diferente que no falla en estas condiciones es el siguiente:
function areaOfIntersection(x0, y0, r0, x1, y1, r1)
{
var rr0 = r0 * r0;
var rr1 = r1 * r1;
var d = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
// Circles do not overlap
if (d > r1 + r0)
{
return 0;
}
// Circle1 is completely inside circle0
else if (d <= Math.abs(r0 - r1) && r0 >= r1)
{
// Return area of circle1
return Math.PI * rr1;
}
// Circle0 is completely inside circle1
else if (d <= Math.abs(r0 - r1) && r0 < r1)
{
// Return area of circle0
return Math.PI * rr0;
}
// Circles partially overlap
else
{
var phi = (Math.acos((rr0 + (d * d) - rr1)/(2 * r0 * d))) * 2;
var theta = (Math.acos((rr1 + (d * d) - rr0)/(2 * r1 * d))) * 2;
var area1 = 0.5 * theta * rr1 - 0.5 * rr1 * Math.sin(theta);
var area2 = 0.5 * phi * rr0 - 0.5 * rr0 * Math.sin(phi);
// Return area of intersection
return area1 + area2;
}
}
escribí esta función mediante la lectura de la información que se encuentra en el Math Forum. Encontré esto más claro que la explicación Wolfram MathWorld.
http://mathworld.wolfram.com/Circle-CircleIntersection.html –
Gracias. De hecho, era consciente del enlace antes de publicarlo. En realidad estaba buscando una ecuación específica usando las variables que enumeré. –