多边形面重心不能直接对顶点取平均,因顶点几何中心不等于面积加权重心;须用有向面积加权三角剖分法:以首顶点为公共顶点分解为n-2个三角形,用叉积算有向面积,三角形重心为三顶点均值,最终重心为(面积×重心)之和除以总面积。

多边形重心公式为什么不能直接对顶点取平均
直接用 std::accumulate 对所有顶点坐标求平均,得到的是顶点的几何中心(centroid of vertices),不是物理意义上的面重心(centroid of area)。对于凹多边形、非均匀顶点分布或自相交多边形,结果会明显偏移。真正有效的算法必须考虑每个三角形子区域的面积权重。
用有向面积加权求和实现稳定计算
标准做法是将多边形沿某固定点(如第一个顶点)剖分为 n-2 个三角形,对每个三角形计算其有向面积和局部重心,再按面积加权平均。关键点在于:
- 使用叉积计算有向面积:对连续三点
(x0,y0),(x1,y1),(x2,y2),面积为0.5 * ((x1-x0)*(y2-y0) - (x2-x0)*(y1-y0)) - 三角形重心就是三顶点坐标的算术平均,即
((x0+x1+x2)/3, (y0+y1+y2)/3) - 最终重心 = 所有三角形(面积 × 重心)之和 ÷ 总面积
- 务必保持顶点顺序一致(顺时针或逆时针),否则有向面积正负混杂,总和可能趋近于零
示例片段(假设顶点存于 std::vector<:pair>></:pair>):
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
double cx = 0.0, cy = 0.0, area = 0.0;
const auto& p0 = points[0];
for (size_t i = 1; i + 1 1e-12) {
cx /= area;
cy /= area;
} // 否则多边形退化(共线或重复点)
处理自相交或多环多边形时的陷阱
上述算法默认输入是简单多边形(无自相交、单连通)。若传入自相交多边形(如蝴蝶形),有向面积会自动抵消重叠区域,结果仍是“净面积”的重心——这在某些场景下是预期行为,但容易被误认为错误。真正需要支持洞或多环时,必须:
- 将外环顶点按逆时针排列,内环(洞)按顺时针排列
- 统一用相同剖分逻辑遍历所有环,累加时洞的有向面积为负
- 不建议手动实现多环逻辑;优先用
CGAL或Boost.Geometry的centroid()函数
浮点精度与退化情况必须显式检查
当多边形面积接近零时(三点共线、顶点重复、极小面积),cx/area 会产生极大误差甚至 inf。不能只靠 area != 0 判断:
- 用
std::abs(area) ::epsilon() * max_coord做相对容差判断 - 预处理剔除连续重复点,或合并距离小于阈值的顶点
- 若输入来自用户绘图或传感器,建议先调用
std::unique+ 自定义 epsilon 比较器去重
重心坐标的数值稳定性高度依赖原始坐标的量级。如果顶点坐标是 1e6 级别,建议先平移到原点附近再计算,最后平移回去。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










