I'm creating a 2D game and want to test for collision between an OBB (Oriented Bounding Box) and a Circle. I'm unsure of the maths and code to do this. I'm creating the game in c++ and 开发者_StackOverflow社区opengl.
Since both your shapes are convex, you can use the Separating Axis Theorem. Here's a tutorial on how to implement an algorithm to do this.
Essentially, you try to find if it's possible to put a line somewhere that's between the two shapes and if you can't find one, then you know they're colliding.
References and general answer taken from this question.
Here's what I would do, in pseudocode:
function does_line_go_through_circle (original_line, circle_centerpoint, radius):
original_slope = get_slope_of_line (original_line)
perpendicular_slope = 1/original_slope
perpendicular_line = create_line_with_slope_through_point (perpendicular_slope, circle_centerpoint)
intersect_point = intersection_of_infinite_lines (perpendicular_line, original_line)
if point_is_on_line (intersect_point, original_line):
finite_line_along_radius = create_finite_line_between_points (circle_centerpoint, intersect_point)
if length_of_line (finite_line_along_radius) < length_of_line (radius):
return true
end
end
return false
end
function does_box_intersect_with_circle (bounding_box, circle):
for each side in bounding_box:
if does_line_go_through_circle (side, circle.center, circle.radius):
return true
end
end
return false
end
Keep in mind, I'm a little rusty on this stuff, I might be wrong.
Anyway, it should be trivial to implement this in C++.
We will divide the rectangle into 4 finite lines.
We can construct the line equation ax + by + c = 0
connecting the points (x1, y1)
and (x2, y2)
as follows:
mx - y + c = 0
where m = (y2-y1)/(x2-x1)
Shortest (perpendicular) distance from a line ax + by + c = 0
to a point (xc, yc)
is given by the expression:
d = (a*xc + b*yc + c) / sqrt(a*a + b*b)
or d = (m*xc - yc + c) / sqrt(m*m + 1)
according the the above equation
For infinite lines, you can check if 'd' is less than the radius of the circle. But for finite lines, you'd also have to make sure whether the point of contact is within the line.
Now m = tan(angle). You can have
cos = 1 / sqrt(m*m + 1); sin = m / sqrt(m*m + 1)
Then you can calculate the point of contact as
xp = xc + d*cos; yp = yc + d*sin
And to check whether (xp, yp)
lies in between the points connecting line, you can do a simple check as
if(x1 < xp < x2 && y1 < yp < y2)
return true
depending upon which is greater among x1 x2 and y1 y2.
You can repeat the same algorithm for all the four lines of a rectangle by passing the points.
Please correct me if I'm wrong somewhere.
精彩评论