盒子的boost rtree给出了与段错误的交集

Posted

技术标签:

【中文标题】盒子的boost rtree给出了与段错误的交集【英文标题】:boost rtree of box gives wrong intersection with segment 【发布时间】:2015-09-08 12:30:34 【问题描述】:

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

是我用错了还是 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 = boxpoint_def0, 0, 0, point_def10, 0, 10;
  buff[0].second = 1;
  tree_type tree(buff);

  segment querypoint_def2, 1, 0, point_def2, 1, 10;
//  box querypoint_def2, 1, 0, point_def2, 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

【问题讨论】:

是的,正如 sehe 所写,这似乎是不相交/相交中的错误。正如我在列表中的电子邮件中所写的,您可以创建一张票,以便获得有关此错误的更新。或者,如果您愿意贡献,您可以在 GitHub 上创建一个带有修复的拉取请求。 【参考方案1】:

尽管看起来不太可能,但在我看来这是一个错误。

甚至编译它的第一个版本是 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 = boxpoint0, 0, 0, point10, 0, 10;
    segment segpoint2, 1, 0, point2, 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 = boxpoint0, 0, point10, 10;
    bg::correct(y0rect);

    
        segment segpoint12, 0, point20, 10;
        bg::correct(seg);
        assert(!bg::intersects(seg, y0rect));
    
    
        segment segpoint2, 0, point8, 6;
        bg::correct(seg);
        assert(bg::intersects(seg, y0rect));
    
    
        segment segpoint2, 0, point18, 6;
        bg::correct(seg);
        assert(bg::intersects(seg, y0rect)); // OOPS BREAKS?
    

【讨论】:

感谢您的意见。已在 boost geometry 邮件列表中提出问题。 你有那个链接吗?添加会非常有用 为什么不贴出最小化版本的代码?我现在订阅了,但我无法回复(因为我没有收到那条消息......)。也许你可以添加一些东西 @sehe 实际上第 23 行的断言失败了,所以第二个。 修复应该与 Boost 1.61 一起发布。你也可以用类似这样的方式更改代码:github.com/boostorg/geometry/pull/332

以上是关于盒子的boost rtree给出了与段错误的交集的主要内容,如果未能解决你的问题,请参考以下文章

Boost rtree.bounds():获取更多盒子和/或访问其结构

R-trees 上的多级查询(交集、联合)

Boost Geometry:多边形和盒子的交集

boost中rtree中的打包算法

我可以在线程中使用 Boost.Geometry.index.rtree 吗?

从 boost::geometry::index::rtree 中删除点的问题