我的程序中有一个圆圈和一个矩形在表面上移动。我想知道一个圆圈和一个矩形是否相互接触。它必须非常准确。对不解释它的细节我很抱歉,但我希望你理解。
考虑一个轴对齐的矩形由左上角原点和宽度和高度给出:
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