框的提升 rtree 给出了与线段的错误交集
boost rtree of box gives wrong intersection with segment
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 = 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());
}
编辑:问题正在移至 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
, (types<Geometry>)
);
但是,即使代码已编译,它似乎也不正确...:intersects
调用是查询谓词本身的基础 returns "false positive" 似乎.
简化很多: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。我不确定结果是不是简单地不确定...
#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?
}
}
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 = 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());
}
编辑:问题正在移至 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
, (types<Geometry>)
);
但是,即使代码已编译,它似乎也不正确...:intersects
调用是查询谓词本身的基础 returns "false positive" 似乎.
简化很多: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。我不确定结果是不是简单地不确定...
#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?
}
}