构建n维提升点

Construct n-dimensional boost point

问题: boost/geometry/geometries/point.hpp 点模板不提供构造具有 非零值的 n 维点类型 的方法。

例如:

#include <boost/geometry/geometries/point.hpp>
namespace bg = boost::geometry;

...
typedef bg::model::point<double,4,bg::cs::cartesian> point;

auto nDimPoint1 = point(); // creates a point with 4 values each 0
auto nDimPoint2 = point(1,2,3,4); // !!!compiler error!!! since point's template does not provide a strategy past 3 dimensions.

// workaround, but must be hard-coded
nDimPoint1.set<0>(1);
nDimPoint1.set<1>(2);
nDimPoint1.set<2>(3);
nDimPoint1.set<3>(4);

我尝试过的: 在阅读了 boost 的文档后,我找不到任何带有 n 维点的示例,尽管我可能错过了它们。

我确实遇到过创建自定义点 classes 并注册它们,但是内置点 class 完全符合我的要求。不幸的是,我无法通过从基点继承来解决这个问题,因为点表示是一个私有变量。

Point 的模板包含一个私有数组变量,m_values,通过创建一个接受向量并将向量复制到 m_values 中的新构造函数,我解决了这个问题。

我对 C++ 的模板也很陌生,因为我通常使用 C 和 python。是否可以将 Point 模板扩展到 Point.hpp 文件之外,以包含我想要的 n 维构造函数?或者是否有更好的方法在 boost 中构建 n 维点,例如从向量转换?

理想情况下(恕我直言)boost 会提供一个通用的复制构造函数,它接受 std::vector 并将每个值复制到其内部数组中。

相关问题: 在这个问题 Defining a dimensional point in Boost.Geometry, the author is attempting to utilize point for rtree (I am also attempting to do this), however the accepted answer claims this is not possible and a second solution 中,声称可以解决问题,但我看不出它是如何工作的。

你是对的。 model::point class 模板不提供 direct/aggregate 初始化并且不可能添加它(m_values 是私有的,例如,但也有可选的 access-tracking 调试不同步的元数据)。

请注意 class 已记录

\details Defines a neutral point class, fulfilling the Point Concept.
    Library users can use this point class, or use their own point classes.
    This point class is used in most of the samples and tests of Boost.Geometry
    This point class is used occasionally within the library, where a temporary
    point class is necessary.

并且:

\tparam DimensionCount number of coordinates, usually 2 or 3

因此,您可以 - 并且可能应该 - 使用您自己的类型。最简单的方法是直接使用数组(因此,实际上只是 m_values 成员数据)。这没什么神奇的:

Live On Compiler Explorer

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/adapted/std_array.hpp>
#include <fmt/ranges.h>
namespace bg = boost::geometry;

BOOST_GEOMETRY_REGISTER_STD_ARRAY_CS(bg::cs::cartesian)

using point = std::array<double, 4>;

int main() {
    auto a = point(); // creates a point with 4 values each 0
    auto b = point{1, 2, 3, 4}; 

    // generic Boost code will still work:
    bg::set<0>(a, 10);
    bg::set<1>(a, 20);
    bg::set<2>(a, 30);
    bg::set<3>(a, 40);

    fmt::print("default:{}, a:{}, b:{}\n", point{}, a, b);
}
    

版画

default:[0, 0, 0, 0], a:[10, 20, 30, 40], b:[1, 2, 3, 4]