简体   繁体   English

OBB 和圆之间二维碰撞检测的数学计算

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

I'm creating a 2D game and want to test for collision between an OBB (Oriented Bounding Box) and a Circle.我正在创建一个 2D 游戏并想测试 OBB(定向边界框)和圆之间的碰撞。 I'm unsure of the maths and code to do this.我不确定执行此操作的数学和代码。 I'm creating the game in c++ and opengl.我正在用 c++ 和 opengl 创建游戏。

Since both your shapes are convex, you can use the Separating Axis Theorem .由于您的两个形状都是凸面,因此您可以使用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++.无论如何,在 C++ 中实现它应该是微不足道的。

We will divide the rectangle into 4 finite lines.我们将把矩形分成 4 条有限的线。 We can construct the line equation ax + by + c = 0 connecting the points (x1, y1) and (x2, y2) as follows:我们可以构建连接点(x1, y1)(x2, y2)的线方程ax + by + c = 0如下:

mx - y + c = 0

where m = (y2-y1)/(x2-x1)其中 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:从直线ax + by + c = 0到点(xc, yc)最短(垂直)距离由以下表达式给出:

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 equationd = (m*xc - yc + c) / sqrt(m*m + 1)根据上述等式

For infinite lines, you can check if 'd' is less than the radius of the circle.对于无限长的直线,您可以检查 'd' 是否小于圆的半径。 But for finite lines, you'd also have to make sure whether the point of contact is within the line.但是对于有限线,您还必须确保接触点是否在该线内。

Now m = tan(angle).现在 m = tan(角度)。 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并检查(xp, yp)是否位于连接线之间的点之间,您可以做一个简单的检查

if(x1 < xp < x2 && y1 < yp < y2)
    return true

depending upon which is greater among x1 x2 and y1 y2.取决于 x1 x2 和 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.如果我在某处错了,请纠正我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM