I would like to define a Quaternion on top of the memory of an existing matrix. Let this matrix be
MatrixXd M(4,4);
as an example. I would like my quaternion to be mapped on the second column. Usually I would do
Map<Quaterniond> q (&M(0,1));
Should M be column-major, this would work since the Map
would be column-wise.
Now imagine I have a second array N, which is now row-major
Matrix<double, -1, -1, RowMajor> N(4,4);
Now my mapped quaternion
Map<Quaterniond> q (&N(0,1));
would be wrong: the elements of q
would be picked up from N row-wise, that is, N(0,1),N(0,2),N(0,3),N(1,0)
.
With vectors, I have the possibility of specifying the Stride
, e.g. the following two lines produce valid results if what I want is to map a 4x1 vector on the second columns of M and N, be them row- or col- major:
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()));
I have attempted to use the Stride
technique to Map<Quaternion>
without success. In fact, from the eigen documentation, it seems this is not possible.
The questions are:
Stride
in Map<Quaternion>
? How?Quaternion
object?As of now, this is not possible. This would probably not be too hard to implement, I added a short comment on a related feature request, which would directly allow to write N.row(i).asQuaternion()
.
At the moment, you can just copy back and forth between the matrix and the quaternion, which is usually very cheap, maybe even cheaper than handling a pointer and a stride object would be:
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)
If M
does not have 4 columns at compile time, you may need an intermediate Eigen::Vector4d
object, or copy the row into an existing Eigen::Quaterniond
object, i.e., these alternatives work in this case (copying back stays the same):
// 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