【问题标题】:How to use boost::geometry::rtree with glm::vec3 as a custom point type?如何使用带有 glm::vec3 的 boost::geometry::rtree 作为自定义点类型?
【发布时间】:2018-05-19 02:24:36
【问题描述】:

我正在使用

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

RTree 定义为:

  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 的特化。我曾尝试手动添加它们,但无法使其工作。如何添加所需的距离类型特化?

请注意,我可以很好地使用相同的设置进行空间查询,所以它看起来基本上是合理的。

【问题讨论】:

    标签: c++ templates boost glm-math boost-geometry


    【解决方案1】:

    我无法重现 GCC/Boost 1.65.1 的问题:

    Live¹ On 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 上不起作用的结论感到满意?
    • 非常感谢您的快速响应和测试程序。问题是我没有包含geometry.hpp,只有rtree、box 和point。我试图最小化我的依赖,显然走得太远了。我现在觉得有点傻。 OTOH:要使该程序正常工作,包含的最小标题集是什么?
    • 不太确定 - 我不会出汗,因为无论如何优化器都会把它记下来,而且对于我的大多数项目来说,所有这些 boost 标头都不算“易失性”。以下是 IWYU 给出的内容:paste.ubuntu.com/26118710 - 虽然不完全准确,因为它无法编译
    • 如果没有 glm 的解决方法:``` namespace glm { struct vec3 { double x, y, z; vec3(双 x_, 双 y_, 双 z_) { x = x_; y = y_; z = z_; } }; } ```
    【解决方案2】:

    我只是想从对已接受答案(@BuschnicK)的评论中找出真正为我解决这个问题的答案。

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

    将以下包含添加到我的标题中解决了上面显示的问题。

    #include <boost/geometry.hpp>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多