我怎么知道Pygame中是否触及了圆圈和矩形?

问题描述 投票:2回答:1

我的程序中有一个圆圈和一个矩形在表面上移动。我想知道一个圆圈和一个矩形是否相互接触。它必须非常准确。对不解释它的细节我很抱歉,但我希望你理解。

python pygame circle rect
1个回答
1
投票

考虑一个轴对齐的矩形由左上角原点和宽度和高度给出:

rect_tl   = (x, y)
rect_size = (width, height)

并且圆圈由中心点和半径给出:

circle_cpt = (x, y)
circle_rad = r

如果你想测试这两个形状是否相交,那么为了捕捉所有可能的情况,必须进行2次测试。

首先,如果圆的中心点在矩形内,则必须进行测试。这可以通过pygame.Rect.collidepoint轻松完成:

rect = pygame.Rect(*rect_tl, *rect_size)
isIsect = rect.collidepoint(*circle_cpt)

此外,如果矩形的any角点在圆圈内,则必须进行测试。如果角点和圆的中心点之间的距离小于或等于圆的半径,则情况就是这样。一个点可以用pygame.math.Vector2表示,2点之间的距离可以通过pygame.math.Vector2.distance_to()获得:

centerPt = pygame.math.Vector2(*circle_cpt)
cornerPts = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
isIsect = any([p for p in cornerPts if pygame.math.Vector2(*p).distance_to(centerPt) <= circle_rad])

结合两个测试的函数可能如下所示:

def isectRectCircle(rect_tl, rect_size, circle_cpt, circle_rad):

    rect = pygame.Rect(*rect_tl, *rect_size)
    if rect.collidepoint(*circle_cpt):
        return True

    centerPt = pygame.math.Vector2(*circle_cpt)
    cornerPts = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
    if [p for p in cornerPts if pygame.math.Vector2(*p).distance_to(centerPt) <= circle_rad]:
        return True

    return False
© www.soinside.com 2019 - 2024. All rights reserved.