欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

角和矩形的交点

程序员文章站 2022-03-03 11:01:29
import mathimport matplotlib.pyplot as pltdef calc_theta(point1,point2): delta_x=point2[0]-point1[0] delta_y=point2[1]-point1[1] if delta_x>0 : #第一第四象限,直接用反正切函数 return math.atan(delta_y/delta_x) elif delta_x==0 and del...
import math

import matplotlib.pyplot as plt


def calc_theta(point1, point2):
    delta_x = point2[0] - point1[0]
    delta_y = point2[1] - point1[1]
    if delta_x > 0:  # 第一第四象限,直接用反正切函数
        return math.atan(delta_y / delta_x)
    elif delta_x == 0 and delta_y > 0:
        return math.pi / 2
    elif delta_x == 0 and delta_y < 0:
        return -math.pi / 2
    elif delta_y >= 0:
        return math.atan(delta_y / delta_x) + math.pi
    else:
        return math.atan(delta_y / delta_x) - math.pi


def calc_cross(bbox, center, theta1, theta2):
    [xmin, ymin, xmax, ymax] = bbox
    [x, y] = center
    up_right_theta = calc_theta(center, [xmax, ymax])
    up_left_theta = calc_theta(center, [xmin, ymax])
    down_right_theta = calc_theta(center, [xmax, ymin])
    down_left_theta = calc_theta(center, [xmin, ymin])
    # 第一个交点
    if down_right_theta < theta1 < up_right_theta:  # 和(xmax,?)相交,(?-y)/(xmax-x)=tan(theta1)
        cross_point1 = [xmax, math.tan(theta1) * (xmax - x) + y]
        cross_flag1 = 0  # 和x=xmax相交
    elif up_right_theta <= theta1 <= up_left_theta:  # 和(?,ymax)相交,(ymax-y)/(?-x)=tan(theta1)
        cross_point1 = [(ymax - y) / math.tan(theta1) + x, ymax]
        cross_flag1 = 1  # 和y=ymax相交
    elif down_left_theta <= theta1 <= down_right_theta:  # 和(?,ymin)相交,(ymin-y)/(?-x)=tan(theta1)
        cross_point1 = [(ymin - y) / math.tan(theta1) + x, ymin]
        cross_flag1 = 3  # 和y=ymin相交
    else:  # 和(xmin,?)相交,(?-y)/(xmin-x)=tan(theta1)
        cross_point1 = [xmin, math.tan(theta1) * (xmin - x) + y]
        cross_flag1 = 2  # 和x=xmin相交
    # 第二个交点
    if down_right_theta < theta2 < up_right_theta:  # 和(xmax,?)相交,(?-y)/(xmax-x)=tan(theta1)
        cross_point2 = [xmax, math.tan(theta2) * (xmax - x) + y]
        cross_flag2 = 0
    elif up_right_theta <= theta2 <= up_left_theta:  # 和(?,ymax)相交,(ymax-y)/(?-x)=tan(theta1)
        cross_point2 = [(ymax - y) / math.tan(theta2) + x, ymax]
        cross_flag2 = 1
    elif down_left_theta <= theta2 <= down_right_theta:  # 和(?,ymin)相交,(ymin-y)/(?-x)=tan(theta1)
        cross_point2 = [(ymin - y) / math.tan(theta2) + x, ymin]
        cross_flag2 = 3
    else:  # 和(xmin,?)相交,(?-y)/(xmin-x)=tan(theta1)
        cross_point2 = [xmin, math.tan(theta2) * (xmin - x) + y]
        cross_flag2 = 2

    return {"points": [cross_point1, cross_point2], "flag": [cross_flag1, cross_flag2]}


