【问题标题】:Defining a dimensional point in Boost.Geometry在 Boost.Geometry 中定义一个维度点
【发布时间】:2020-07-07 22:25:29
【问题描述】:

我正在努力定义和填充 d 维度中的一个点。确切地说,我利用让 Boost.Geometry 处理用户的任何维度是不可能的(这是我从文档和他们的邮件列表中看到的)。所以,我正在尝试定义一个 100D 或 10000D 维度点。

这是代码,我的尝试和他们列表中的帮助在此开发:

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

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

template <int CompileTimeDimension>
void do_something()
{
    typedef bg::model::point<float, CompileTimeDimension, bg::cs::cartesian> point;
    bgi::rtree<point, bgi::linear<8> > rt;
}

template <std::size_t D, std::size_t N>
struct fill
{
    template <typename Point>
    static void apply(Point& p, typename bg::coordinate_type<Point>::type const& v)
    {
        bg::set<D>(p, v);
        fill<D + 1, N>::apply(p, v);
    }
};
template <std::size_t N>
struct fill<N, N>
{
    template <typename Point>
    static void apply(Point&, typename bg::coordinate_type<Point>::type const&) {}
};


int main()
{
    int M;
    M = 100;
    if ( M == 100 )
        do_something<100>();
        else if ( M == 10000 )
        do_something<10000>();
        else
        std::cerr << "invalid dimension!";
    point p;    
    if ( M == 100 )
        fill<0, 100>::apply(p, 5);
        else if ( M == 10000 )
        fill<0, 10000>::apply(p, 5);
        else
        std::cerr << "invalid dimension!";  
    return 0;
}

错误是编译器看不到“point”的typedef。另一方面,我不能将 typedef 的维度设为运行时变量(Boost 不会让我(!))。我能做些什么?除了使用另一个库,因为这是我在高维几何中见过的最糟糕的界面。 :/

编译为: c++ -I ../bla.cpp -std=c++0x -ftemplate-depth-170001 -o bla

【问题讨论】:

    标签: c++ templates boost-geometry


    【解决方案1】:

    我发现文档有点迟钝。有一些宏(ick!)有助于为低维类型启用点概念。这是我希望 Boost 提供的示例 (C++17):

    namespace boost::geometry::traits {
    template<typename T, int D> struct tag<Eigen::Matrix<T, D, 1>> { using type = point_tag; };
    template<typename T, int D> struct dimension<Eigen::Matrix<T, D, 1>> : boost::mpl::int_<D> {};
    template<typename T, int D> struct coordinate_type<Eigen::Matrix<T, D, 1>> { using type = T; };
    template<typename T, int D> struct coordinate_system<Eigen::Matrix<T, D, 1>> { using type = boost::geometry::cs::cartesian; };
    
    template<typename T, int D, int Dim>
    struct access<Eigen::Matrix<T, D, 1>, Dim> {
        static_assert(0 <= Dim && Dim < D, "Out of range");
        using Point = Eigen::Matrix<T, D, 1>;
        using CoordinateType = typename coordinate_type<Point>::type;
        static inline const CoordinateType& get(Point const& p) { return p[Dim]; }
        static inline void set(Point& p, CoordinateType const& value) { p[Dim] = value; }
    };
    } // namespace boost::geometry::traits
    

    【讨论】:

      【解决方案2】:
      • 在我的拙见中,Boost 几何不适用于高任意维度点(即维度 > 4)。然而,由于其通用性,支持具有高任意维度的点。
      • 编译器正确地抱怨不知道point,因为你没有在任何地方定义它。

      解决方案:使用template aliasespoint定义为任意维度提升点:

      template <std::size_t D = 100>
      using point = bg::model::point<double, D, bg::cs::cartesian>;
      

      示例代码:

      #include <iostream>
      #include <boost/geometry.hpp>
      
      namespace bg = boost::geometry;
      
      template <std::size_t D = 100>
      using point = bg::model::point<double, D, bg::cs::cartesian>;
      
      int main()
      {
          int const M = 2;
          point<M> p;
          p.set<0>(1.0);
          p.set<1>(2.0);
          double x = p.get<0>();
          double y = p.get<1>();
          std::cout << x << ", " << y << std::endl;
          return 0;
      }
      

      【讨论】:

      • 我同意这个观点。但是,我必须填补这一点。我将有 10000 个维度的点。这意味着,我必须使用上面的 fill()。当你的模板..使用点..,填充()和主时,我收到这个错误:在“使用”之前预期不合格的ID
      • 该死,刚刚注意到,fill() 将用相同的值填充该点。为我的目的使用 Boost 付出了太多努力,我怀疑他们的算法无法扩展,所以我将使用另一个库。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多