sprites deteccion colisiones python pygame collision-detection circle

python - deteccion - Detectando una colisión de rectángulo con un círculo



deteccion de colisiones en java (3)

Esto es lo que estaba describiendo en mis comentarios, además de los cambios al manejo correcto de la caja de un círculo dentro de un rectángulo más grande que Michael Anderson señaló en un comentario:

import math def collision(rleft, rtop, width, height, # rectangle definition center_x, center_y, radius): # circle definition """ Detect collision between a rectangle and circle. """ # complete boundbox of the rectangle rright, rbottom = rleft + width/2, rtop + height/2 # bounding box of the circle cleft, ctop = center_x-radius, center_y-radius cright, cbottom = center_x+radius, center_y+radius # trivial reject if bounding boxes do not intersect if rright < cleft or rleft > cright or rbottom < ctop or rtop > cbottom: return False # no collision possible # check whether any point of rectangle is inside circle''s radius for x in (rleft, rleft+width): for y in (rtop, rtop+height): # compare distance between circle''s center point and each point of # the rectangle with the circle''s radius if math.hypot(x-center_x, y-center_y) <= radius: return True # collision detected # check if center of circle is inside rectangle if rleft <= center_x <= rright and rtop <= center_y <= rbottom: return True # overlaid return False # no collision detected

Tengo un círculo con un punto central (Center_X, Center_Y) y estoy detectando si un rectángulo cae en su radio (radio). ¿Cómo podría realizar esta tarea? He intentado usar

if (X - Center_X)^2 + (Y - Center_Y)^2 < Radius^2: print(1)

Luego trato de dibujar un círculo para encajar en esta área:

Circle = pygame.draw.circle(Window, Blue, (Center_X, Center_Y), Radius, 0)

Pero no parece alinearse. ¿Hay algo que estoy haciendo mal?


Tienes dos opciones comunes para este tipo de detección de colisión.

El primero es comprender cómo pueden colisionar dos objetos 2D.

  1. Un vértice de uno puede estar dentro del otro
  2. Sus lados pueden cruzar (incluso si no hay verice dentro)
  3. Uno puede ser completamente interior al otro.

Técnicamente el caso 1. solo puede ocurrir si el caso 2. también ocurre, pero a menudo es un cheque más barato. También el caso 3 es verificado por el caso 1, en el caso donde se verifican ambos vértices de objetos.

Yo procedería así. (como es en orden de bajo costo)

  1. Verifique que sus casillas de delimitación se cruzan.
  2. Comprueba si algún vértice del cuadrado está dentro del
  3. Verifica si el centro del círculo está dentro del rectángulo
  4. Verifique las intersecciones de círculo y borde.

El segundo y más general método se basa en la noción de producto / expansión de formas. Esta operación le permite convertir la pregunta de intersección en una pregunta de contención de punto.

En este caso, la intersección de la caja de círculo / rectángulo se puede reemplazar con una verificación de un punto en un rectángulo redondeado.


Utilice la función dist desde la distancia más corta entre un punto y un segmento de línea

import math def dist(p1, p2, c): x1,y1 = p1 x2,y2 = p2 x3,y3 = c px = x2-x1 py = y2-y1 something = px*px + py*py u = ((x3 - x1) * px + (y3 - y1) * py) / float(something) if u > 1: u = 1 elif u < 0: u = 0 x = x1 + u * px y = y1 + u * py dx = x - x3 dy = y - y3 dist = math.sqrt(dx*dx + dy*dy) return dist

Aquí hay una prueba:

rect = [[0. , 0. ], [ 0.2, 1. ], [ 2.2, 0.6], [ 2. , -0.4]] c = 0.5, 2.0 r = 1.0 distances = [dist(rect[i], rect[j], c) for i, j in zip([0, 1, 2, 3], [1, 2, 3, 0])] print distances print any(d < r for d in distances)

salida:

[1.044030650891055, 1.0394155162323753, 2.202271554554524, 2.0592194189509323] False

Aquí está la trama: