nml::quat nml::rotationMatrixToQuat(const nml::mat4& mat)
Return a quaternion from a rotation matrix.
The conversion from a rotation matrix to a quaternion is calculated this way:
\(trace = mat.x.x + mat.y.y + mat.z.z\)
if
\(trace \gt 0\)
\(S = \sqrt{1 + trace} * 2\)
\(quat.a = \frac{S}{4}\)
\(quat.b = \frac{mat.y.z - mat.z.y}{S}\)
\(quat.c = \frac{mat.z.x - mat.x.z}{S}\)
\(quat.d = \frac{mat.x.y - mat.y.x}{S}\)
else if
\((mat.x.x \gt mat.y.y) \&\& (mat.x.x \gt mat.z.z)\)
\(S = \sqrt{1 + mat.x.x - mat.y.y - mat.z.z} * 2\)
\(quat.a = \frac{mat.y.z - mat.z.y}{S}\)
\(quat.b = \frac{S}{4}\)
\(quat.c = \frac{mat.y.x + mat.x.y}{S}\)
\(quat.d = \frac{mat.z.x + mat.x.z}{S}\)
else if
\((mat.y.y \gt mat.z.z)\)
\(S = \sqrt{1 + mat.x.x - mat.y.y - mat.z.z} * 2\)
\(quat.a = \frac{mat.z.x - mat.x.z}{S}\)
\(quat.b = \frac{mat.y.x + mat.x.y}{S}\)
\(quat.c = \frac{S}{4}\)
\(quat.d = \frac{mat.z.y + mat.y.z}{S}\)
else
\(S = \sqrt{1 + mat.z.z - mat.x.x - mat.y.y} * 2\)
\(quat.a = \frac{mat.x.y - mat.y.x}{S}\)
\(quat.b = \frac{mat.z.x + mat.x.z}{S}\)
\(quat.c = \frac{mat.z.y + mat.y.z}{S}\)
\(quat.d = \frac{S}{4}\)
Example
#include "include/quat.h"
#include "include/mat4.h"
#include <iostream>
int main() {
nml::mat4 m(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
nml::quat q = nml::rotationMatrixToQuat(m);
std::cout << nml::to_string(q) << std::endl;
return 0;
}
Result:
0.000000 + 0.000000i + 1.000000j + 0.000000k