2012-02-28 28 views
10

Estoy teniendo un problema. Tengo una tarea que me obliga a encontrar si un segundo círculo se superpone, adentro, o no es un segundo círculo. Sin embargo, tengo problemas para verificar la superposición y si el segundo círculo está dentro del primero.Encontrar si un círculo está dentro de otro círculo

(variables utilizadas son x1, x2, y1, y2, r1, r2, distancia)

Esto es lo que tengo:

if (distance > (r1 + r2)) { 
     // No overlap 
     System.out.println("Circle2 does not overlap Circle1"); 
    } else if (distance <= Math.abs(r1 + r2)) { 
     // Overlap 
     System.out.println("Circle2 overlaps Circle1"); 
    } else if ((distance <= Math.abs(r1 - r2)) { 
     // Inside 
     System.out.println("Circle2 is inside Circle1"); 
} 

Me temo que el problema es con los controles superpuestos y en el interior, pero no puedo descifrar cómo configurarlo adecuadamente para poder verificar de manera confiable si el segundo círculo está dentro del primero.

Cualquier ayuda o consejo sería muy apreciado ya que he intentado varios enfoques, pero la solución simplemente se me escapa cada vez.

+1

Primero - ¿qué es la distancia? ¿Es la distancia entre los centros de los círculos? Segundo: ¿podría ayudar a determinar qué radio es mayor? – user1118321

+0

Todas las variables son ingresadas por el usuario. Sí, la distancia es la distancia entre los dos centros de los dos círculos con la fórmula de distancia. – Battleroid

+0

Acabo de buscar en Google para encontrar sobre este problema y encontré esto http://gamedev.stackexchange.com/questions/7172/how-to-find-out-if-two-circles-intersect-each-other – Jayy

Respuesta

14

sólo tiene que comprobar si hay dentro antes de solapamiento como la distancia, el interior es < = distancia de solapamiento

if (distance > (r1 + r2)) 
{ 
    // No overlap 
    System.out.println("Circle2 does not overlap Circle1"); 
} 
else if ((distance <= Math.abs(r1 - r2)) 
{ 
    // Inside 
    System.out.println("Circle2 is inside Circle1"); 
} 
else    // if (distance <= r1 + r2) 
{ 
    // Overlap 
    System.out.println("Circle2 overlaps Circle1"); 
} 

respuesta modificado de acuerdo con los comentarios de Chris

+0

Sí, ese era mi problema. Intenté esto una vez antes, pero creo que lo ordené mal con las comparaciones incorrectas. Gracias de nuevo. – Battleroid

+1

Tiene código innecesario allí. Como r1 y r2 son ambos> 0 (supongo que ya que son radios) entonces r1 + r2 no necesita la llamada de abs a su alrededor. Si luego compara esta verificación con la primera, notará que siempre se probará si la primera es falsa, por lo que puede omitir la condición y hacer que la última sea simplemente otra. – Chris

+0

Sé que acabo de reorganizar el código en la pregunta original, pero es un buen punto para hacer, voy a poner un comentario. – Dampsquid

2

Bueno, si la suma de la distancia y el radio más pequeño es menor que el otro radio, el círculo más pequeño debe estar dentro del más grande.

+0

Solo si los centros están lo suficientemente cerca el uno del otro, si no lo están, puede que se superpongan o que ni siquiera se superpongan círculos. –

+1

@JonathanDrapeau. Lo siento, pero esto no es verdad. Bueno, al menos, siempre que la * distancia * signifique la distancia entre los dos centros. Si los centros están lo suficientemente lejos como para que los círculos se crucen, entonces podemos tener dos casos: a) el centro de un círculo está dentro del otro => d + r2> r1 || d + r1> r2; o b) ningún centro circular está dentro del otro círculo => d> r1 || d> r2 ya. – Matthias

2

Editar para obviedad por el comentario de proxy:

La distancia entre los puntos en el espacio está descrita por pythagoras:

distance = sqrt(travelled_x_squared + travelled_y_squared); 

Lo que por supuesto se traduce en código como

distance = Math.sqrt( (x1-x2)*(x1-x2) + (y1 - y2)*(y1 - y2)); 

La distancia está en contacto en R1 + R2.

