I am trying to rotate an object by 45 degrees using quaternions about Y-Axis. After Specifying the Quaternion i am trying to get the Rotation Matrix. But the values I see are incorrect
Eigen::Quaterniond q;
q.x() = 0;
q.y() = 1;
q.z() = 0;
q.w() = PI/8; // Half of the rotation angle must be specified, even IDK why
Eigen::Matrix3d R = q.normalized().toRotationMatrix();
std::cout << "R=" << std::endl << R << std::endl;
OUTPUT :
R=
-0.732 -0 -0.680
0 1 -0
0.680 0 -0.732
Since the OpenGL Rotation Matrix along Y-Axis should be :
Therefore my expected output should be :
R=
0.707 0 0.707
0 1 0
-0.707 0 0.707
Not only are the values off by a small percent the wrong signs on the values are causing some unexpected rotations. Because of the negative signs my cube is doing a 180 degree turn plus the specified angle. I have broken my head over this for the whole day. Can some one tell me what I am doing wrong ?
Quaternions are very efficient for analyzing situations where rotations in R3 are involved. A quaternion is a 4-tuple, which is a more concise representation than a rotation matrix. Its geo- metric meaning is also more obvious as the rotation axis and angle can be trivially recovered.
Four values make up a quaternion, namely x, y, z and w. Three of the values are used to represent the axis in vector format, and the forth value would be the angle of rotation around the axis." So you could think of it as the rotation of the rotation, in simple terms!
You can write this as (q, c, f); simply stated, "Transform a point by rotating it counterclockwise about the z axis by q degrees, followed by a rotation about the y axis by c degrees, followed by a rotation about the x axis by f degrees." There are 12 different conventions that you can use to represent rotations using ...
It's quicker and more efficient to renormalize a quaternion than it is to renormalize a rotation matrix.
The way you initialize your quaternion is incorrect. If you directly initialize the coordinates of quaternion, you should take the definition into account:
Alternatively, the Quaternion
class in Eigen provides a constructor from an axis-angle representation.
This code:
#include <Eigen/Geometry>
#include <iostream>
void outputAsMatrix(const Eigen::Quaterniond& q)
{
std::cout << "R=" << std::endl << q.normalized().toRotationMatrix() << std::endl;
}
void main()
{
auto angle = M_PI / 4;
auto sinA = std::sin(angle / 2);
auto cosA = std::cos(angle / 2);
Eigen::Quaterniond q;
q.x() = 0 * sinA;
q.y() = 1 * sinA;
q.z() = 0 * sinA;
q.w() = cosA;
outputAsMatrix(q);
outputAsMatrix(Eigen::Quaterniond{Eigen::AngleAxisd{angle, Eigen::Vector3d{0, 1, 0}}});
}
outputs what you expect:
R=
0.707107 0 0.707107
0 1 0
-0.707107 0 0.707107
R=
0.707107 0 0.707107
0 1 0
-0.707107 0 0.707107
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With