【问题标题】:Find the center (of mass) of a 2D complex polygon找到二维复杂多边形的中心(质心)
【发布时间】:2011-09-14 00:23:16
【问题描述】:

所以我想知道如果我有一组顶点,找到形状质心的算法是什么?

此外,如果它使算法更短,我的复杂多边形将保存为一组简单的凸多边形,您可以获得它们的顶点。

我找到了上面的等式,但我不知道如何翻译......

【问题讨论】:

标签: c++ algorithm centroid


【解决方案1】:

鉴于新的证据,我坚信您给出的公式是错误的。请允许我提供一个不同的算法。我试图让它看起来像 C++ish,但我确定我做错了一些事情。如果你想挑剔那些,那很好。如果您想对它们投反对票,我无法阻止您,但我宁愿您将它们编辑掉以使帖子更好。 :-)

// use doubles if appropriate
float xsum = 0.0;
float ysum = 0.0;
float area = 0.0;
for(int i = 0; i < points.size - 1; i++) {
    // I'm not a c++ guy... do you need to use pointers? You make the call here
    Point p0 = points[i];
    Point p1 = points[i+1];

    double areaSum = (p0.x * p1.y) - (p1.x * p0.y)

    xsum += (p0.x + p1.x) * areaSum;
    ysum += (p0.y + p1.y) * areaSum;
    area += areaSum;
}

float centMassX = xsum / (area * 6);
float centMassY = ysum / (area * 6);

【讨论】:

  • 正如您所怀疑的,这不是多边形的质心。你可以通过取一个三角形,多次分割它的底边来看到这一点,顶点的平均值将刚好离开底边,而质心仍然在三角形的中心。
  • 我脑海中想象的例子是一个很薄的,用很小的边稍微弯曲,然后曲线变成了百万点。显然,质心不会发生显着变化,因为面积没有显着变化,但点的平均值几乎完全是小端点的平均值。
  • 三角形的特殊情况下,角的平均值等于重心。因此,如果您将凸多边形划分为三角形(例如,通过从选定角到所有其他角绘制对角线),则可以取所有 CoG 的平均值,并按每个三角形的面积加权。
  • @Oli 感谢原始帖子中的链接。我提供了一个算法来匹配它。在检查时,它似乎更直观。
  • @Henning 我想过这个问题,但是如果你考虑我的细三角形与分裂的小边......新的三角形可能会被分割成所有在小端的三角形,导致中心重力也像角落的平均值一样被加权。
【解决方案2】:

尝试给定here 的算法。它适用于凸多边形。

【讨论】:

【解决方案3】:

一般的方法是将图形分割成更容易计算的部分,计算它们的质心并将它们组合:C=sum(C[i]*mass[i])/sum(mass[i])

首先,您应该定义质量在多边形中的分布方式。可能的(简单)分布:

  1. 集中在顶点(统一) - 您问题中的公式适用于这种情况
  2. 均匀分布在多边形的边界上 - 在这种情况下,您应该计算每条线的质心(它只是线的中间),将其乘以线长,然后将它们全部相加并除以整个边界长度
  3. 均匀分布在多边形的面积上 - 最简单的理解方法是将其拆分为三角形,计算每个三角形的质心,乘以它的面积,将它们全部相加,然后除以多边形的整个面积

【讨论】:

    【解决方案4】:

    你可以使用一个简单的平均函数,大致如下:

    template <typename T, typename iterator> T avg(iterator const& begin, iterator const& end) {
      T result;
      size_t size(0);
      for (iterator it = begin; it != end; ++it) {
        result += *it;
        size++;
      }
      return result/size;
    }
    

    现在,假设您的值在一个集合中,您可以这样做:

    std::set<double> xs; // assuming your values are in there
    double x = avg<double,std::set<double>::iterator>(xs.begin(), xs.end());
    

    如果没有通过 g++ 运行,我不确定可以自动推断出哪些模板参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多