在Map <Quaternion>

时间:2019-08-27 15:06:14

标签: c++ eigen

我想在现有矩阵的内存顶部定义​​一个四元数。将此矩阵设为

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>,但没有成功。实际上,从eigen documentation看来,这是不可能的。

问题是:

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

1 个答案:

答案 0 :(得分:0)

到目前为止,这是不可能的。这可能不太容易实现,我在related feature request上添加了一条简短的注释,可以直接写出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