Определение размерной точки в Boost.Geometry

Я изо всех сил пытаюсь определить и заполнить точку в 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;
}

Ошибка в том, что компилятор не видит typedef «точки». С другой стороны, я не могу сделать размер typedef переменной времени выполнения (Boost не позволит мне (!)). Что я могу сделать? За исключением использования другой библиотеки, так как это худший интерфейс, который я когда-либо видел в геометрии более высоких измерений. :/

Скомпилировано как: c++ -I ../ bla.cpp -std=c++0x -ftemplate-depth-170001 -o bla


person gsamaras    schedule 16.04.2014    source источник


Ответы (2)


  • По моему скромному мнению, геометрия Boost не подходит для точек с высокой произвольной размерностью (т. Е. Размерностью> 4). Тем не менее, точки с высокой произвольной размерностью поддерживаются из-за их общего характера.
  • Компилятор справедливо жалуется на то, что не знает point, поскольку вы нигде его не определили.

Решение. Используйте псевдонимы шаблонов, чтобы определить point как произвольную точку усиления измерения:

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;
}
person 101010    schedule 16.04.2014
comment
Я согласен с этим мнением. Тем не менее, я должен заполнить точку. У меня будут точки в 10000 измерениях. Это означает, что я должен использовать функцию fill(), описанную выше. Когда у вас есть шаблон... используя точку..., fill () и main, я получаю эту ошибку: ожидаемый неквалифицированный идентификатор перед «использованием» - person gsamaras; 17.04.2014
comment
Блин, только что заметил, что fill() заполнит точку одним и тем же значением. Слишком много усилий, чтобы использовать Boost для моей цели, и я подозреваю, что их алгоритм не масштабируется, поэтому я буду использовать другую библиотеку. - person gsamaras; 17.04.2014

Я нашел документы немного тупыми. Есть несколько макросов (ах!), которые помогают включить концепцию Point для низкоразмерных типов. Это пример, который я хотел бы предоставить Boost (С++ 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
person Ben    schedule 07.07.2020