def make_polygon(bbox, center, cross_point, cross_flag):
    [xmin, ymin, xmax, ymax] = bbox
    cross_point1 = cross_point[0]
    cross_point2 = cross_point[1]
    cross_flag1 = cross_flag[0]  #
    cross_flag2 = cross_flag[1]

    if cross_flag1 == 0 and cross_flag2 == 0:
        if cross_point1[1] < cross_point2[1]:
            point_list = [center, cross_point1, cross_point2]
        else:
            point_list = [center, cross_point1, [xmax, ymax], [xmin, ymax], [xmin, ymin], [xmax, ymin], cross_point2]
    elif cross_flag1 == 0 and cross_flag2 == 1:
        point_list = [center, cross_point1, [xmax, ymax], cross_point2]
    elif cross_flag1 == 0 and cross_flag2 == 2:
        point_list = [center, cross_point1, [xmax, ymax], [xmin, ymax], cross_point2]
    elif cross_flag1 == 0 and cross_flag2 == 3:
        point_list = [center, cross_point1, [xmax, ymax], [xmin, ymax], [xmin, ymin], cross_point2]

    elif cross_flag1 == 1 and cross_flag2 == 0:
        point_list = [center, cross_point1, [xmin, ymax], [xmin, ymin], [xmax, ymin], cross_point2]
    elif cross_flag1 == 1 and cross_flag2 == 1:
        if cross_point1[0] > cross_point2[0]:
            point_list = [center, cross_point1, cross_point2]
        else:
            point_list = [center, cross_point1, [xmin, ymax], [xmin, ymin], [xmax, ymin], [xmax, ymax], cross_point2]
    elif cross_flag1 == 1 and cross_flag2 == 2:
        point_list = [center, cross_point1, [xmin, ymax], cross_point2]
    elif cross_flag1 == 1 and cross_flag2 == 3:
        point_list = [center, cross_point1, [xmin, ymax], [xmin, ymin], cross_point2]

    elif cross_flag1 == 2 and cross_flag2 == 0:
        point_list = [center, cross_point1, [xmin, ymin], [xmax, ymin], cross_point2]
    elif cross_flag1 == 2 and cross_flag2 == 1:
        point_list = [center, cross_point1, [xmin, ymin], [xmax, ymin], [xmax, ymax], cross_point2]
    elif cross_flag1 == 2 and cross_flag2 == 2:
        if cross_point1[1] > cross_point2[1]:
            point_list = [center, cross_point1, cross_point2]
        else:
            point_list = [center, cross_point1, [xmin, ymin], [xmax, ymin], [xmax, ymax], [xmin, ymax], cross_point2]
    elif cross_flag1 == 2 and cross_flag2 == 3:
        point_list = [center, cross_point1, [xmin, ymin], cross_point2]

    elif cross_flag1 == 3 and cross_flag2 == 0:
        point_list = [center, cross_point1, [xmax, ymin], cross_point2]
    elif cross_flag1 == 3 and cross_flag2 == 1:
        point_list = [center, cross_point1, [xmax, ymin], [xmax, ymax], cross_point2]
    elif cross_flag1 == 3 and cross_flag2 == 2:
        point_list = [center, cross_point1, [xmax, ymin], [xmax, ymax], [xmin, ymax], cross_point2]
    else:
        if cross_point1[0] < cross_point2[0]:
            point_list = [center, cross_point1, cross_point2]
        else:
            point_list = [center, cross_point1, [xmax, ymin], [xmax, ymax], [xmin, ymax], [xmin, ymin], cross_point2]

    return point_list

def angle_intersect_rectangle(bbox,center,theta1,theta2):
    dic=calc_cross(bbox,center,theta1,theta2)
    cross_point=dic["points"]
    cross_flag=dic["flag"]
    return make_polygon(bbox,center,cross_point,cross_flag)

while 1:
    # bbox=[xmin,ymin,xmax,ymax]
    bbox = eval(input("输入bbox:"))
    [xmin, ymin, xmax, ymax] = bbox
    # center=[xc,yc]
    center = eval(input("输入center:"))

    th1 = eval(input("输入角度1:"))
    th2 = eval(input("输入角度2:"))

    theta1 = th1 / 180 * math.pi
    theta2 = th2 / 180 * math.pi



    point_list =angle_intersect_rectangle(bbox, center,theta1, theta2)

    x = []
    y = []
    for p in point_list:
        x.append(p[0])
        y.append(p[1])

    x.append(point_list[0][0])
    y.append(point_list[0][1])



    plt.figure(num=3, figsize=(8, 5))
    plt.plot([xmax, xmin, xmin, xmax, xmax], [ymax, ymax, ymin, ymin, ymax], color="red")
    plt.plot(x, y, color="yellow")
    plt.show()

上述代码可稍作修改将矩形也画出,便于观察。下面是几个实验结果:
角和矩形的交点
角和矩形的交点
角和矩形的交点

本文地址:https://blog.csdn.net/qq_40268672/article/details/107674760