eigen3rotational-matrices

Transform a rotation matrix to match another


I have two 3x3 rotation matrices as:

Eigen::Matrix3d a;
a = Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitX())
  * Eigen::AngleAxisd(0.45*M_PI,   Eigen::Vector3d::UnitY())
  * Eigen::AngleAxisd(0.0,         Eigen::Vector3d::UnitZ());

Eigen::Matrix3d b;
a = Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitX())
  * Eigen::AngleAxisd(0.0,         Eigen::Vector3d::UnitY())
  * Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitZ());

I would like to find the 3x3 matrix c where a*c = b.

I calculate the angle axis of both rotations like this:

Eigen::AngleAxisd angleAxisA(a);
Eigen::AngleAxisd angleAxisB(b);

Now I know that I have an angle a.angle() and a Vector3d axis a.axis().

From here I do not know what to do. Can someone suggest how I can go from here please?


Solution

  • It's a 3x3 matrix. You can simply invert it to solve the equation system. a*c = b --> c = a^-1 * b.

    int main() {
      Eigen::Matrix3d a;
      a = Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitX())
        * Eigen::AngleAxisd(0.45*M_PI,   Eigen::Vector3d::UnitY())
        * Eigen::AngleAxisd(0.0,         Eigen::Vector3d::UnitZ());
    
      Eigen::Matrix3d b;
      b = Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitX())
        * Eigen::AngleAxisd(0.0,         Eigen::Vector3d::UnitY())
        * Eigen::AngleAxisd(0.25*M_PI,   Eigen::Vector3d::UnitZ());
    
      Eigen::Matrix3d c = a.inverse() * b;
    
      std::cout << "a:\n" << a << "\n\n"
                << "b:\n" << b << "\n\n"
                << "c:\n" << c << "\n\n"
                << "a * c = b:\n" << (a * c) << "\n";
    }
    
    a:
     0.156434         0  0.987688
     0.698401  0.707107 -0.110616
    -0.698401  0.707107  0.110616
    
    b:
       0.707107   -0.707107 5.55112e-17
            0.5         0.5   -0.707107
            0.5         0.5    0.707107
    
    c:
       0.110616   -0.110616   -0.987688
       0.707107    0.707107 1.11022e-16
       0.698401   -0.698401    0.156434
    
    a * c = b:
       0.707107   -0.707107 5.55112e-17
            0.5         0.5   -0.707107
            0.5         0.5    0.707107
    

    But is there a way to solve it using the AngleAxisd which I was trying to use?

    Yes.

    Eigen::AngleAxisd angleAxisC {angleAxisA.inverse() * angleAxisB};
    

    Mathematically, inverting an AngleAxis is simple enough (just negate the angle). But multiplying two AngleAxis is non-trivial. It converts to a Quaternion and multiplies those. The conversion involves transcendental function calls. Try to avoid needless conversions.