用圆检测矩形碰撞

时间:2014-07-13 23:19:23

标签: python pygame collision-detection geometry

我有一个带有中心点的圆(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)

但它似乎并不排队。有什么我做错了吗?

3 个答案:

答案 0 :(得分:3)

以下是我在评论中所描述的内容,以及对Michael Anderson在评论中指出的更大矩形内正确处理圆形情况的更改:

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

答案 1 :(得分:1)

这种碰撞检测有两种常见的选择。

首先要了解两个2D物体可能碰撞的方式。

  1. 一个顶点可以在另一个
  2. 他们的双方可以交叉(甚至认为里面没有任何内容)
  3. 一个可以完全在另一个内部。
  4. 技术案例1.只有在情况2发生时才会发生,但通常是更便宜的检查。 在检查两个对象顶点的情况下,情况1也检查情况3。

    我会这样做。 (因为它是廉价的顺序)

    1. 检查他们的边界框是否相交。
    2. 检查方块的任何顶点是否在
    3. 检查圆的中心是否在矩形内
    4. 检查圆边交叉点。
    5. 第二种更通用的方法是基于产品/形状扩展的概念。 此操作允许您将交叉点问题转换为点遏制问题。

      在这种情况下,圆形/矩形框交叉点可以替换为圆角矩形中的点的检查。

答案 2 :(得分:1)

使用Shortest distance between a point and a line segment

中的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