import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import math
import random
# 最后一个坐标与第一个坐标重合,目的是为了连成闭合环折线
# dis 边平行外扩的距离
# 五边形
# x = [0, 0, 1, 2, 2, 0]
# y = [0, 1, 2, 1, 0, 0]
# dis = 1
# 6边形
# x = [294, 233, 184, 233, 294, 343, 294]
# y = [262, 262, 111, 75, 75, 111, 262]
# dis = 100
# 7边形
x = [8.436253836097336, 6.9836432412046205, -4.099978618084548, -14.633368178499788, -3.719587185521087, -0.774194225877325, 11.370708546243407, 8.436253836097336]
y = [0.0, 8.757211636856805, 17.963180016600237, 7.047058702431258, -1.7912587809886855, -3.391966530241074, -14.25841752811158, 0.0]
dis = 5
# 11边形
# x = [1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5, 0, 0.5,1]
# y = [0, 0.5, 0.866, 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866,0]
# dis = 2.5
# 绘制原折线图
plt.plot(x, y, marker='o', linestyle='-')
# 根据相邻点,以AX+BY+C=0(A>=0)形式获得直线表达式
def expr(hori, vect):
con_x, con_y, cons, M = [], [], [], [0, 0]
sum_x, sum_y = 0, 0
for i in range(len(hori) - 1):
con_x.extend([vect[i + 1] - vect[i]])
con_y.extend([hori[i] - hori[i + 1]])
cons.extend([-hori[i] * vect[i + 1] + hori[i + 1] * vect[i]])
if con_x[i] < 0: # 确保A>=0
con_x[i] *= -1
con_y[i] *= -1
cons[i] *= -1
print(f"第{i + 1}条直线的表达式是:{con_x[i]}X+{con_y[i]}Y+{cons[i]} = 0")
# 求凸多边形的重心
sum_x += hori[i] # 各顶点横坐标之和
sum_y += vect[i] # 各顶点横坐标之和
M[0] = sum_x / (len(hori) - 1)
M[1] = sum_y / (len(hori) - 1)
return con_x, con_y, cons, tuple(M)
# A,B,C 是原直线表达式的系数和参数
A, B, C, M = expr(x, y)
# print('\n',A,'\n', B,'\n', C,'\n', M,'\n')
# 根据重心相对边直线的位置,判断直线移动的方向
D = []
for i in range(len(x) - 1):
d = A[i] * M[0] + B[i] * M[1] + C[i]
D.extend([d])
for values in D:
print(f'重心相对于第{i+1}条直线的方位是:{"left" if values<0 else "right"}') # D<0,说明在左侧,D>0,说明在右侧
C_1 = [] # 外扩后直线的常数项
for i in range(len(B)):
delta_c = 0
if B[i] is not 0:
delta_c = dis * math.sqrt(1 + (A[i] / B[i]) * (A[i] / B[i]))
if B[i] * D[i] > 0:
pass
else:
delta_c *= (-1)
C_1.extend([C[i] + B[i] * delta_c])
else:
if D[i] > 0:
delta_c = A[i] * dis
else:
delta_c = (-1) * A[i] * dis
C_1.extend([C[i] + delta_c])
print(f'\n',f'平移后的直线常数项是:{C_1}',f'\n')
for i in range(len(C_1)):
print(f'外扩后,第{i + 1}条直线表达式是{A[i]}X+{B[i]}Y+{C_1[i]} = 0')
# 已知外扩后的边直线表达式,求其交点坐标
def to_point(lis):
lis_1 = lis.copy()
lis_1.extend([lis[0]])
return lis_1
A_f = to_point(A)
B_f = to_point(B)
C_f = to_point(C_1)
# print(len(A_f), len(B_f), len(C_f))
X, Y = [], []
for i in range(len(A_f) - 1):
# 相邻两条边直线有交点,其分母天然不为0,
val_Y = (C_f[i] * A_f[i + 1] - C_f[i + 1] * A_f[i]) / (B_f[i + 1] * A_f[i] - B_f[i] * A_f[i + 1])
val_X = (B_f[i + 1] * C_f[i] - B_f[i] * C_f[i + 1]) / (B_f[i] * A_f[i + 1] - B_f[i + 1] * A_f[i])
Y.extend([val_Y]) # 获得外扩后的坐标点
X.extend([val_X])
# print(f'外扩后的全部坐标点的横坐标是{X}','\n',f'外扩后的全部坐标点的纵坐标是{Y}') # 输出外扩后的全部坐标点
print(f'\n')
aft_points = tuple(zip(X,Y))
print(f'外扩后的坐标点的坐标为:{aft_points}')
print(f'\n')
X.extend([X[0]])
Y.extend([Y[0]]) # 将外扩后的坐标连成环线
plt.plot(X, Y, marker='o', linestyle='-')
plt.show()
# 获取多边形外扩后的重心坐标
# X_1 = X.pop(-1)
# Y_1 = Y.pop(-1)
# print(X_1,Y_1)
def M_1(lis_1, lis_2):
sum_1 = 0
sum_2 = 0
for i in range(len(lis_1) - 1):
sum_1 += lis_1[i]
for i in range(len(lis_2) - 1):
sum_2 += lis_2[i]
return sum_1 / (len(lis_1) - 1), sum_2 / (len(lis_2) - 1)
M_11_x, M_11_y = M_1(X, Y)
M_11 = [M_11_x, M_11_y]
print(f'外扩前的重心坐标是{M}') # 外扩前的重心坐标
print(f'外扩后的重心坐标是({M_11_x}, {M_11_y})') # 外扩后的重心坐标
# 发现重心变化
凸多边形外扩——by me
最新推荐文章于 2024-07-09 23:19:55 发布