Antes de editar pistas: Necesita el ángulo entre los círculos.

Luego calcula la distancia desde circle1 hasta circle 2. Si es menor que radii1 + radii2, está dentro.

atan2 podría ser una función de su interés.

O simplemente vaya con la distancia pythagorean directamente.

+2

Los ángulos son totalmente irrelevantes. Siempre puedes considerar la línea a través de los dos centros y las distancias a lo largo de esas líneas (distancia, r1, r2). – Chris

+0

@Chris Sí, esa es la distancia pitagórica. –

+0

No estoy seguro de que eso explique por qué cree que necesita ángulos.Solo vas a complicar las cosas y atan2 realmente no es de interés para este problema y te llevará por un camino a una solución incorrecta ... – Chris

9

Este problema es probablemente el más fácil de resolver visualmente primero y luego el código escrito. Parece que tienes la lógica correcta para no dentro y completamente adentro.

La manera más fácil de tratar con esto es que si no están completamente adentro y no completamente afuera, entonces deben estar superpuestos. Esta es sin duda la forma en que lo codificaría. Las matemáticas son un poco más complicadas que las otras dos.

if (distance > (r1 + r2)) { 
    // No overlap 
    System.out.println("Circle2 does not overlap Circle1"); 
} else if ((distance <= Math.abs(r1 - r2)) { 
    // Inside 
    System.out.println("Circle2 is inside Circle1"); 
{ else { 
    // Overlap 
    System.out.println("Circle2 overlaps Circle1"); 
} 

La condición actual es:

r2>r1-d y r2 < r1+d

Por symmetery que no es necesario hacer las dos formas (solo si cambias R2 y R1 en ambos y hace un poco de reordenación obtienes el mismo par de ecuaciones).

Es más fácil simplemente dejar esto en la categoría "else" en lugar de codificar a menos que lo necesite por alguna razón.

0

Es una tarea sencilla,

tomar la suma de los radios de dos círculos. di r1 + r2. Ahora encontrar la distancia entre el centro de dos círculos que es sqrt ((x1-x2)^2 + (Y1-Y2)^2) if r1+r2 = sqrt((x1-x2)^2 + (y1-y2)^2) they just touch each other. if r1+r2 > sqrt((x1-x2)^2 + (y1-y2)^2) the circle overlaps(intersect) if r1+ r2 < sqrt((x1-x2)^2 + (y1-y2)^2) the circle doesnot intersect

2

Eres muy cerca de allí. Es solo el orden de las condiciones lo que está mal.

if (distance > (r1 + r2)) { 
     // No overlap 
     System.out.println("Circle2 does not overlap Circle1"); 
    } else if ((distance <= Math.abs(r1 - r2)) { 
     // Inside 
     System.out.println("Circle2 is inside Circle1"); 
    } else { 
     // Overlap 
     System.out.println("Circle2 overlaps Circle1"); 
} 

Comprobación del caso 'dentro' después de que el caso 'no se solapan' asegura que no será considerado como una superposición accidental. Entonces todo el resto debe superponerse.

+0

Usted y Dampsquid tenían razón sobre el dinero. Intenté esto antes, pero hice el tonto de las comparaciones, por lo que me salió mal cada vez. – Battleroid

-1
/** 
    * 
    * @param values { x0, y0, r0, x1, y1, r1 } 
    * @return true if circles is intersected 
    */ 
    public static boolean isCircleIntersect(double... values) 
    { 
    /* check using mathematical relation: ABS(R0-R1) <= SQRT((x0-x1)^2+(y0-y1)^2) <= (R0+R1) */ 
    if (values.length == 6) 
    { 
     /* get values from first circle */ 
     double x0 = values[0]; 
     double y0 = values[1]; 
     double r0 = values[2]; 
     /* get values from second circle */ 
     double x1 = values[3]; 
     double y1 = values[4]; 
     double r1 = values[5]; 
     /* returun result */ 
     return (Math.abs(r0 - r1) <= Math.sqrt(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2))) 
       && (Math.sqrt(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2)) <= (r0 + r1)); 
    } 
    else 
    { 
     /* return default result */ 
     return false; 
    } 
    } 
+0

Debe usar el botón de código para formatear esto como código fuente. – Thom

Cuestiones relacionadas