Home > Mobile >  Eigen::Map and dimension change 4 to 3
Eigen::Map and dimension change 4 to 3

Time:06-28

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:

  1. 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)
  2. You used AngleAxisf but then want to combine it with a matrix of doubles. I changed everything to doubles for consistency but Eigen::Transform also has a cast method if you really want to compute the rotation at reduced precision
  • Related