import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import math
import random
def generate_nonuniform_convex_polygon_points(n):
if n < 3:
raise ValueError("n must be greater than or equal to 3 for a convex polygon.")
# 生成不同的边长
side_lengths = [random.uniform(1, 20) for _ in range(n)]
# 计算角度增量
angle_increment = 2 * math.pi / n
x_coords = []
y_coords = []
for i in range(n):
angle = i * angle_increment
x = side_lengths[i] * math.cos(angle)
y = side_lengths[i] * math.sin(angle)
x_coords.append(x)
y_coords.append(y)
# 添加第一个点闭合多边形和第二个点以求最后一个外扩点
x_coords.append(x_coords[0])
x_coords.append(x_coords[1])
y_coords.append(y_coords[0])
y_coords.append(y_coords[1])
return x_coords, y_coords
# 指定边数
n = 7
# 生成凸多边形的坐标
x, y = generate_nonuniform_convex_polygon_points(n)
z = list(map(list, zip(x, y)))
# 画原始图形
plt.plot(x, y, marker='o', linestyle='-')
# 求两条直线的方向向量a和方向向量b
def xl(p0, p1, p2): # 此处的p0,p1,p2是(xi,yi)形式
a = list(map(lambda x: x[0] - x[1], zip(p0, p1))) # a是怕p0_p1的向量;
b = list(map(lambda x: x[0] - x[1], zip(p1, p2))) # b是篇p1_p2的向量
return a, b
# 求两条直线的单位法向量afa,bfa
def fa(a, b):
# a法向量
afa = np.dot(np.array([[0, -1], [1, 0]]), a)
afa = afa / np.linalg.norm(afa)
# b法向量
bfa = np.dot(np.array([[0, -1], [1, 0]]), b) # 顺时针旋转向量90°
bfa = bfa / np.linalg.norm(bfa)
return afa, bfa
# 求两直线交点坐标 输入分别为向量a[,],扩张后a上点[,],向量b[,],扩张后b上点[,]
# 参数方程求交点
def j(a, ak, b, bk):
#踩雷
# theta1 = a[0] / math.sqrt((a[0] ** 2) + a[1] ** 2)
# theta2 = b[0] / math.sqrt((b[0] ** 2) + b[1] ** 2)
# t2 = (ak[0] - bk[0]) / (theta2 - (ak[0] - bk[0])/(ak[1] - bk[1]) * theta1)
# x0 = bk[0] + t2 * theta2
# y0 = bk[1] + t2 * theta2
A = np.array([[b[0], -a[0]], [b[1], -a[1]]])
X = np.array([[ak[0] - bk[0]], [ak[1] - bk[1]]])
Ani = np.linalg.inv(A)
T = np.dot(Ani, X)
x0 = bk[0] + T[0] * b[0]
y0 = bk[1] + T[0] * b[1]
return x0, y0
def expend(z, l):
n = len(z)
xkuo = [] # 保存扩张后交点的横坐标
ykuo = [] # 保存扩张后交点的纵坐标
for i in range(0, n-2):
xli = xl(z[i], z[i+1], z[i+2])
xli = list(map(list, xli)) # 将xli转化为嵌套列表的形式
faxl = fa(xli[0], xli[1])
# 扩张后a,b上一点
ak = list(map(lambda x: x[0] + x[1], zip(faxl[0] * l, z[i+1])))
bk = list(map(lambda x: x[0] + x[1], zip(faxl[1] * l, z[i+1])))
xj = j(xli[0], ak, xli[1], bk)
xkuo.append(xj[0])
ykuo.append(xj[1])
xkuo.append(xkuo[0]) # 添加第一个交点横坐标闭合多边形
ykuo.append(ykuo[0]) # 添加第一个交点纵坐标闭合多边形
# print(xkuo)
# print(ykuo)
plt.plot(xkuo, ykuo, marker='o', linestyle='-')
plt.show()
# if __name__ == '__main__':
expend(z,2)
多边形外扩——by Liang
最新推荐文章于 2024-07-06 16:25:50 发布