在地图<Quaternion>中使用步幅

Using Stride in Map<Quaternion>

本文关键字:Quaternion 地图 lt gt      更新时间:2023-10-16

我想在现有矩阵的内存之上定义一个四元数。让这个矩阵成为

MatrixXd M(4,4);

举个例子。我希望我的四元数映射到第二列。通常我会做

Map<Quaterniond> q (&M(0,1));

如果 M 是列主,这将起作用,因为Map将是按列的。

现在假设我有第二个数组 N,它现在是行主数组

Matrix<double, -1, -1, RowMajor> N(4,4);

现在我的映射四元数

Map<Quaterniond> q (&N(0,1));

将是错误的:q的元素将从 N 行中拾取,即N(0,1),N(0,2),N(0,3),N(1,0).

对于向量,我有可能指定Stride,例如,如果我想要在 M 和 N 的第二列上映射一个 4x1 向量,那么以下两行会产生有效的结果,无论它们是行或行:

Map<const VectorXs, 0, Stride<-1, -1> > vc(&M(0,1), 4, 1, Stride<-1, -1>(M.colStride(),M.rowStride()));
Map<const VectorXs, 0, Stride<-1, -1> > vr(&N(0,1), 4, 1, Stride<-1, -1>(N.colStride(),N.rowStride()));

我曾试图使用Stride技术Map<Quaternion>但没有成功。事实上,从特征文档来看,这似乎是不可能的。

问题是:

  1. 是否可以在Map<Quaternion>中使用Stride?如何?
  2. 如果不是,为什么这是不可能的?
  3. 除了将数据复制到新的Quaternion对象之外,我还有什么解决方法或替代方法?

截至目前,这是不可能的。这可能不会太难实现,我在相关功能请求中添加了一个简短的评论,这将直接允许编写N.row(i).asQuaternion()

目前,您可以在矩阵和四元数之间来回复制,这通常非常便宜,甚至可能比处理指针和步幅对象便宜:

Eigen::Matrix4Xd M; // input/output matrix
// extract quaternion from M
Eigen::Quaterniond q(M.row(1).transpose());
// ... do something with q
// copy back quaternion
M.row(1) = q.coeffs().transpose(); // transposing not necessary (would be done implicitly)

如果M在编译时没有 4 列,您可能需要一个中间Eigen::Vector4d对象,或者将该行复制到现有的Eigen::Quaterniond对象中,即,这些替代方法在这种情况下有效(复制回来保持不变):

// If M.row(1) is not known at compile time to have 4 elements:
Eigen::Quaterniond q(Eigen::Vector4d(M.row(1)));
q.coeffs() = M.row(1); // copy row into an existing quaternion