在Python中找到一个多边形的重心

6

我想计算由以下点形成的图形的质心:(0,0), (70,0), (70,25), (45, 45), (45, 180), (95, 188), (95, 200), (-25, 200), (-25,188), (25,180), (25,45), (0, 25), (0,0)。

我知道这个多边形的质心正确结果是x = 35,y = 100.4615(source),但下面的代码没有返回正确的值(如下图所示)。

import numpy as np

points = np.array([(0,0), (70,0), (70,25), (45,45), (45,180), (95,188), (95,200), (-25,200), (-25, 188), (25,180), (25,45), (0,25), (0,0)])
centroid = np.mean(points, axis=0)
print("Centroid:", centroid)

输出:质心:[32.30769231 98.15384615]

如何正确计算多边形的质心?

enter image description here


1
你是在寻找计算质心位置的公式还是Python实现? - JonSG
4个回答

7

如果您不想从头开始计算数学问题,我强烈建议在处理多边形时使用shapely库。

要计算给定顶点坐标的多边形的质心,可以执行以下操作:

from shapely.geometry import Polygon
polygon = Polygon([(0,0), (70,0), (70,25), (45, 45), (45, 180), (95, 188), (95, 200), (-25, 200), (-25,188), (25,180), (25,45), (0, 25)])
print(polygon.centroid)
>>> POINT (35 100.46145124716553)

4

已修复:

def centroid(vertices):
    x, y = 0, 0
    n = len(vertices)
    signed_area = 0
    for i in range(len(vertices)):
        x0, y0 = vertices[i]
        x1, y1 = vertices[(i + 1) % n]
        # shoelace formula
        area = (x0 * y1) - (x1 * y0)
        signed_area += area
        x += (x0 + x1) * area
        y += (y0 + y1) * area
    signed_area *= 0.5
    x /= 6 * signed_area
    y /= 6 * signed_area
    return x, y

x, y = centroid(vertices)
print(x, y)

生成:

35.0 100.46145124716553

4

这里有一些代码,下面会有解释。

import numpy as np

polygon = np.array(
    [
        (0,0), (70,0), (70,25), (45, 45), (45, 180), (95, 188),
        (95, 200), (-25, 200), (-25,188), (25,180), (25,45), (0, 25),
    ],
    dtype=np.float64,
)

# Same polygon, but with vertices cycled around. Now the polygon
# decomposes into triangles of the form origin-polygon[i]-polygon2[i]
polygon2 = np.roll(polygon, -1, axis=0)

# Compute signed area of each triangle
signed_areas = 0.5 * np.cross(polygon, polygon2)

# Compute centroid of each triangle
centroids = (polygon + polygon2) / 3.0

# Get average of those centroids, weighted by the signed areas.
centroid = np.average(centroids, axis=0, weights=signed_areas)

print("Centroid:", centroid)

在我的电脑上运行此代码的结果是您所期望的:
$ python polygon_centroid.py
Centroid: [ 35.         100.46145125]

基本思路是将形状分解成三角形。我们可以通过明显的公式(它是顶点的平均值)计算每个三角形的重心。要计算整个多边形的重心,我们只需计算组成三角形的重心的平均值,每个三角形的权重为其(有符号的)面积。
对于多边形来说,使这项任务特别容易的是,我们可以允许自己包括“负”三角形 - 也就是说,我们可以将多边形表示为三角形的和与差。只要我们跟踪面积中的符号,一切都能解决。因此,无需担心您的多边形是否凸或原点是否在多边形内等问题。
在上面的代码中,我们只需将连续顶点与原点形成的三角形分解即可。
请参阅维基百科页面以获取更多信息。

1

一系列对齐点的质心是它们的平均值。

对于一个闭合的、非自交的多边形,您必须使用一些更复杂的公式,请参见wikipedia centroid中的“多边形”。

另外需要注意的是,我想您也需要梁的惯性。为此,我建议将其分解为矩形和三角形,然后使用Steiner定理https://es.wikipedia.org/wiki/Teorema_del_eje_paralelo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接