箱体的提升树与线段的交点错误

boost rtree of box gives wrong intersection with segment

本文关键字:错误      更新时间:2023-10-16

Boost rtree给出一些与段查询相交的错误相交结果。在这种情况下,边界框是y=0处的一个10 × 10的y平面正方形。我正在查询与z对齐的线从(2,1,0)到(2,1,10)。有趣的是,如果我使用一个查询框而不是一个段,那么它的工作如预期。当框不是平面时也会出现这种行为,只需将最小角移动到(0,- 5,0),它仍然会发生。

我使用这个错误还是它是一个bug在boost?

编辑:已经在Boost 1.56和1.59上尝试过了。

#include <vector>
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <vector>
#include <iterator>
#include <memory>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 3, bg::cs::cartesian> point_def;
typedef bg::model::box<point_def> box;
typedef bg::model::segment<point_def> segment;
typedef std::pair<box, size_t> tri_box;
typedef bgi::rtree< tri_box, bgi::linear<8>> tree_type;
using namespace std;
TEST(boost_rtree, cant_intersect_box_with_segment) {
  vector<tri_box> buff(1);
  buff[0].first = box{point_def{0, 0, 0}, point_def{10, 0, 10}};
  buff[0].second = 1;
  tree_type tree(buff);
  segment query{point_def{2, 1, 0}, point_def{2, 1, 10}};
//  box query{point_def{2, 1, 0}, point_def{2, 1, 10}};
  vector<tri_box> out;
  size_t count = tree.query(bgi::intersects(query), back_inserter(out));
  ASSERT_EQ(0, count); // fails here
  ASSERT_EQ(0, out.size());
}

编辑:问题正在移动到增强邮件列表:lists.boost.org/geometry/2015/09/3472.php

虽然看起来不太可能,但在我看来这是一个bug。

第一个编译这个的版本是Boost 1.56。使用

所有以前的版本都失败
BOOST_MPL_ASSERT_MSG
    (
        false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
        , (types<Geometry>)
    );

但是,即使代码被编译,它似乎不正确…:作为查询谓词本身基础的intersects调用似乎返回"假阳性"。

简化:Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/segment.hpp>
namespace bg  = boost::geometry;
typedef bg::model::point<int, 3, bg::cs::cartesian> point;
typedef bg::model::box<point>     box;
typedef bg::model::segment<point> segment;
int main() {
    box y0rect = box{point{0, 0, 0}, point{10, 0, 10}};
    segment seg{point{2, 1, 0}, point{2, 1, 10}};
    bg::correct(y0rect);
    bg::correct(seg);
    assert(!bg::intersects(seg, y0rect));
}

有趣的是,对于2d, 有时似乎可以正常工作。我不确定结果是不是简单地没有定义……

Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/segment.hpp>
namespace bg  = boost::geometry;
typedef bg::model::point<int, 4, bg::cs::cartesian> point;
typedef bg::model::box<point>     box;
typedef bg::model::segment<point> segment;
int main() {
    box y0rect = box{point{0, 0}, point{10, 10}};
    bg::correct(y0rect);
    {
        segment seg{point{12, 0}, point{20, 10}};
        bg::correct(seg);
        assert(!bg::intersects(seg, y0rect));
    }
    {
        segment seg{point{2, 0}, point{8, 6}};
        bg::correct(seg);
        assert(bg::intersects(seg, y0rect));
    }
    {
        segment seg{point{2, 0}, point{18, 6}};
        bg::correct(seg);
        assert(bg::intersects(seg, y0rect)); // OOPS BREAKS?
    }
}