最可靠方法是使用cgal计算多边形交集面积,需确保输入为cgal::polygon_2或polygon_with_holes_2类型、顶点逆时针排序、采用exact_predicates_exact_constructions_kernel,并验证结果有效性后调用area()。

用 CGAL 计算两个多边形交集面积最可靠
直接手写多边形裁剪逻辑极易出错,尤其是处理自相交、退化边、浮点精度、内外环嵌套等边界情况。工业级项目应优先用 CGAL——它把 intersection()、area() 封装得足够健壮,且支持精确几何计算。
关键前提是:两个多边形必须是 CGAL::Polygon_2 或 CGAL::Polygon_with_holes_2 类型,顶点顺序统一(通常逆时针为外环),坐标类型推荐用 CGAL::Exact_predicates_exact_constructions_kernel 避免浮点误差导致交集为空或面积为负。
- 若输入是普通
std::vector<:pair double>></:pair>,需先转成CGAL::Point_2<k></k>序列再构造Polygon_2 - 交集结果是
std::vector<:polygon_with_holes_2>></:polygon_with_holes_2>,因为两多边形交集可能产生多个不连通区域或带孔区域 - 调用
CGAL::area()前务必检查返回的多边形是否有效(p.is_valid()),否则面积可能为 NaN 或 0
用 Boost.Geometry 快速原型但慎用于生产
Boost.Geometry 的 intersection() 接口更轻量,适合简单凸多边形或调试验证,但它默认使用浮点数运算,对共线边、微小重叠、接近退化的构型容忍度低,容易返回空结果或碎片化多边形。
常见错误现象:boost::geometry::intersection(a, b, output) 返回 output.size() == 0,但肉眼可见有重叠——这往往是因为顶点未归一化、坐标范围过大(如经纬度未缩放)或存在重复点。
- 务必提前调用
boost::geometry::correct()对输入多边形预处理 - 使用
boost::geometry::model::d2::point_xy<double></double>而非float,减少舍入误差 - 交集结果可能是
boost::geometry::model::polygon<...></...>或boost::geometry::model::multi_polygon<...></...>,需统一用boost::geometry::area()计算总和
手动实现 Sutherland–Hodgman 裁剪只适用于凸×任意
如果确定其中一个多边形严格凸(比如矩形、三角形),可用 Sutherland–Hodgman 算法将另一个多边形逐边裁剪。它比通用布尔运算快,代码量少,但一旦两个都是凹多边形,结果必然错误——交集区域可能被错误分割或遗漏。
核心陷阱在于:裁剪平面顺序必须与凸多边形边界的法向量一致;顶点需用叉积判断“在内侧”,但浮点下 cross_product == 0 的边界点处理不当会导致边丢失。
- 所有中间顶点必须用
double存储,避免累积误差 - 裁剪后需调用
remove_duplicate_points()和is_simple()检查输出是否构成合法简单多边形 - 最终面积用鞋带公式(
shoelace formula)计算,注意顶点顺序影响正负号,取abs()
面积为 0 或负值?重点检查三类问题
无论用哪种库,拿到面积为 0 或负值,大概率不是算法问题,而是输入或解释环节出错:
- 多边形顶点顺序不一致:一个顺时针一个逆时针,
CGAL可能拒绝构造,Boost可能算出负面积——统一用CGAL::orientation()或boost::geometry::oriented_read_wkt()校验 - 坐标系单位不匹配:比如一个用米,一个用经纬度(度),数值尺度差 10⁵ 量级,直接导致交集计算溢出或失效
- 多边形未闭合或含重复点:
CGAL::Polygon_2构造时若首尾点不完全相等(浮点误差),is_valid()返回 false;Boost则可能静默失败
真正棘手的是带孔多边形的交集——孔与外环的拓扑关系必须显式维护,稍有不慎,交集结果里孔就变成了实心区域。这种场景几乎无法绕过 CGAL::General_polygon_set_2 这类专用结构。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











