开发者

The Maths for 2D Collision Detection between an OBB and a Circle

开发者 https://www.devze.com 2022-12-23 09:34 出处:网络
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 开发者_Stack

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消