我正在努力定义和填充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;
}
错误是编译器无法看到&#34; point&#34;的typedef。另一方面,我不能使typedef的维度成为运行时变量(Boost赢了,不让我(!))。我能做什么?除了使用另一个库,因为这是我在高维几何中见过的最差的接口。 :/
编译为: c ++ -I ../ bla.cpp -std = c ++ 0x -ftemplate-depth-170001 -o bla
答案 0 :(得分:1)
point
,因为你没有在任何地方定义它。 解决方案:使用 template aliases 将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;
}
答案 1 :(得分:1)
我发现文档有点钝。有一些宏(ick!)有助于为低维类型启用Point概念。这是我希望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