角和矩形的交点
程序员文章站
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