用Ci检测矩形碰撞

2024-03-29 05:17:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个圆心(中心X,中心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)

但好像排不上队。我做错什么了吗?


Tags: 区域if半径bluewindow中心pygamecenter
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. 一个顶点可以在另一个顶点内
  2. 他们的两边可以交叉(即使认为里面没有真凭实据)
  3. 一个可以完全在另一个内部。

从技术上讲,案例1。只有在情况2时才能发生。也会发生,但这通常是一种更便宜的支票。 在同时检查两个对象顶点的情况下,情况3由情况1检查。

我想这样继续。(按便宜程度排列)

  1. 检查它们的边界框是否相交。
  2. 检查正方形的任何顶点是否在
  3. 检查圆的中心是否在矩形内
  4. 检查圆边交叉点。

第二种也是更普遍的方法是基于形状的乘积/展开的概念。 此操作允许您将交叉点问题转换为点包含问题。

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

使用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

相关问题 更多 >