框的加速rtree给段错误的交集 [英] boost rtree of box gives wrong intersection with segment

查看:239
本文介绍了框的加速rtree给段错误的交集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Boost rtree为段查询的某些交集提供错误的交集结果。
在这种情况下,边界框是在y = 0的y平面10x10平方。我使用从(2,1,0)到(2,1,10)的z对齐线查询。有趣的是,如果我使用一个查询框而不是一个段,它的工作原理。这个行为也存在于盒子不是平面的,只是移动最小角落(0,-5,0),它仍然发生。





编辑:已在Boost 1.56和1.59上尝试过此操作。

  #include< vector> 
#includegtest / gtest.h
#includegmock / 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>

命名空间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>框;
typedef bg :: model :: segment< point_def>分割;
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);

段查询{point_def {2,1,0},point_def {2,1,10}};
//框查询{point_def {2,1,0},point_def {2,1,10}};
矢量< tri_box>出口;

size_t count = tree.query(bgi :: intersects(query),back_inserter(out)); $ b¥b
ASSERT_EQ(0,count); // failed here
ASSERT_EQ(0,out.size());
}

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

解决方案

似乎不太可能,这似乎是一个错误。



第一个编译这个的版本是Boost 1.56。所有以前的版本都会失败,并且

  BOOST_MPL_ASSERT_MSG 

false,NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
, Geometry>)
);

但是,即使代码被编译,它似乎不正确...:

很简单: Live On Coliru

  #include< boost / geometry.hpp> 
#include< boost / geometry / geometries / box.hpp>
#include< boost / geometry / geometries / segment.hpp>

命名空间bg = boost :: geometry;

typedef bg :: model :: point< int,3,bg :: cs :: cartesian>点;
typedef bg :: model :: box< point>框;
typedef bg :: model :: segment< point>分割;

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));
}

UPDATE



有趣的是,对于2d,它似乎可以正常工作 。我不确定结果是不是简单的未定义...



Live On Coliru

  #include< ; boost / geometry.hpp> 
#include< boost / geometry / geometries / box.hpp>
#include< boost / geometry / geometries / segment.hpp>

命名空间bg = boost :: geometry;

typedef bg :: model :: point< int,4,bg :: cs :: cartesian>点;
typedef bg :: model :: box< point>框;
typedef bg :: model :: segment< point>分割;

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?
}
}


Boost rtree gives wrong intersection result for some intersection with segment queries. In this case the bounding box is a y-planar 10x10 square at y=0. I'm querying with a z-aligned line from (2, 1, 0) to (2, 1, 10). What's interesting is that if I use a box for query instead of a segment then it works as expected. This behavior is also present when the box is not planar, just move the min corner to (0, -5, 0) and it still happens.

Am I using this wrong or is it a bug in boost?

Edit: have tried this on Boost 1.56 and 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());
}

Edit: issue is being moved to boost mailing list: lists.boost.org/geometry/2015/09/3472.php

解决方案

As unlikely as it seems, this appears to me to be a bug.

The first version that even compiles this is Boost 1.56. All previous versions fail with

BOOST_MPL_ASSERT_MSG
    (
        false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
        , (types<Geometry>)
    );

But, even though the code is compiled, it does not seem to be correct...: the intersects call that underlies the query predicate itself returns "false positive" it seems.

Much simplified: 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));
}

UPDATE

Interestingly, it seems to work correctly sometimes for 2d. I'm not sure the outcome isn't simply undefined...

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?
    }
}

这篇关于框的加速rtree给段错误的交集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