多边形重心(内部带空洞)

本文介绍了一种利用鞋带定理求解带空洞多边形面积的方法,并通过numpy处理外多边形和内空洞,计算它们的重心。算法首先计算外多边形和空洞的面积以及质心,然后根据面积加权平均得到整体重心。
摘要由CSDN通过智能技术生成

多边形面积可用鞋带定理求解,实心多边形求重心【点击】。

带空洞多边形面积公式

1. 分别计算外多边形和每个内部空洞的面积 A_outer 和A_hole_i ;

2. 分别计算它们各自的质心 G_outer 和 G_hole_i ;

3. 整体重心G_total是所有组成部分面积加权的平均。

import numpy as np

# 判断首尾是否一样的坐标,一样的话去掉。
def ensure_open_boundary(boundary_list):
    import copy
    if boundary_list[-1][0] == boundary_list[0][0] and boundary_list[-1][1] == boundary_list[0][1]:
        res_boundary_list = copy.deepcopy(boundary_list[:-1])
        return res_boundary_list
    else:
        return boundary_list

def simple_boundary_gravity_center(boundary_points_in):
    """
    :param boundary_points_in: polygon [[x1,y1],[x2,y2],[x3,y3],[x4,y4]...]
    :return:
    """
    boundary_points_in=ensure_open_boundary(boundary_points_in)
    area = 0
    y = 0
    x = 0
    for i in range(1, len(boundary_points_in)+1):
        this_x = boundary_points_in[i % len(boundary_points_in)][0]
        this_y = boundary_points_in[i % len(boundary_points_in)][1]
        next_x = boundary_points_in[i - 1][0]
        next_y = boundary_points_in[i - 1][1]
        temp = (this_y * next_x - this_x * next_y) / 2.0
        area += temp
        y += temp * (this_y +next_y) / 3.0
        x += temp * (this_x +next_x) / 3.0
    y = y / area
    x = x / area

    return x,y,abs(area)


def boundary_gravity_center(boundary_points):
    """
    :param boundary_points:  [[[x1,y1],[x2,y2],...],[[],[],[]...],....]  三层列表里多个polygon,eg:[outer,hole,hole,...]
    :return:
    """
    if len(boundary_points)==1:
        x,y,area=simple_boundary_gravity_center(boundary_points[0])
        return [x,y]
    else:
        x_outer, y_outer, S_outer = simple_boundary_gravity_center(boundary_points[0])

        hole_list=np.array([simple_boundary_gravity_center(i) for i in boundary_points[1:]]) # [[x,y,area],[x,y,area]...]

        S_total = S_outer - np.sum(hole_list[:, 2])

        G_hole_sum =np.sum([i[2] / S_total * i[:2] for i in hole_list],axis=0)

        G_total=S_outer/S_total * np.array([x_outer, y_outer]) - G_hole_sum
        return G_total


if __name__ == '__main__':

    polygon=[[[1,5],[5,5],[5,3],[5,1],[1,1],[1,5]],[[4,3],[4,4],[3,4],[3,2],[4,2],[4,3]]]


    G=boundary_gravity_center(polygon)
    print(G)

    # # 画图
    # import matplotlib.pyplot as plt
    # fig3 = plt.figure(num=3, figsize=(5, 5))
    # axes3 = fig3.add_subplot(1, 1, 1)
    # p1=plt.Polygon(xy=polygon[0], color='red')
    # axes3.add_patch(p1)
    # for i in polygon[1:]:
    #     axes3.add_patch(plt.Polygon(xy=i, color='white'))
    # plt.grid()
    # plt.scatter(G[0],G[1],alpha=0)
    # plt.show()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值