已知一多边形没有边相交,质量分布均匀。顺序给出多边形的顶点坐标,求其重心。
分析:
求多边形重心的题目大致有这么几种:
1,质量集中在顶点上。n个顶点坐标为(xi,yi),质量为mi,则重心
X = ∑( xi×mi ) / ∑mi
Y = ∑( yi×mi ) / ∑mi
特殊地,若每个点的质量相同,则
X = ∑xi / n
Y = ∑yi / n
2,质量分布均匀。这个题就是这一类型,算法和上面的不同。
特殊地,质量均匀的三角形重心:
X = ( x0 + x1 + x2 ) / 3
Y = ( y0 + y1 + y2 ) / 3
3,质量分布不均匀。只能用积分来算,不会……
下面讨论这个题的解法:
以第一个顶点为基准,分别连接p[i],p[i+1],1<i<n。将多边形划分为若干个三角形。
若我们求出了每个三角形的重心和质量,可以构造一个新的多边形,顶点为所有三角形的重心,顶点质量为三角形的质量。这个新多边形的质量和重心与原多边形相同,即可使用第一种类型的公式计算出整个多边形的重心。
由于三角形的面积与质量成正比,所以我们这里用面积代替质量来计算。
现在有个问题就是,多边形有可能为凹多边形,三角形有可能在多边形之外。如何处理这种情况呢?
很简单,我们使用叉积来计算三角形面积,当三角形在多边形之外时,得到“负面积”就抵消掉了。
S =( x0*y1 + x1*y2 + x2*y0
- x1*y0 - x2*y1 - x0*y2 ) /2;
代码:
//用叉积计算三角形面积
//coutourpoint是一个类似point的结构体,表示一个点
double det(ContourPoint p0,ContourPoint p1,ContourPoint p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double PolygonAreaCenter(std::vector<ContourPoint> &points,double &cx,double&cy)
{
double s=0.0,sx=0.0,sy=0.0; //S面积,xy横纵坐标和
double ts=0.0;
for(int i=1;i<(int)points.size()-1;i++)
{
ts = det(points[0],points[i],points[i+1]);
s += ts;
sx += ts*(points[0].x+points[i].x+points[i+1].x)/3;
sy += ts*(points[0].y+points[i].y+points[i+1].y)/3;
}
cx=sx/s;cy=sy/s;
return fabs(s)/2.0;
}