在python中使用两个左下角和右上角检查两个矩形是否重叠

q43xntqr  于 2023-02-17  发布在  Python
关注(0)|答案(7)|浏览(413)
class Point:

    def __init__(self, xcoord=0, ycoord=0):
        self.x = xcoord
        self.y = ycoord

class Rectangle:
    def __init__(self, bottom_left, top_right, colour):
        self.bottom_left = bottom_left
        self.top_right = top_right
        self.colour = colour

    def intersects(self, other):

我试图看看是否两个矩形相交的基础上,右上角和左下角,但当我使函数:

def intersects(self, other):
    return self.top_right.x>=other.top_right.x>=self.bottom_left.x and self.top_right.x>=other.bottom_left.x>=self.bottom_left.x and self.top_right.y>=other.top_right.y>=self.bottom_left.y and self.top_right.x>=other.bottom_left.x>=self.bottom_left.x

函数在输入以下内容时返回false:

r1=Rectangle(Point(1,1), Point(2,2), 'blue')
r3=Rectangle(Point(1.5,0), Point(1.7,3), 'red')
r1.intersects(r3)

进入壳内。

rqenqsqc

rqenqsqc1#

您可以使用Separating Axis Theorem的一个简单版本来测试相交。如果两个矩形不相交,那么至少有一个右边会在另一个矩形左边的左边(即它将是一个分隔轴),反之亦然,或者一个上边会在另一个矩形下边的下面,反之亦然。
因此,更改测试以检查它们是否不相交:

def intersects(self, other):
    return not (self.top_right.x < other.bottom_left.x or self.bottom_left.x > other.top_right.x or self.top_right.y < other.bottom_left.y or self.bottom_left.y > other.top_right.y)

这段代码假设“top”的y值大于“bottom”(y值在屏幕上向下递减),因为你的例子看起来就是这样的,如果你使用另一种约定,那么你只需要翻转y比较的符号。

2cmtqfgy

2cmtqfgy2#

我最近遇到了这个问题,今天又遇到了命名元组,所以我想试试看:

from collections import namedtuple

RECT_NAMEDTUPLE = namedtuple('RECT_NAMEDTUPLE', 'x1 x2 y1 y2')

Rect1 = RECT_NAMEDTUPLE(10,100,40,80)
Rect2 = RECT_NAMEDTUPLE(20,210,10,60)

def overlap(rec1, rec2):
  if (rec2.x2 > rec1.x1 and rec2.x2 < rec1.x2) or \
     (rec2.x1 > rec1.x1 and rec2.x1 < rec1.x2):
    x_match = True
  else:
    x_match = False
  if (rec2.y2 > rec1.y1 and rec2.y2 < rec1.y2) or \
     (rec2.y1 > rec1.y1 and rec2.y1 < rec1.y2):
    y_match = True
  else:
    y_match = False
  if x_match and y_match:
    return True
  else:
    return False

print ("Overlap found?", overlap(Rect1, Rect2))

Overlap found? True
shstlldc

shstlldc3#

也可以使用shapely中的多边形(例如,具有[x0,y0,x1,y1]的矩形)完成此操作

from shapely.geometry import Polygon
import numpy as np

rect1=np.array([0  ,0 ,3,  3])
rect2=np.array([1, 1 , 4 , 4])

def overlap2(rect1,rect2):
    p1 = Polygon([(rect1[0],rect1[1]), (rect1[1],rect1[1]),(rect1[2],rect1[3]),(rect1[2],rect1[1])])
    p2 = Polygon([(rect2[0],rect2[1]), (rect2[1],rect2[1]),(rect2[2],rect2[3]),(rect2[2],rect2[1])])
    return(p1.intersects(p2))

print(overlap2(rect1,rect2))
iovurdzv

iovurdzv4#

下面是您在编写代码之前可以做的事情:1.考虑两个矩形不重叠的情况2.首先选择每种颜色编码x和y的配对比较。例如,比较rectangle.A.X1并将其与Rectangle.B.X2进行比较
下面是代码

def check_for_overlap():
    rectangle_a  = {"x1":15, "y1":10, "x2":10,"y2":5}
    rectangle_b  = {"x1": 25, "y1":10, "x2":20,"y2":5}
    #black color                           or    red color
    if(rectangle_a["y1"]<rectangle_b["y2"] or rectangle_a["x1"]<rectangle_b["x2"]):
        print("no overlap ")
    #the blue color                          or   green 
    elif(rectangle_a["x2"]>rectangle_b["x1"] or rectangle_a["y2"]>rectangle_b["y1"]):
        print("no overlap ")
    else:
        print("YES ! there is a overlap")

check_for_overlap()

tv6aics1

