Context:
I want to operate rotations and scaling on an existing array, representing a 4x4 matrix, using Eigen.
I don't know how to do it without copying data around:
Edit: Input matrix is of type array<double,16>
The code:
Rotation:
Eigen::Map <Eigen::Matrix4d> mapped_data( (double *)&input_matrix );
auto rot = Eigen::AngleAxisf( angle_z, Eigen::Vector3f::UnitZ() );
mapped_data *= rot.matrix();
Scale:
Eigen::Map <Eigen::Matrix4d> mapped_data( (double *)&input_matrix );
auto scaler = Eigen::Scaling(sx, sy, sz);
mapped_data *= scaler;
Obviously it tells me that I cannot do it because of matrices of different sizes.
Constraint:
Again, I don't want to copy, so Map should be what I am after, but it only allows plain matrices (matrix2x, 3x or 4x) to be used (am I wrong?).
Question:
How to modify my code to make it work, with no useless copies?
Thanks,
CodePudding user response:
Eigen's geometry module has a handy Transform class that helps with this stuff. Something like this should work:
using Affine3d = Eigen::Transform<double, 3, Eigen::Affine>;
double angle_z = ..., sx = ..., sy = ..., sz = ...;
Affine3d transform =
Eigen::AngleAxisd(angle_z, Eigen::Vector3d::UnitZ())
* Eigen::Scaling(sx, sy, sz);
mapped_data = mapped_data * transform.matrix();
Two notes:
- Please double-check whether to apply the transformation on the left or right side. I always mess this up but I think the given order is correct (first rotate, then scale)
- You used
AngleAxisf
but then want to combine it with a matrix of doubles. I changed everything to doubles for consistency butEigen::Transform
also has acast
method if you really want to compute the rotation at reduced precision