I have a Circle with a center point (Center_X, Center_Y) and I am detecting if a rectangle falls into it\'s Radius (Radius). How would I be able to perform this task? I ha
You have two common options for this kind of collision detection.
The first is to understand the ways two 2D objects can collide.
Technically case 1. can only occur if case 2. also occurs, but it is often a cheaper check. Also case 3 is checked by case 1, in the case where both objects vertices are checked.
I would proceed like this. (as it is in order of cheapness)
The second and more general method is based on the notion of the product / expansion of shapes. This operation allows you to convert the intersection question into a point containment question.
In this case the circle / rectangle box intersection can be replaced with a check for a point in a rounded rectangle.
Here's what I was describing in my comments, plus changes to correct handling of the case of a circle inside a larger rectangle which Michael Anderson pointed out in a comment:
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
Use the dist
function from Shortest distance between a point and a line segment
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
Here is a test:
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)
output:
[1.044030650891055, 1.0394155162323753, 2.202271554554524, 2.0592194189509323]
False
Here is the plot: