boost::geometry::within() 点和序列的行为

boost::geometry::within() behavior for point and seqment

我目前使用的是 boost 1.67 和 我发现如果我使用 boost::geometry::within() 来检查一个点是否在一个段内,我不会得到我期望的答案。例如,我可以构造一对相交的线段,然后使用 boost::geometry::intersection() 获取交点。我希望该点位于每个边缘内。然而,这并不总是我所看到的。这是一些演示我的问题的代码:

#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

int main() {
    using point_t = boost::geometry::model::d2::point_xy<double>;
    using segment_t = boost::geometry::model::segment<point_t>;
    segment_t e1{point_t{100, 350}, point_t{-100, 400}};
    segment_t e2{point_t{0, 0}, point_t{90, 600}};
    std::vector<point_t> iv;
    boost::geometry::intersection(e1, e2, iv);
    assert(iv.size() == 1);
    const auto& v = iv[0];
    bool is_within = boost::geometry::within(v, e1);
    std::cout << "is within? " << is_within << std::endl;
    is_within = boost::geometry::within(v, e2);
    std::cout << "is within? " << is_within << std::endl;

    return 0;
}

在这种情况下 within() returns 两条边都为假。

这个问题 几乎Is Floating Point Math Broken? 的重复,但我认为不应该这样标记它。

你一共遇到两个问题:

    对于恰好位于几何对象边界上的点,
  • boost::geometry::within 将为 return false,对于一条线上的所有点都是如此。您需要更改策略以允许边界上的点 within 为 return true。
  • 计算两点的交集,通常会在浮点运算过程中产生一定程度的错误。您不能保证确定为两条线的交点的点确实在任何一条线上。您需要在距离上允许一定程度的公差,直到 delta 值(由您定义,我不会大于十分之一)以允许被视为 "intersecting" 线。

我将 post 这个作为答案,希望将来对其他人有用。如果您需要检查给定的 point 是否位于 segment 上,请不要使用 within()(或 covered_by())。在对原始问题的评论中,@rafix07 提出了一种更有用的方法来解决这个问题:使用 boost::geometry::distance(point, segment)。你可以根据自己的情况设置一个合适的容忍度,如果测得的距离落在容忍度范围内,就宣告胜利继续前进。