直线和矩形是否相交(方法一)
class Intersection(object):
'''计算直线和矩形是否相交'''
@classmethod
def cross_product(cls, x1, y1, x2, y2, x3, y3):
return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)
@classmethod
def is_intersecting(cls, x1, y1, x2, y2, x3, y3, x4, y4):
d1 = cls.cross_product(x1, y1, x2, y2, x3, y3)
d2 = cls.cross_product(x1, y1, x2, y2, x4, y4)
d3 = cls.cross_product(x3, y3, x4, y4, x1, y1)
d4 = cls.cross_product(x3, y3, x4, y4, x2, y2)
if ((d1 * d2 < 0) and (d3 * d4 < 0)):
return True
if (d1 == 0 and min(x1, x2) <= x3 <= max(x1, x2) and min(y1, y2) <= y3 <= max(y1, y2)) or \
(d2 == 0 and min(x1, x2) <= x4 <= max(x1, x2) and min(y1, y2) <= y4 <= max(y1, y2)) or \
(d3 == 0 and min(x3, x4) <= x1 <= max(x3, x4) and min(y3, y4) <= y1 <= max(y3, y4)) or \
(d4 == 0 and min(x3, x4) <= x2 <= max(x3, x4) and min(y3, y4) <= y2 <= max(y3, y4)):
return True
return False
@classmethod
def line_intersects_rectangle(cls, x1, y1, x2, y2, pxmin, pymin, pxmax, pymax):
edges = [
(pxmin, pymin, pxmin, pymax),
(pxmax, pymin, pxmax, pymax),
(pxmin, pymin, pxmax, pymin),
(pxmin, pymax, pxmax, pymax)
]
for edge in edges:
if cls.is_intersecting(x1, y1, x2, y2, *edge):
return True
return False
@classmethod
def is_line_intersect_rect(cls, line, rect):
'''计算直线和矩形是否相交'''
x1, y1, x2, y2 = line
pxmin, pymin, pxmax, pymax = rect
return cls.line_intersects_rectangle(x1, y1, x2, y2, pxmin, pymin, pxmax, pymax)
line = [500, 0, 500, 500]
rect = [271, 191, 672, 720]
result = Intersection.is_line_intersect_rect(line, rect)
print(f"直线与矩形是否相交: {result}")
直线和矩形是否相交(方法二)
def is_line_intersect_rect(line, rect):
x1, y1, x2, y2 = line
x3, y3, x4, y4 = rect
if (max(x1, x2) < min(x3, x4)) or (max(x3, x4) < min(x1, x2)) or \
(max(y1, y2) < min(y3, y4)) or (max(y3, y4) < min(y1, y2)):
return False
def cross_product(x1, y1, x2, y2, x3, y3):
return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)
d1 = cross_product(x1, y1, x2, y2, x3, y3)
d2 = cross_product(x1, y1, x2, y2, x4, y3)
d3 = cross_product(x1, y1, x2, y2, x4, y4)
d4 = cross_product(x1, y1, x2, y2, x3, y4)
line_cross_rect = ((d1 < 0 and d3 > 0) or (d1 > 0 and d3 < 0)) or ((d2 < 0 and d4 > 0) or (d2 > 0 and d4 < 0))
rect_vertices_on_line = (d1 == 0 and (x3 >= min(x1, x2) and x3 <= max(x1, x2) and y3 >= min(y1, y2) and y3 <= max(y1, y2))) or \
(d2 == 0 and (x4 >= min(x1, x2) and x4 <= max(x1, x2) and y3 >= min(y1, y2) and y3 <= max(y1, y2))) or \
(d3 == 0 and (x4 >= min(x1, x2) and x4 <= max(x1, x2) and y4 >= min(y1, y2) and y4 <= max(y1, y2))) or \
(d4 == 0 and (x3 >= min(x1, x2) and x3 <= max(x1, x2) and y4 >= min(y1, y2) and y4 <= max(y1, y2)))
return line_cross_rect or rect_vertices_on_line
line = [500, 0, 500, 500]
rect = [1193, 167, 1280, 716]
result = is_line_intersect_rect(line, rect)
print(f"直线与矩形是否相交: {result}")
判断一个矩形是否在另一个矩形内
def is_rect_inside(rect1, rect2):
"""
判断 rect1 是否在 rect2 内
:param rect1: 第一个矩形,格式为 [x1, y1, x2, y2],(x1, y1) 是左上角坐标,(x2, y2) 是右下角坐标
:param rect2: 第二个矩形,格式为 [x3, y3, x4, y4],(x3, y3) 是左上角坐标,(x4, y4) 是右下角坐标
:return: 如果 rect1 在 rect2 内返回 True,否则返回 False
"""
x1, y1, x2, y2 = rect1
x3, y3, x4, y4 = rect2
return x1 >= x3 and y1 >= y3 and x2 <= x4 and y2 <= y4
rect1 = [20, 20, 40, 40]
rect2 = [10, 10, 50, 50]
result1 = is_rect_inside(rect1, rect2)
print(f"rect1 是否在 rect2 内(示例 1): {result1}")
rect3 = [30, 30, 60, 60]
rect4 = [10, 10, 50, 50]
result2 = is_rect_inside(rect3, rect4)
print(f"rect3 是否在 rect4 内(示例 2): {result2}")
rect5 = [10, 10, 50, 50]
rect6 = [10, 10, 50, 50]
result3 = is_rect_inside(rect5, rect6)
print(f"rect5 是否在 rect6 内(示例 3): {result3}")
计算矩形和矩形相交(不含嵌套)
def is_rectangles_intersect(rect1, rect2):
"""
判断两个矩形是否相交且不嵌套
:param rect1: 第一个矩形,格式为 [x1, y1, x2, y2],(x1, y1) 是左上角坐标,(x2, y2) 是右下角坐标
:param rect2: 第二个矩形,格式为 [x3, y3, x4, y4],(x3, y3) 是左上角坐标,(x4, y4) 是右下角坐标
:return: 如果相交且不嵌套返回 True,否则返回 False
"""
x1, y1, x2, y2 = rect1
x3, y3, x4, y4 = rect2
if (x2 < x3) or (x4 < x1) or (y2 < y3) or (y4 < y1):
return False
is_rect1_inside_rect2 = x1 >= x3 and y1 >= y3 and x2 <= x4 and y2 <= y4
is_rect2_inside_rect1 = x3 >= x1 and y3 >= y1 and x4 <= x2 and y4 <= y2
if is_rect1_inside_rect2 or is_rect2_inside_rect1:
return False
return True
rect1 = [10, 10, 50, 50]
rect2 = [30, 30, 70, 70]
result = is_rectangles_intersect(rect1, rect2)
print(f"两个矩形是否相交且不嵌套: {result}")