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.
- Un vértice de uno puede estar dentro del otro
- Sus lados pueden cruzar (incluso si no hay verice dentro)
- 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)
- Verifique que sus casillas de delimitación se cruzan.
- Comprueba si algún vértice del cuadrado está dentro del
- Verifica si el centro del círculo está dentro del rectángulo
- 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: