Search code examples
c++matrixeigen

How to rotate a point MatrixXd by a Matrix3d rotation matrix in Eigen using transformations


I have the following MatrixXd V, representing points of a 2d shape:

==========================================
Bounding box vertices (AV) (Rows: 8 Cols: 3)
==========================================
[[ 2.367639937564554,  3.100420929531666,                  0]
 [ 2.367639937564554,  3.100420929531666,                  0]
 [ 2.367639937564554, -3.097445263635904,                  0]
 [ 2.367639937564554, -3.097445263635904,                  0]
 [-2.362324650030633,  3.100420929531666,                  0]
 [-2.362324650030633,  3.100420929531666,                  0]
 [-2.362324650030633, -3.097445263635904,                  0]
 [-2.362324650030633, -3.097445263635904,                  0]]

and I want to rotate the shape by this Matrix3d rotation matrix:

==========================================
RM: (RM)  (Rows: 3 Cols: 3)
==========================================
[[   0.997496638487424, -0.07071390391068358,                    0]
 [ 0.07071390391068358,    0.997496638487424,                    0]
 [                   0,                    0,                    1]]
==========================================

I'm not able to figure the correct way to do this... I've checked with transformations:

Affine3d tf = RM;
tf.rotate(V);

Of course this doesn't work, as Eigen reports no viable conversion from 'Eigen::Matrix3d' to 'Eigen::Affine3d'.

In short, how do I tell Eigen to use this rotation matrix (RM) as a transformation and apply it to the target matrix (V)?

As I already have the rotation matrix, I have no reason to use quaternions...

Thank you


Solution

  • Of course this doesn't work, as Eigen reports no viable conversion from 'Eigen::Matrix3d' to 'Eigen::Affine3d'.

    Affine3d is from the Transform class and not the Matrix class. Try this:

    Affine3d tf = Affine3d(RM);
    

    Now regarding the rotation, I came up with this small demo:

    #include <iostream>
    #include <eigen3/Eigen/Dense>
    using Eigen::Matrix3d;
    using Eigen::MatrixXd;
    using Eigen::Affine3d;
    
    int main(){
    
    //obviously not a rotation matrix, but needed some numbers only
    Matrix3d rot = Matrix3d::Random();
    std::cout << "We have the rotation matrix:" << std::endl;
    std::cout << rot << std::endl;
    
    Affine3d aff_rot = Affine3d(rot);
    std::cout << "Affine version:" << std::endl;
    std::cout << aff_rot.matrix() << std::endl;
    
    MatrixXd points = MatrixXd::Random(8,3);
    std::cout << "Some random points:" << std::endl;
    std::cout << points << std::endl;
    
    std::cout << std::endl << std::endl;
    MatrixXd m = aff_rot * points.transpose().colwise().homogeneous();
    MatrixXd result = m.transpose();
    
    std::cout << "Result:" << std::endl;
    std::cout << result << std::endl;
    
    return 0;
    }
    

    Here the rotation is applied on left side, but you can adapt the code to apply it on the right side.