几何中心(质心)即所有点x、y坐标的算术平均值:$ c_x = \frac{\sum x_i}{n} $,$ c_y = \frac{\sum y_i}{n} $;需判空、用double累加、避免整数除法截断。

怎么求一组二维点的几何中心(质心)
直接对所有 x 和 y 坐标分别求平均值就行,前提是这些点权重相同。这不是加权中心或重心物理计算,只是算术平均。
常见错误是用整数除法导致截断,比如 int 类型点坐标却用 int 存结果;或者空容器没判空直接访问,触发 std::out_of_range 或未定义行为。
- 用
std::vector<:pair double>></:pair>或自定义结构体存点,避免类型窄化 - 先检查容器是否为空,空时返回
{0.0, 0.0}或抛异常,别硬算 - 累加用
double累加器,最后除以points.size(),别用int除
示例:
auto centroid(const std::vector<:pair double>& points) {
if (points.empty()) return std::make_pair(0.0, 0.0);
double sum_x = 0.0, sum_y = 0.0;
for (const auto& p : points) {
sum_x += p.first;
sum_y += p.second;
}
return {sum_x / points.size(), sum_y / points.size()};
}
</:pair>
如何快速得到最小包围矩形(AABB)
遍历一遍找 min_x、max_x、min_y、max_y 就够了,不需要排序或凸包算法——那是为最小面积包围盒准备的。
容易踩的坑是初始化极值不当:比如用 0 初始化 min_x,但所有点 x 都大于 0,结果 min_x 错成 0;或用 INT_MAX 却和 double 混用,隐式转换出问题。
- 用
std::numeric_limits<double>::max()</double>初始化min_*,用lowest()或-max()初始化max_* - 如果点集非空,也可直接用第一个点初始化,更安全
- 返回结构建议用
struct { double left, right, top, bottom; },比四元组语义清晰
示例:
struct AABB {
double left, right, top, bottom;
};
AABB bounding_box(const std::vector<:pair double>>& points) {
if (points.empty()) return {0,0,0,0};
double min_x = points[0].first, max_x = points[0].first;
double min_y = points[0].second, max_y = points[0].second;
for (size_t i = 1; i bottom
}
</:pair>
std::minmax_element 能不能用来优化包围盒计算
能,但只适合单维度。它一次遍历返回最小和最大迭代器,比手写循环略简洁,但对二维仍需调两次(x 和 y 各一次),总开销差不多,可读性未必更好。
注意:必须传自定义比较器,否则默认按 pair 的字典序比较,会出错。而且它不支持同时提取两个字段的极值,没法一步到位。
- 对
x坐标:用std::minmax_element(points.begin(), points.end(), [](auto& a, auto& b) { return a.first - 对
y坐标:同样写一遍,把.first换成.second - 别忘了判空——
minmax_element在空区间行为是未定义的
实际项目中,手写四变量循环反而更直白、更容易被编译器优化。
要不要考虑旋转最小包围盒(OBB)
除非明确需求是“最小面积”或“方向敏感”,否则不要。AABB 计算快、用途广(碰撞检测、空间划分),而 OBB 需要 PCA 或旋转卡壳,涉及特征向量、角度转换、坐标系变换,复杂度高一个数量级。
典型误用场景:看到“包围盒”就默认该用 OBB;或用 OpenCV 的 cv::minAreaRect 处理纯坐标数据,却没意识到它依赖图像坐标系(y 向下)且返回的是 RotatedRect 结构,和纯数学坐标系不一致。
- 确认需求:是做粗筛(AABB 足够)、还是精度优先(才考虑 OBB)
- 若真要 OBB,优先用成熟库如
CGAL或Boost.Geometry,别手推 SVD - 注意坐标系约定:数学常用 y 向上,图形 API 常 y 向下,翻转不处理会导致包围盒倒置
多数时候,中心点 + AABB 已覆盖 95% 的实际用途,比如地图标记聚合、UI 元素布局、游戏对象粗略碰撞。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











