多边形面积可用鞋带定理求解,实心多边形求重心【点击】。
带空洞多边形面积公式
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()