📌  相关文章
📜  给定点的矩形坐标在里面(1)

📅  最后修改于: 2023-12-03 15:27:35.799000             🧑  作者: Mango

判断给定点是否在矩形内的算法

在开发过程中,我们经常会遇到需要判断给定点是否在矩形内的场景。下面我们就来介绍一种判断算法。

算法思路

根据矩形四个顶点坐标,将矩形分成四个三角形,然后利用点与向量的叉积关系来判断点是否在矩形内。

详细步骤
  1. 判断给定点的x坐标是否在矩形左右两侧,若是则点不在矩形内。
  2. 判断给定点的y坐标是否在矩形上下两侧,若是则点不在矩形内。
  3. 根据矩形的四个顶点坐标,将矩形分成四个三角形,分别为A、B、C、D三角形。
  4. 利用向量的叉积关系判断给定点坐标与A、B、C、D三角形的关系,判断给定点是否在矩形内。
代码实现
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)在长方形右边
结语

以上就是判断给定点是否在矩形内的算法,希望对大家有所帮助。