tv6aics15#

比较我找到的所有答案,@samgak answer是最好的。

def is_overlapping_1D(line1, line2):
    """
    line:
        (xmin, xmax)
    """
    return line1[0] <= line2[1] and line2[0] <= line1[1]

def is_overlapping_2d(box1, box2):
    """
    box:
        (xmin, ymin, xmax, ymax)
    """
    return is_overlapping_1D([box1[0],box1[2]],[box2[0],box2[2]]) and is_overlapping_1D([box1[1],box1[3]],[box2[1],box2[3]])

from shapely.geometry import Polygon
def overlap2(box1, box2):
    p1 = Polygon([(box1[0],box1[1]), (box1[0],box1[3]), (box1[2],box1[3]),(box1[2],box1[1])])
    p2 = Polygon([(box2[0],box2[1]), (box2[0],box2[3]), (box2[2],box2[3]),(box2[2],box2[1])])
    return p1.intersects(p2)

def intersects(box1, box2):
    return not (box1[2] < box2[0] or box1[0] > box2[2] or box1[1] > box2[3] or box1[3] < box2[1])
# xyxy (xmin, xmax, ymin, ymax)
boxes = [
    (200,70,240,110),
    (10,10,60,60),
    (30,20,70,60),
    (100, 90, 190, 180),
    (50,100,150,200),
    (180,190,220,230),
    (10,210,40,240)
]
%%timeit
boxes_merged = iterate_merge(intersects, unify, boxes)

%%timeit
boxes_merged = iterate_merge(overlap2, unify, boxes)

%%timeit
boxes_merged = iterate_merge(is_overlapping_2d, unify, boxes)
67.5 µs ± 313 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

924 µs ± 1.12 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

83.1 µs ± 223 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
slhcrj9b

slhcrj9b6#

我所做的就是找出哪个矩形在顶部,哪个在底部;还有哪个在左边,哪个在右边。最后,我们讨论的是我们正在比较的两个相同的矩形。但是获得右/左和上/下有助于简化条件。一旦我们获得了右/左和上/下,我们就可以比较重叠、非重叠和包含。

class Rectangle:
# Create rectangle with center at (x, y)
# width x, and height h

    def __init__(self, x, y, w, h):
    self._x = float(x)
    self._y = float(y)
    self._width = float(w)
    self._height = float(h)
    # Extended four instance variables
    self._x0 = self._x - self._width / 2
    self._x1 = self._x + self._width / 2
    self._y0 = self._y - self._height / 2
    self._y1 = self._y + self._height/2
    # True if self intersects other; False otherwise
    def intersects(self, other):

        # find which rectangle is on the left
        leftRec = None
        rightRec = None
        if self._x1 >= other._x1:
            leftRec = other
            rightRec = self
        else:
            leftRec = self
            rightRec = other

        # find which rectangle is on the top
        topRec = None
        lowRec = None
        if self._y1 >= other._y1:
            topRec = self
            lowRec = other
        else:
            topRec = other
            lowRec = self

        if (leftRec._x0 + leftRec._width <= rightRec._x0) or (lowRec._y0 + lowRec._height <= topRec._y0):
            # Not overlap
            return False
        elif (leftRec._x0 + leftRec._width <= rightRec._x0 + rightRec._width) or (lowRec._y0 + lowRec._height <= topRec._y0 + topRec._height):
            # full overlap, contains
            return False
        else:
            # intersect
            return True

基本上,如果左矩形的左下x值加上其宽度小于右矩形的左下x值,则它是不重叠的。如果左矩形的左下x值加上其宽度小于或等于右矩形的左下x值加上其宽度,则右矩形与左矩形完全重叠。除此之外,这就是交集。上下比较,然后合并起来,你就能找到交集。

7vux5j2d

7vux5j2d7#

这里有很棒的解决方案,但我还没有看到任何以模式(top_x,top_y)作为左上角点和(bottom_x,bottom_y)作为边界框右下角点的解决方案。我想分享一个分析该模式的解决方案,尽管您可以从该模式中推断出右上角和左下角点,并使用上述解决方案。
下面是代码:

def bbox_intersect(bbox_a, bbox_b):
    (a_top_x, a_top_y), (a_bot_x, a_bot_y) = bbox_a
    (b_top_x, b_top_y), (b_bot_x, b_bot_y) = bbox_b
    
    cond_1 = a_top_x < b_top_x < a_bot_x
    cond_2 = b_top_x < a_top_x < b_bot_x
    cond_3 = a_top_y < b_top_y < a_bot_y
    cond_4 = b_top_y < a_top_y < b_bot_y
    
    return (cond_1 or cond_2) and (cond_3 or cond_4)

相关问题