如何使用 boost::geometry::rtree 作为自定义点类型处理 glm::vec3?

4
我正在使用的是:

BOOST_GEOMETRY_REGISTER_POINT_3D(glm::vec3, float, boost::geometry::cs::cartesian, x, y, z);

使用定义如下的R树:

  using IndexedPoint = std::pair<glm::vec3, uint32_t>;
  using RTree = boost::geometry::index::rtree<IndexedPoint, boost::geometry::index::rstar<8>>;

当我尝试使用最近邻查询时,它无法编译:

auto it = rtree.qbegin(boost::geometry::index::nearest(glm::vec3(), 3))

错误信息如下:
error C2664: 'int boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)': cannot convert argument 1 from 'boost::mpl::failed ************(__cdecl boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag,boost::geometry::box_tag,glm::vec<3,float,0>,boost::geometry::model::point<float,3,boost::geometry::cs::cartesian>,boost::geometry::cartesian_tag,boost::geometry::cartesian_tag,void>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION::* ***********)(boost::mpl::assert_::types<Point1,Point2,CsTag1,CsTag2>)' to 'boost::mpl::assert<false>::type'
        with
        [
            Point1=glm::vec<3,float,0>,
            Point2=boost::geometry::model::point<float,3,boost::geometry::cs::cartesian>,
            CsTag1=boost::geometry::cartesian_tag,
            CsTag2=boost::geometry::cartesian_tag
        ]

看起来comparable_distance_result在vec3与boost::geometry::model::point和boost::geometry::model::box之间缺少专业化。我尝试手动添加它们,但无法使其正常工作。我该如何添加所需的距离类型专业化?

请注意,我可以成功地使用相同的设置进行空间查询,因此它似乎基本上是正确的。

2个回答

4

我无法在GCC/Boost 1.65.1上重现这个问题:

现场演示¹ 在Coliru上

#include <boost/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/register/point.hpp>

namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;

#include <glm/vec3.hpp>
BOOST_GEOMETRY_REGISTER_POINT_3D(glm::vec3, float, bg::cs::cartesian, x, y, z)

#include <iostream>
int main() {

    using IndexedPoint = std::pair<glm::vec3, uint32_t>;
    using RTree = boost::geometry::index::rtree<IndexedPoint, boost::geometry::index::rstar<8>>;

    RTree rtree;
    rtree.insert({glm::vec3(1,1,1), 1});
    rtree.insert({glm::vec3(2,2,2), 2});
    rtree.insert({glm::vec3(3,3,3), 3});
    rtree.insert({glm::vec3(4,4,4), 4});

    auto it = rtree.qbegin(bgi::nearest(glm::vec3(2.9, 2.9, 2.9), 99));

    auto p = it->first;
    std::cout << "Nearest: # " << it->second << " (" << p.x << ", " << p.y << " " << p.z << ")\n";
}

打印

Nearest: # 3 (3, 3 3)

Coliru没有libglm库。


它是否随机地有所帮助,或者您满意得出结论说它在MSVC上无法工作? - sehe
2
非常感谢您的快速响应和测试程序。问题在于我没有包含geometry.hpp,只有rtree、box和point。我试图尽量减少依赖,显然走得太远了。现在我感觉有点愚蠢。另一方面,为使此程序正常工作,需要包含哪些最小的头文件集合? - BuschnicK
我不太确定 - 我不会过于担心,因为优化器会将其擦除,而且对于我的大多数项目来说,所有这些boost头文件都不算是“易失性”的。这是IWYU给出的:http://paste.ubuntu.com/26118710/ - 但这并不完全准确,因为它不能编译。 - sehe
如果您没有glm,可以使用以下解决方法:namespace glm { struct vec3 { double x, y, z; vec3(double x_, double y_, double z_) { x = x_; y = y_; z = z_; } }; } - dvorak4tzx

2

我只想从已接受的答案(@BuschnicK)的评论中找到真正解决我的答案。

问题是我没有包含geometry.hpp,只有rtree、box和point。

将以下include添加到我的头文件中即可解决上述问题。

#include <boost/geometry.hpp>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接