Reputation: 1727
I have a rotation matrix rot
(Eigen::Matrix3d) and a translation vector transl
(Eigen::Vector3d) and I want them both together in a 4x4 transformation matrix. I just for the life of me can't figure out how to do this in Eigen. I think Affine can be used somehow but I don't understand how it works.
Essentially I want a combination of How translation a matrix(4x4) in Eigen? and Multiplying Transform and Matrix types in Eigen
My code (that doesn't compile as I don't understand how Affine works) looks like this:
Eigen::Affine3d r(rot);
Eigen::Affine3d t(transl);
Eigen::Matrix4d m = t.matrix();
m *= r.matrix();
Upvotes: 11
Views: 65426
Reputation: 1362
Another method is to do the following:
Eigen::Matrix3d R;
// Find your Rotation Matrix
Eigen::Vector3d T;
// Find your translation Vector
Eigen::Matrix4d Trans; // Your Transformation Matrix
Trans.setIdentity(); // Set to Identity to make bottom row of Matrix 0,0,0,1
Trans.block<3,3>(0,0) = R;
Trans.block<3,1>(0,3) = T;
This method literally copies the Rotation matrix into the first 3 rows and columns and the translation vector to the 4th column. Then sets the bottom right matrix entry to 1. You final matrix will look like:
R R R T
R R R T
R R R T
0 0 0 1
where R are the corresponding values from the rotation matrix and T the values from the Translation vector.
Upvotes: 23
Reputation: 12896
Another way is to use the Eigen::Transform.
Let's take a example such as to implemente this affine transform ,
#include <Eigen/Dense>
#include <Eigen/Geometry>
using namespace Eigen;
Matrix4f create_affine_matrix(float a, float b, float c, Vector3f trans)
{
Transform<float, 3, Eigen::Affine> t;
t = Translation<float, 3>(trans);
t.rotate(AngleAxis<float>(a, Vector3f::UnitX()));
t.rotate(AngleAxis<float>(b, Vector3f::UnitY()));
t.rotate(AngleAxis<float>(c, Vector3f::UnitZ()));
return t.matrix();
}
You can also implemented as the following
Matrix4f create_affine_matrix(float a, float b, float c, Vector3f trans)
{
Transform<float, 3, Eigen::Affine> t;
t = AngleAxis<float>(c, Vector3f::UnitZ());
t.prerotate(AngleAxis<float>(b, Vector3f::UnitY()));
t.prerotate(AngleAxis<float>(a, Vector3f::UnitX()));
t.pretranslate(trans);
return t.matrix();
}
The difference between the first implementation and the second is like the difference between Fix Angle and Euler Angle, you can refer to this video.
Upvotes: 6
Reputation: 2279
You didn't post the compilation errors, nor what are rot
and transl
. Below is a working
sample showing, how you can create a 4x4 transformation matrix.
#include <Eigen/Geometry>
Eigen::Affine3d create_rotation_matrix(double ax, double ay, double az) {
Eigen::Affine3d rx =
Eigen::Affine3d(Eigen::AngleAxisd(ax, Eigen::Vector3d(1, 0, 0)));
Eigen::Affine3d ry =
Eigen::Affine3d(Eigen::AngleAxisd(ay, Eigen::Vector3d(0, 1, 0)));
Eigen::Affine3d rz =
Eigen::Affine3d(Eigen::AngleAxisd(az, Eigen::Vector3d(0, 0, 1)));
return rz * ry * rx;
}
int main() {
Eigen::Affine3d r = create_rotation_matrix(1.0, 1.0, 1.0);
Eigen::Affine3d t(Eigen::Translation3d(Eigen::Vector3d(1,1,2)));
Eigen::Matrix4d m = (t * r).matrix(); // Option 1
Eigen::Matrix4d m = t.matrix(); // Option 2
m *= r.matrix();
return 0;
}
Upvotes: 13