凸多边形外扩——by me

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})')  # 外扩后的重心坐标


# 发现重心变化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值