如果给出多边形的顶点,如何计算多边形的质心?

时间:2015-03-06 19:36:12

标签: c c++11 math geometry

http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon

我访问了上面的链接并尝试实现公式来制定由n个顶点(x0,y0),(x1,y1),...,(xn-)定义的非自相交闭合多边形的质心。 1,炔1)。

例如,如果坐标是:(0,1)(1,0)(-1,0)(0,-1),则生成的质心坐标应为: 0.00 0.00

#include<stdio.h>
#include<iostream>
#include<utility>
using namespace std;
int main()
{
    int t,points;       
    scanf("%d",&points);
    pair<float,float>p[points];
    int i;
    for(i=0;i<points;i++)
    {
        scanf("%f %f",&p[i].first,&p[i].second);

    }
    float ar,x,y;
    for(i=0;i<points-1;i++)
    {
         ar+=(p[i].first*p[i+1].second-(p[i+1].first*p[i].second));
         x+=((p[i].first+p[i+1].first)*ar);
         y+=((p[i].second+p[i+1].second)*ar);
    }
    x/=(3*ar);
    y/=(3*ar);
    printf("%.2f %.2f\n",x,y);
}

然而,当我为给定的坐标运行上面的代码时,得到的质心坐标是:

-1. -1.

2 个答案:

答案 0 :(得分:2)

您的代码中有一些要改变的地方:

  • 正如@R Sahu所注意到的那样,arxy必须在for循环之前初始化为零。否则,输出可能是错误的,或者可能会在不同的运行中发生变化。
  • 在迭代jar

eq

所以x+=(p[i].first+p[i+1].first)*ar;错了,因为它必须是:

eq2

  

在这些公式中,假设顶点按照它们沿多边形周长出现的顺序编号,并且假设顶点(xn,yn)与(x0,y0)相同。

由于最后一个点不等于程序中的第一个点,因此输出错误。并且没有什么能确保按照多边形周边出现的顺序输入点。

这是由g++ main.cpp -o main -Wall编译的代码。选项-Wall启用所有警告......使用它来调试代码是一种很好的做法。

#include<stdio.h>
#include<iostream>
#include<utility>
using namespace std;
int main()
{
    int points;
    //scanf("%d",&points);
    points=4;
    pair<float,float>p[points];
    int i;
    /* for(i=0;i<points;i++)
    {
        scanf("%f %f",&p[i].first,&p[i].second);
    } */
    p[0].first=1;p[0].second=0;
    p[1].first=0;p[1].second=1;
    p[2].first=-1;p[2].second=0;
    p[3].first=0;p[3].second=-1;

    float ar=0,x=0,y=0,temp;
    for(i=0;i<points-1;i++)
    {
        temp=p[i].first*p[i+1].second-p[i+1].first*p[i].second;
        ar+=temp;
        x+=(p[i].first+p[i+1].first)*temp;
        y+=(p[i].second+p[i+1].second)*temp;
    }
    temp=p[points-1].first*p[0].second-p[0].first*p[points-1].second;
    ar+=temp;
    x+=(p[points-1].first+p[0].first)*temp;
    y+=(p[points-1].second+p[0].second)*temp;

    x/=(3*ar);
    y/=(3*ar);
    printf("%.6f %.6f\n",x,y);
}

请注意,通过测试(1,0),(0,1),(-1,0),(0,-1),无法确保ar的正确性......

答案 1 :(得分:1)

我看到以下问题:

  1. arxy未初始化。
  2. 行中的计算错误:

    x+=((p[i].first+p[i+1].first)*ar);
    y+=((p[i].second+p[i+1].second)*ar);
    
  3. 您使用以下方法缺少循环的一次迭代:

    for(i=0;i<points-1;i++)
    
  4. 这是一个适合我的功能版本:

    int main()
    {
       int points;       
       scanf("%d",&points);
       pair<float,float>p[points];
       int i;
       for(i=0;i<points;i++)
       {
          scanf("%f %f",&p[i].first,&p[i].second);
       }
    
       float ar = 0.0;
       float x = 0.0;
       float y = 0.0;
    
       for(i=0;i<points;i++)
       {
          // This allows wrap-around when are you dealing with 
          // the last point in the list.
          int j = (i+1)%points;
    
          float common = (p[i].first*p[j].second - p[j].first*p[i].second);
          ar += common;
          x+=(p[i].first+p[j].first)*common;
          y+=(p[i].second+p[j].second)*common;
       }
    
       ar *= 0.5;
       x /= (6*ar);
       y /= (6*ar);
    
       printf("area: %.2f, xc: %.2f, yc: %.2f\n", ar, x, y);
    }