Boost Geometry合并多边形时Buffer操作不符合预期问题排查
问题描述
为处理多边形接触时的浮点精度误差,我使用带boost::geometry::strategy::buffer::distance_symmetric<double>膨胀策略的boost::geometry::buffer操作计算一组多边形的并集。但针对特定输入,结果不符合预期:待合并的7个多边形中,boost::geometry::union_的并集结果正常,但缓冲合并结果里最后两个多边形缺失。
有趣的是,若微调第4个多边形(x、y方向各偏移+0.01),或直接移除该多边形,Buffer操作结果就恢复正常。相关代码如下:
using Point = boost::geometry::model::d2::point_xy<double>; using Polygon = boost::geometry::model::polygon<Point>; double epsilon = 0.3; boost::geometry::strategy::buffer::join_miter join_strategy; boost::geometry::strategy::buffer::distance_symmetric<double> inflate_strategy(epsilon); boost::geometry::strategy::buffer::end_flat end_strategy; boost::geometry::strategy::buffer::side_straight side_strategy; boost::geometry::strategy::buffer::point_circle point_strategy; boost::geometry::model::multi_polygon<Polygon> source_set, joined_inflated; source_set.push_back( Polygon{{Point(12.50, 36.50), Point(12.50, 30.50), Point(6.50, 30.50), Point(6.50, 36.50), Point(12.50, 36.50)}}); source_set.push_back( Polygon{{Point(6.50, 27.00), Point(6.50, 33.50), Point(12.50, 33.50), Point(12.50, 27.00), Point(6.50, 27.00)}}); source_set.push_back( Polygon{{Point(12.50, 30.00), Point(12.50, 24.00), Point(6.50, 24.00), Point(6.50, 30.00), Point(12.50, 30.00)}}); source_set.push_back( Polygon{{Point(24.00, 24.00), Point(9.50, 24.00), Point(9.50, 30.00), Point(24.00, 30.00), Point(24.00, 24.00)}}); source_set.push_back( Polygon{{Point(27.0, 30.0), Point(27.0, 24.0), Point(21.0, 24.0), Point(21.0, 30.0), Point(27.0, 30.0)}}); source_set.push_back( Polygon{{Point(28.10, 30.73), Point(26.90, 26.23), Point(21.10, 27.77), Point(22.30, 32.27), Point(28.10, 30.73)}}); source_set.push_back( Polygon{{Point(28.20, 34.50), Point(28.20, 28.50), Point(22.20, 28.50), Point(22.20, 34.50), Point(28.20, 34.50)}}); boost::geometry::buffer(source_set, joined_inflated, inflate_strategy, side_strategy, join_strategy, end_strategy, point_strategy);
原因分析
- 缓冲拓扑计算的临界冲突:第4个多边形的上边界为y=30.0,第7个多边形的下边界为y=28.5,垂直距离1.5,远大于膨胀值0.3,看似无重叠,但第6个多边形的顶点(如(22.30,32.27))与第4个多边形右上角(24.0,30.0)的缓冲区域,在浮点运算下触发了拓扑自相交或重叠判定错误,导致后续合并时错误丢弃了第6、7个多边形的缓冲结果。
- 浮点精度的累积误差:第4个多边形的坐标为精确十进制值,转换为double存储时存在微小误差,叠加缓冲计算中的浮点运算累积,使得Boost.Geometry的拓扑判定(点是否在多边形内、轮廓是否相交)进入临界状态,触发异常逻辑。微调第4个多边形坐标后,临界状态被打破,拓扑计算恢复正常。
- Union与Buffer的逻辑差异:
boost::geometry::union_直接计算原始多边形的并集,拓扑判定针对原始位置;而Buffer操作先膨胀生成新轮廓,再合并,这些新轮廓的拓扑关系对浮点误差更敏感,尤其当多个缓冲轮廓距离处于临界值时,极易出现判定错误。
内容的提问来源于stack exchange,提问作者fabmene
相关产品推荐
相关产品推荐

