You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断线段A->B是否位于多边形内且不触碰墙体?

解决Boost Geometry中判断线段完全位于多边形内部时返回错误的问题

问题背景

需求为判断由Point A、Point B构成的线段A->B是否满足以下任一条件:

  • 不与多边形C的墙体相交
  • 完全位于多边形C内部

现有代码对跨通道的线段(如POINT(2.5 3.25)至POINT(3 3.625)的线段)能正确返回true,但完全位于多边形内部的线段会错误返回false。

目标多边形

POLYGON((2 2,2 3.5,4 3.5,4 2,2 3.5,2 5.5,5 5.5,5 3.5,4 2,4 3.5,5 3.5,5 5.5,7.5 5.5,7.5 2,2 2)) 

通道信息

Passage: POINT(2.5 3.5) POINT(3 3.5)
Passage: POINT(4.25 3.5) POINT(4.75 3.5)
Passage: POINT(4 2.5) POINT(4 3)
Passage: POINT(5 4) POINT(5 5)

错误原因分析

当前代码else分支使用的DE-9IM掩码"T*F**F***"不符合需求。该掩码仅要求线段与多边形内部有交集、与外部无交集,但未覆盖线段完全位于多边形内部的所有场景,导致判断逻辑失效。

解决方案

核心修正:替换内部判断逻辑

放弃手动编写DE-9IM掩码,改用Boost Geometry提供的covered_by或within函数,这两个函数更直观且能准确判断线段与多边形的包含关系:

  • bg::covered_by(AB, wall):判断线段完全位于多边形内部包括边界
  • bg::within(AB, wall):判断线段严格位于多边形内部不接触边界

同时需要修正多边形拓扑,输入的多边形存在重复顶点,需调用bg::correct确保其有效性。

完整修正代码

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/segment.hpp>

#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;

typedef bgm::d2::point_xy<double> Point;
typedef bgm::polygon<Point> Polygon;
typedef boost::geometry::model::segment<Point> Segment;

int main() {
    Polygon wall;
    // 读取多边形并修正拓扑
    bg::read_wkt("POLYGON((2 2,2 3.5,4 3.5,4 2,2 3.5,2 5.5,5 5.5,5 3.5,4 2,4 3.5,5 3.5,5 5.5,7.5 5.5,7.5 2,2 2))", wall);
    bg::correct(wall); // 去除重复顶点,确保多边形拓扑有效

    Polygon passage;
    // 此处根据通道信息初始化passage多边形...

    Point start(2.5, 3.25);
    Point end(3, 3.625);
    boost::geometry::model::linestring<Point> AB{start, end};
    bool isPassable = false;

    bool intersecting = bg::intersects(AB, wall);
    if (intersecting) {
        for (int i = 0; i < passage.outer().size(); i += 2) {
            Point p1 = passage.outer()[i];
            Point p2 = passage.outer()[i + 1];
            Segment passageSegment(p1, p2);
            Segment testSegment(start, end);
            if (bg::intersects(passageSegment, testSegment)) {
                isPassable = true;
                break;
            }
        }
    } else {
        // 替换为covered_by判断线段完全在多边形内(含边界)
        isPassable = bg::covered_by(AB, wall);
        // 若需严格内部(不含边界),则替换为:
        // isPassable = bg::within(AB, wall);
    }

    return 0;
}

额外注意事项

  1. 多边形有效性:必须调用bg::correct处理输入多边形,否则重复顶点可能导致几何判断异常。
  2. 通道多边形构建:确保passage多边形正确包含所有通道线段,避免遍历过程中出现索引越界或逻辑错误。

内容的提问来源于stack exchange,提问作者canersevdiceginibekleyenoglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:47:04