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



我目前正在使用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。

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

这个问题几乎是浮点数学坏了吗?的重复,尽管足够独特,我认为它不应该被标记为这样。

您总共有两个问题:

  • 对于正好位于几何对象边界上的点,boost::geometry::within将返回 false,直线中的所有点都是这种情况。您需要更改策略以允许within为边界上的点返回 true。
  • 计算两点的交集通常会在浮点数学过程中导致一定程度的误差。您无法保证确定为两条线的交点实际上位于任一线上。您需要允许在距离内达到一定程度的公差,直到增量值(由您定义,我不会大于万分之一(,以允许被视为与线"相交"。

最新更新