📅  最后修改于: 2023-12-03 15:27:35.799000             🧑  作者: Mango
在开发过程中,我们经常会遇到需要判断给定点是否在矩形内的场景。下面我们就来介绍一种判断算法。
根据矩形四个顶点坐标,将矩形分成四个三角形,然后利用点与向量的叉积关系来判断点是否在矩形内。
def is_point_in_rect(point, rect):
"""
判断给定点是否在矩形内
:param point: 给定点坐标,格式为(x, y)
:param rect: 矩形坐标,格式为(x1, y1, x2, y2),其中(x1,y1)为左上角坐标,(x2,y2)为右下角坐标
:return: 若点在矩形内,则返回True,否则返回False
"""
x_min = min(rect[0], rect[2])
x_max = max(rect[0], rect[2])
y_min = min(rect[1], rect[3])
y_max = max(rect[1], rect[3])
if point[0] < x_min or point[0] > x_max or point[1] < y_min or point[1] > y_max:
return False
# 将矩形分为四个三角形
A = (rect[0], rect[1])
B = (rect[0], rect[3])
C = (rect[2], rect[3])
D = (rect[2], rect[1])
# 判断点是否在ABC、ACD、ABD、CBD三角形内
if in_triangle(point, A, B, C) or in_triangle(point, A, C, D) or in_triangle(point, A, B, D) or in_triangle(point, C, B, D):
return True
return False
def in_triangle(point, A, B, C):
"""
判断点是否在三角形内
:param point: 给定点坐标,格式为(x, y)
:param A: 三角形第一个点坐标,格式为(x, y)
:param B: 三角形第二个点坐标,格式为(x, y)
:param C: 三角形第三个点坐标,格式为(x, y)
:return: 若点在三角形内,则返回True,否则返回False
"""
# 利用向量的叉积关系判断点与三角形的位置关系
if (cross_product(A, B, point) > 0 and cross_product(B, C, point) > 0 and cross_product(C, A, point) > 0) \
or (cross_product(A, B, point) < 0 and cross_product(B, C, point) < 0 and cross_product(C, A, point) < 0):
return True
else:
return False
def cross_product(A, B, C):
"""
计算向量AB与向量AC的叉积
:param A: 向量起点,格式为(x, y)
:param B: 向量终点,格式为(x, y)
:param C: 给定点坐标,格式为(x, y)
:return: 叉积大小,若为正数则表示C在向量AB左侧,反之在右侧
"""
return (B[0] - A[0]) * (C[1] - A[1]) - (C[0] - A[0]) * (B[1] - A[1])
if __name__ == '__main__':
# 正方形测试
rect = (0, 0, 10, 10) # 左上角坐标为(0,0),右下角坐标为(10,10)
assert is_point_in_rect((5, 5), rect) == True # 点(5,5)在正方形内
assert is_point_in_rect((5, 15), rect) == False # 点(5,15)在正方形上面
assert is_point_in_rect((5, -5), rect) == False # 点(5,-5)在正方形下面
assert is_point_in_rect((-5, 5), rect) == False # 点(-5,5)在正方形左边
assert is_point_in_rect((15, 5), rect) == False # 点(15,5)在正方形右边
# 长方形测试
rect = (0, 0, 10, 20) # 左上角坐标为(0,0),右下角坐标为(10,20)
assert is_point_in_rect((5, 10), rect) == True # 点(5,10)在长方形内
assert is_point_in_rect((5, 30), rect) == False # 点(5,30)在长方形上面
assert is_point_in_rect((5, -10), rect) == False # 点(5,-10)在长方形下面
assert is_point_in_rect((-5, 10), rect) == False # 点(-5,10)在长方形左边
assert is_point_in_rect((15, 10), rect) == False # 点(15,10)在长方形右边
以上就是判断给定点是否在矩形内的算法,希望对大家有所帮助。