Kroma
Kroma

Reputation: 1151

Eigen::Map and dimension change 4 to 3

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,

Upvotes: 1

Views: 159

Answers (1)

Homer512
Homer512

Reputation: 13419

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

Upvotes: 1

Related Questions