求三角形重心 包括凹多边形的模板
求多边形重心的题目大致有这么几种:
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
下面讨论这个题的解法:
以第一个顶点为基准,分别连接p[i],p[i+1],1<i<n。将多边形划分为若干个三角形。
若我们求出了每个三角形的重心和质量,可以构造一个新的多边形,顶点为所有三角形的重心,顶点质量为三角形的质量。这个新多边形的质量和重心与原多边形相同,即可使用第一种类型的公式计算出整个多边形的重心。
由于三角形的面积与质量成正比,所以我们这里用面积代替质量来计算。
现在有个问题就是,多边形有可能为凹多边形,三角形有可能在多边形之外。如何处理这种情况呢?
很简单,我们使用叉积来计算三角形面积,当三角形在多边形之外时,得到“负面积”就抵消掉了。
S =( x0*y1 + x1*y2 + x2*y0
- x1*y0 - x2*y1 - x0*y2 ) /2;
point bcenter(struct point pnt[], int n)//【可以用来做模板】
{
point p, s;
double tp, area = 0, tpx = 0, tpy = 0;
p.x = pnt[0].x; p.y = pnt[0].y;
for (int i = 1; i <= n; ++i)
{
s.x = pnt[(i == n) ? 0 : i].x;
s.y = pnt[(i == n) ? 0 : i].y;
tp = (p.x * s.y - s.x * p.y);//表示这两个点的叉乘,即这两个点与原点所围成的三角形的面积的两倍,由于采用叉乘方式,所有可能为负,所以,可以将该多边形外面的部分面积减去
area += tp/2 ;//加上这个面积,area为这个多边形的总面积
tpx += (p.x + s.x) * tp;
tpy += (p.y + s.y) * tp;
p.x = s.x;
p.y = s.y;
}
s.x = tpx / (6 * area);
s.y = tpy / (6 * area);
return s;
}