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

时间:2018-10-02 16:30:54

标签: c++ boost-geometry

我目前正在使用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()的两条边都返回false。

2 个答案:

答案 0 :(得分:1)

这个问题几乎是Is Floating Point Math Broken?的一个副本,尽管区别足够明显,我认为不应将其标记为这样。

您总共有两个问题:

  • boost::geometry::within对于正好在几何对象边界上的点将返回false,对于直线中的所有点都是如此。您需要更改策略,以允许within对边界上的点返回true。
  • 计算两个点的交点通常会在浮点数学运算期间导致一定程度的误差。您不能保证确定为两条线的交点的点实际上在任一条线上。您需要在距离上允许一定程度的公差,直到达到增量值(由您定义,我不会超过千分之一),才能将其视为“相交”线。

答案 1 :(得分:0)

我将把它发布为答案,希望它将来对其他人有用。如果您需要检查给定的point是否位于segment上,请不要使用within()(或covered_by())。在对原始问题的评论中,@ rafix07建议了一种解决此问题的更有用的方法:使用boost::geometry::distance(point, segment)。您可以根据自己的情况设置适当的公差,如果测得的距离在公差之内,则宣告胜利并继续前进。