This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Problem constructing quaternion from rotation matrix

Tags: None
(comma "," separated)
stefanTUD
Registered Member
Posts
5
Karma
0
Hi,

I have the following code snippet:
Code: Select all
#include <iostream>
#include <Eigen/Geometry>
#include <Eigen/Dense>

int main(int argc, char **argv)
{
    //Below is setup stuff
    Eigen::Vector3f v1(Eigen::Vector3f::Zero());
    Eigen::Matrix3f m1(Eigen::Matrix3f::Identity());
    m1(0,0) = 2.0*2.0;
    m1(2,2) = 0.5*0.5;

    Eigen::AngleAxisf rot(0.25*M_PI, Eigen::Vector3f::UnitZ());


    Eigen::Matrix3f m1_rot = rot.toRotationMatrix().transpose() * m1 * rot.toRotationMatrix();
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eig(m1_rot);

    const Eigen::Vector3f& eigValues (eig.eigenvalues());
    const Eigen::Matrix3f& eigVectors (eig.eigenvectors());

    //The important part: Construct a quaternion from the matrix of eigenvectors (which is a rotation matrix)
    Eigen::Quaternionf quaternion (eigVectors);

    std::cout << "\neigVec:\n" << eigVectors << "\n";

    std::cout << "\nw:" << quaternion.w() << " x:" << quaternion.x() << " y:" << quaternion.y() << " z:" << quaternion.z() << "\n";   
}


As can be seen, I want to construct a quaternion from a Eigen::Matrix3f (which should work looking at the Eigen documentation). I get the following output:
Code: Select all
eigVec:
        0 -0.707107  0.707107
        0 -0.707107 -0.707107
        1        -0         0

w:0.270598 x:0.653282 y:-0.270598 z:0.653282

The matrix of eigenvectors looks like a valid rotation matrix around a single axis to me, but for the quaternion I get a rotation around multiple axes. I fail to see the mistake I'm making.

If I flip around the columns of the matrix of eigenvalues like so:
Code: Select all
    Eigen::Matrix3f eigVectorsFlipped;
    eigVectorsFlipped.col(0) = eigVectors.col(2);
    eigVectorsFlipped.col(1) = eigVectors.col(1);
    eigVectorsFlipped.col(2) = eigVectors.col(0);
   
    std::cout << "\neigVecFlipped:\n" << eigVectorsFlipped << "\n";
   
    Eigen::Quaternionf quaternionFlipped (eigVectorsFlipped);
    std::cout << "\nw:" << quaternionFlipped.w() << " x:" << quaternionFlipped.x() << " y:" << quaternionFlipped.y() << " z:" << quaternionFlipped.z() << "\n";

I get the following non-normalized quaternion (which looks like a wrong constructor is used, copying elements of the input matrix):
Code: Select all
eigVecFlipped:
 0.707107 -0.707107         0
-0.707107 -0.707107         0
        0        -0         1

w:0.707107 x:-0 y:0 z:0


I'm using Eigen installed from the package manager on a 64bit Ubuntu Natty system.
jitseniesen
Registered Member
Posts
204
Karma
2
stefanTUD wrote:
Code: Select all
eigVec:
        0 -0.707107  0.707107
        0 -0.707107 -0.707107
        1        -0         0

w:0.270598 x:0.653282 y:-0.270598 z:0.653282

The matrix of eigenvectors looks like a valid rotation matrix around a single axis to me, but for the quaternion I get a rotation around multiple axes. I fail to see the mistake I'm making.

I'm not sure what you mean with single axis / multiple axes. I suppose you are refering to the coordinate axes (x-axis, y-axis and z-axis). However, the matrix is not a rotation around one of the coordinate axes. The matrix for a rotation around the coordinate axes are as given in Wikipedia as the 'basic rotations', see http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations. Your matrix is not in one of these forms (the 1 should be on the main diagonal).

I get the following non-normalized quaternion (which looks like a wrong constructor is used, copying elements of the input matrix):
Code: Select all
eigVecFlipped:
 0.707107 -0.707107         0
-0.707107 -0.707107         0
        0        -0         1

w:0.707107 x:-0 y:0 z:0

The matrix eigVecFlipped has determinant -1, so it is not a rotation matrix. I guess that's why you get an unexpected result.


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]