Обнаружение столкновения Rectangle с кругом
У меня есть круг с центральной точкой (Center_X, Center_Y), и я обнаруживаю, что в него попадает прямоугольник Радиус (Радиус). Как я смогу выполнить эту задачу? Я пробовал использовать
if (X - Center_X)^2 + (Y - Center_Y)^2 < Radius^2:
print(1)
Затем я пытаюсь нарисовать круг для этой области:
Circle = pygame.draw.circle(Window, Blue, (Center_X, Center_Y), Radius, 0)
Но это не похоже на линию. Есть ли что-то, что я делаю неправильно?
Ответы
Ответ 1
Вот то, что я описывал в своих комментариях, плюс изменения в правильной обработке случая круга внутри большего прямоугольника, который Майкл Андерсон указал в комментарии:
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 radius
for x in (rleft, rleft+width):
for y in (rtop, rtop+height):
# compare distance between circle center point and each point of
# the rectangle with the circle 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
Ответ 2
У вас есть два общих варианта для такого обнаружения столкновения.
Во-первых, чтобы понять, как могут столкнуться два 2D-объекта.
- Вершина одного может быть внутри другого
- Их стороны могут пересекаться (даже не думая, что внутри нет)
- Можно быть полностью внутренним для другого.
Технически случай 1. может произойти только в том случае, если также имеет место случай 2, но он часто является более дешевой проверкой.
Также случай 3 проверяется случаем 1, в случае, когда проверяются обе вершины объектов.
Я бы сделал так. (так как это в порядке дешевизны)
- Убедитесь, что их ограничивающие прямоугольники пересекаются.
- Проверьте, находится ли какая-либо вершина квадрата внутри
- Проверьте, находится ли центр круга внутри прямоугольника
- Проверьте пересечения границ круга.
Второй и более общий метод основан на понятии продукта/расширения форм.
Эта операция позволяет преобразовать вопрос о пересечении в вопрос одержимости точки.
В этом случае пересечение прямоугольника прямоугольника/прямоугольника можно заменить проверкой на точку в закругленном прямоугольнике.
Ответ 3
Используйте функцию dist
из кратчайшее расстояние между точкой и сегментом линии
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
Вот тест:
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)
выход:
[1.044030650891055, 1.0394155162323753, 2.202271554554524, 2.0592194189509323]
False
Вот сюжет:
![enter image description here]()