2010-11-22 39 views
13

Dados dos círculos:área de intersección entre dos círculos

  • C1 al (x1, y1) con radius1
  • C2 al (x2, y2) con radius2

¿Cómo se calcula el área de su intersección? Todas las funciones matemáticas estándar (sin, cos, etc.) están disponibles, por supuesto.

+0

http://mathworld.wolfram.com/Circle-CircleIntersection.html –

+0

Gracias. De hecho, era consciente del enlace antes de publicarlo. En realidad estaba buscando una ecuación específica usando las variables que enumeré. –

Respuesta

24

bien, utilizando el enlace Wolfram y cue de Misnomer para mirar a la ecuación 14, I haber derivado la siguiente solución Java utilizando las variables que se enumeran y la distancia entre los centros (trivialmente, que se pueden derivar de ellos):

Double r = radius1; 
Double R = radius2; 
Double d = distance; 
if(R < r){ 
    // swap 
    r = radius2; 
    R = radius1; 
} 
Double part1 = r*r*Math.acos((d*d + r*r - R*R)/(2*d*r)); 
Double part2 = R*R*Math.acos((d*d + R*R - r*r)/(2*d*R)); 
Double part3 = 0.5*Math.sqrt((-d+r+R)*(d+r-R)*(d-r+R)*(d+r+R)); 

Double intersectionArea = part1 + part2 - part3; 
+0

Publique su meta-nota en Meta http://meta.stackoverflow.com/ –

+0

Sí, lo verifiqué allí y ya hay un hilo donde la respuesta oficialmente votada es que es bueno regresar y responder su propia pregunta . Pero no parece que la mayoría de los usuarios de SO realmente sigan esa política. Sin ofender a Misnomer y le agradezco que trate de ayudar. Pero, en este momento, tiene 3 votos positivos por darme un enlace que ya sabía antes de publicar. He hecho el trabajo arduo de traducir la información en ese enlace al código y solo tengo 1 voto positivo. He visto este tipo de comportamiento multitudinario en SO y me desconcierta. –

+0

@ Chris ... perdiste mi respuesta porque ... querías que tuvieras más votos ascendentes ... ahora eso me desconcierta ... No discutiré tu punto ... porque es algo tonto según mi opinión ... .pero de cualquier manera..por favor, al menos, deje un comentario explicando los votos a favor la próxima vez ... – Vishal

10

Es posible que desee comprobar esto analytical solution y aplicar la fórmula con sus valores de entrada.

Otra fórmula dada here -

Area = r^2*(q - sin(q)) where q = 2*acos(c/2r), 
where c = distance between centers and r is the common radius. 
+0

+1 El primer enlace tiene una derivación completa de la fórmula. El segundo es útil si los radios de los círculos son los mismos. – eaj

+0

Gracias por los enlaces. ¿Hay una fórmula más general que pueda derivarse utilizando específicamente las variables que di (por ejemplo, no suponiendo un radio común)? –

+1

Cree que el primer enlace eq 14 le da una solución general, pero necesito repasar las matemáticas para ver qué está sucediendo exactamente ... también es posible que necesite más necesita más de un radio de círculos para encontrar esto, también intente esto si es útil-http : //2000clicks.com/MathHelp/GeometryConicSectionCircleIntersection.aspx – Vishal

18

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.

+0

Gracias - ¡me ayudó! La versión modificada era exactamente lo que buscaba. – scipilot

+0

Esta respuesta es incorrecta. No estoy completamente seguro de dónde está el error lógico, pero falla al menos en estos casos (cuando r1 se acerca a 2 desde abajo): x0 = 0, y0 = 0, r0 = 1, x1 = 1, y0 = 0, r1 = 2. Específicamente, su código le da al área que se acerca a Pi, cuando debería acercarse a Pi/2. – user1145925

+1

@ user1145925, para entradas x0 = 0, y0 = 0, r0 = 1, x1 = 1, y0 = 0, r1 = 2 una salida de Pi es correcta ya que el círculo 0 tiene un área de Pi, y está completamente dentro del círculo 2. –

Cuestiones relacionadas